3939 SymbolInfinity ,
4040 SymbolRowBox ,
4141)
42+ from mathics .eval .datetime import eval_timeconstrained , valid_time_from_expression
4243from mathics .settings import TIME_12HOUR
4344
44- if sys .platform == "emscripten" :
45- from timed_threads import SignalTimeout as TimeoutHandler
46- else :
47- from timed_threads import ThreadingTimeout as TimeoutHandler
48-
4945START_TIME = time .time ()
5046
5147TIME_INCREMENTS = {
@@ -1098,34 +1094,35 @@ def evaluate(self, evaluation: Evaluation) -> Expression:
10981094
10991095
11001096class TimeConstrained (Builtin ):
1101- """
1097+ r """
11021098 <url>:WMA link:https://reference.wolfram.com/language/ref/TimeConstrained.html</url>
11031099
11041100 <dl>
1105- <dt>'TimeConstrained[$expr$, $t$]'
1101+ <dt>'TimeConstrained' [$expr$, $t$]
11061102 <dd>'evaluates $expr$, stopping after $t$ seconds.'
11071103
1108- <dt>'TimeConstrained[$expr$, $t$, $failexpr$]'
1104+ <dt>'TimeConstrained' [$expr$, $t$, $failexpr$]
11091105 <dd>'returns $failexpr$ if the time constraint is not met.'
11101106 </dl>
11111107
11121108 Possible issues: for certain time-consuming functions (like simplify)
11131109 which are based on sympy or other libraries, it is possible that
11141110 the evaluation continues after the timeout. However, at the end of the \
1115- evaluation, the function will return '$Aborted' and the results will not affect
1111+ evaluation, the function will return '\ $Aborted' and the results will not affect
11161112 the state of the Mathics3 kernel.
11171113
1118- >> TimeConstrained[Pause[5]; a, 1]
1119- = $Aborted
1120-
1121- 'TimeConstrained' can be nested. In this case, the outer 'TimeConstrained' waits for \
1122- 2 seconds that the inner sequence be executed. Inner expressions would take in \
1123- sequence more than 3 seconds:
1124- >> TimeConstrained[TimeConstrained[Pause[1]; Print["First Done"], 2];\
1125- TimeConstrained[Pause[5];Print["Second Done"],2,"inner"], \
1126- 2, "outer"]
1127- | First Done
1128- = outer
1114+
1115+ ## >> TimeConstrained[Pause[5]; a, 1]
1116+ ## = $Aborted
1117+
1118+ ## 'TimeConstrained' can be nested. In this case, the outer 'TimeConstrained' waits for \
1119+ ## 2 seconds that the inner sequence be executed. Inner expressions would take in \
1120+ ## sequence more than 3 seconds:
1121+ ## >> TimeConstrained[TimeConstrained[Pause[1]; Print["First Done"], 2];\
1122+ ## TimeConstrained[Pause[5];Print["Second Done"],2,"inner"], \
1123+ ## 2, "outer"]
1124+ ## | First Done
1125+ ## = outer
11291126 """
11301127
11311128 attributes = A_HOLD_ALL | A_PROTECTED
@@ -1135,36 +1132,30 @@ class TimeConstrained(Builtin):
11351132 "or Infinity."
11361133 ),
11371134 }
1135+ if sys .platform == "emscripten" :
1136+ messages .update ({"tcns" : f"TimeConstrained is not supported in { sys .platform } " })
11381137
11391138 summary_text = "run a command for at most a specified time"
11401139
1141- def eval_2 (self , expr , t , evaluation ):
1140+ def eval_with_timeout (self , expr , t , evaluation ) -> Optional [ BaseElement ] :
11421141 "TimeConstrained[expr_, t_]"
1143- return self .eval_3 (expr , t , SymbolAborted , evaluation )
1142+ try :
1143+ timeout = valid_time_from_expression (t , evaluation )
1144+ except ValueError :
1145+ evaluation .message ("TimeConstrained" , "timc" , t )
1146+ return
1147+ return eval_timeconstrained (expr , timeout , SymbolAborted , evaluation )
11441148
1145- def eval_3 (self , expr , t , failexpr , evaluation ):
1149+ def eval_with_timeout_and_failexpr (
1150+ self , expr , t , failexpr , evaluation
1151+ ) -> Optional [BaseElement ]:
11461152 "TimeConstrained[expr_, t_, failexpr_]"
1147- t = t .evaluate (evaluation )
1148- if not t .is_numeric (evaluation ):
1153+ try :
1154+ timeout = valid_time_from_expression (t , evaluation )
1155+ except ValueError :
11491156 evaluation .message ("TimeConstrained" , "timc" , t )
11501157 return
1151- try :
1152- timeout = float (t .to_python ())
1153- evaluation .timeout_queue .append ((timeout , datetime .now ().timestamp ()))
1154- request = lambda : expr .evaluate (evaluation )
1155- done = False
1156- with TimeoutHandler (timeout ) as to_ctx_mgr :
1157- assert to_ctx_mgr .state == to_ctx_mgr .EXECUTING
1158- result = request ()
1159- done = True
1160- if done :
1161- evaluation .timeout_queue .pop ()
1162- return result
1163- except Exception :
1164- evaluation .timeout_queue .pop ()
1165- raise
1166- evaluation .timeout_queue .pop ()
1167- return failexpr .evaluate (evaluation )
1158+ return eval_timeconstrained (expr , timeout , failexpr , evaluation )
11681159
11691160
11701161class TimeZone (Predefined ):
0 commit comments