Varshithdharmajv commited on
Commit
bf565d0
·
verified ·
1 Parent(s): b2df04b

Upload math_verify/utils.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. math_verify/utils.py +108 -0
math_verify/utils.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MIT License
2
+
3
+ # Copyright (c) 2024 The HuggingFace Team
4
+
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ import logging
24
+ import os
25
+
26
+ from math_verify.errors import TimeoutException
27
+
28
+ TIMEOUT_WARNING_SHOWN = False
29
+ logger = logging.getLogger(__name__)
30
+
31
+
32
+ def timeout(timeout_seconds: int | None = 10): # noqa: C901
33
+ """A decorator that applies a timeout to the decorated function.
34
+
35
+ Args:
36
+ timeout_seconds (int): Number of seconds before timing out the decorated function.
37
+ Defaults to 10 seconds.
38
+
39
+ Notes:
40
+ On Unix systems, uses a signal-based alarm approach which is more efficient as it doesn't require spawning a new process.
41
+ On Windows systems, uses a multiprocessing-based approach since signal.alarm is not available. This will incur a huge performance penalty.
42
+ """
43
+ if timeout_seconds is None or timeout_seconds <= 0:
44
+
45
+ def no_timeout_decorator(func):
46
+ return func
47
+
48
+ return no_timeout_decorator
49
+
50
+ if os.name == "posix":
51
+ # Unix-like approach: signal.alarm
52
+ import signal
53
+
54
+ def decorator(func):
55
+ def handler(signum, frame):
56
+ raise TimeoutException("Operation timed out!")
57
+
58
+ def wrapper(*args, **kwargs):
59
+ old_handler = signal.getsignal(signal.SIGALRM)
60
+ signal.signal(signal.SIGALRM, handler)
61
+ signal.alarm(timeout_seconds)
62
+ try:
63
+ return func(*args, **kwargs)
64
+ finally:
65
+ # Cancel the alarm and restore previous handler
66
+ signal.alarm(0)
67
+ signal.signal(signal.SIGALRM, old_handler)
68
+
69
+ return wrapper
70
+
71
+ return decorator
72
+
73
+ else:
74
+ # Windows approach: use multiprocessing
75
+ from multiprocessing import Process, Queue
76
+
77
+ def decorator(func):
78
+ def wrapper(*args, **kwargs):
79
+ q = Queue()
80
+
81
+ def run_func(q, args, kwargs):
82
+ try:
83
+ result = func(*args, **kwargs)
84
+ q.put((True, result))
85
+ except Exception as e:
86
+ q.put((False, e))
87
+
88
+ p = Process(target=run_func, args=(q, args, kwargs))
89
+ p.start()
90
+ p.join(timeout_seconds)
91
+
92
+ if p.is_alive():
93
+ # Timeout: Terminate the process
94
+ p.terminate()
95
+ p.join()
96
+ raise TimeoutException("Operation timed out!")
97
+
98
+ # If we got here, the process completed in time.
99
+ success, value = q.get()
100
+ if success:
101
+ return value
102
+ else:
103
+ # The child raised an exception; re-raise it here
104
+ raise value
105
+
106
+ return wrapper
107
+
108
+ return decorator