
    oi                     J   / S Qr SSKrSSKrSSKrSSKrSSKJr  SSKrSSKrSSK	r	SSK
rSSKrSSKrSSKrSSKrSSKrSSKrSSKJr  SSKJr  SSKrSSKrSSKJrJrJrJr  \" S5      r\R<                  S 5       r S	\ 4S
 jr! S	\ 4S jr" S\RF                  S\$4S jr% S\RL                  S\$4S jr' SS.S\RL                  S\$4S jjr( SSSSS.S\ S\$S\$S\$S\$4
S jjr) SSSSSS.S\ S\$S\$S\$S\$S\ 4S jjr* S  r+ S! r, \SS"S#.S$\-S%\$S&\-4S' jj5       r. SSK/r0SSK1r1 " S( S)\25      r3S*S+S,.S- jr4 \5" 1 S.k5      r6S/S0S+S1.S$\-S2\ S3\ S4\-S\\S5\4   /\S5\4   4   4
S6 jjr7  " S7 S85      r8 SSK9r9SSK:r:SSK;r;SSK<r<S9 r= S:\ S\ 4S; jr>S<SSS=0 S4S>\?S:\ S?\ 4S@ jjr@g)A)check_python_modulescheck_signal_escape_patternscreate_locked_down_functionexecute_with_time_limitBenchmarkeris_port_openlaunch_openenv    N)Path)contextmanager)wraps)CallableTypeVarAnyTupleTc                     [        [        S[        5       5       V s1 s H  o R                  5       iM     nn U[        R                   V s1 s H  o R                  5       iM     sn -  nUR                  S5         [        [        R                  " S5      5      nUR                  5       (       a  UR                  5        H  nUR                  S:X  a  M  UR                  S:X  a+  UR                  UR                  R                  5       5        MP  UR                  5       (       d  Mg  US-  R                  5       (       d  M  UR                  UR                  R                  5       5        M     U$ s  sn f s  sn f ! [         a     U$ f = f)z
Build a set of canonical stdlib top-level module/package names.
Uses sys.stdlib_module_names when available (3.10+), with a
filesystem fallback for older versions/edge cases.
stdlib_module_names
__future__stdlibzsite-packagesz.pyz__init__.py)getattrsyssetlowerbuiltin_module_namesaddr
   	sysconfigget_pathexistsiterdirnamesuffixstemis_dir	Exception)mnames
stdlib_dirps       U/home/james-whalen/.local/lib/python3.13/site-packages/unsloth_zoo/rl_environments.py_stdlib_namesr*   /   s%    !(-BCE JK J1WWY JEK	!9!9:!9Aggi!9::E	IIl),,X67
'')66_,88u$IIafflln-XXZZQ%6$>$>$@$@IIafflln- * L% L:  Ls*   E.
E3:B'E8 %E8 ?-E8 8
FFcodec                   ^^^  [         R                  " U 5      n[        5       mSm[	        5       m " UU4S jS[         R
                  5      nU" 5       R                  U5        [        U4S jT 5       5      n[        U4S	 jT 5       5      n[        U5      S:H  UUTS
.4$ ! [         a  nSSU 3/ / SS.4s SnA$ SnAff = f)a  
Checks if function only calls Python standard library functions and nothing more
Return (ok: bool, details: dict)

ok == True  -> all absolute imports are from the stdlib.
ok == False -> details['non_stdlib'] lists offending top-level modules.

details includes:
  - stdlib: sorted list of stdlib imports found
  - non_stdlib: sorted list of non-stdlib imports found
  - relative_imports: count of relative imports (always allowed here)
FSyntaxError: r	   )errorr   
non_stdlibrelative_importsNc                   h   > \ rS rSrS\R
                  4U 4S jjrS\R                  4U U4S jjrSr	g)%check_python_modules.<locals>.Visitorf   nodec                    > UR                    H0  nTR                  UR                  R                  S5      S   5        M2     g )N.r	   )r&   r   r    split)selfr4   aliasabs_importss      r)   visit_Import2check_python_modules.<locals>.Visitor.visit_Importg   s1    

 0 0 5a 89 $    c                    > UR                   =(       d    SS:  a  TS-  mg UR                  (       a.  TR                  UR                  R                  S5      S   5        g g )Nr	      r6   )levelmoduler   r7   )r8   r4   r:   relative_counts     r)   visit_ImportFrom6check_python_modules.<locals>.Visitor.visit_ImportFromj   sI    

a1$!#;;OODKK$5$5c$:1$=> r=    N)
__name__
__module____qualname____firstlineno__astImportr;   
ImportFromrC   __static_attributes__)r:   rB   s   r)   Visitorr2   f   s(    	:SZZ 	:	? 	? 	?r=   rN   c              3   R   >#    U  H  oR                  5       T;   d  M  Uv   M     g 7fNr   .0r%   _STDLIB_SETs     r)   	<genexpr>'check_python_modules.<locals>.<genexpr>u   s     M[GGI4L!![   '	'c              3   R   >#    U  H  oR                  5       T;  d  M  Uv   M     g 7frP   rQ   rR   s     r)   rU   rV   v   s     O;a'');2N;rW   )r   r/   r0   )	rJ   parseSyntaxErrorr   r*   NodeVisitorvisitsortedlen)	r+   treeerN   stdlib_foundr/   rT   r:   rB   s	         @@@r)   r   r   K   s    
yy %KN/K? ?#// ? IOODM[MMLO;OOJz?a *"  =  
$QC( !	
 
 	

s   B" "
C,B=7C=Cc                   ^^^	  [         R                  " U 5      n/ m	/ m/ n " UUU	4S jS[         R                  5      nS mU" 5       nUR	                  U5        UR
                  (       a  T	(       d  UR                  S5        [        T	5      S	:H  =(       a    [        T5      S	:H  nUT	TUS
.4$ ! [         a  nSSU 3/ / / S.4s SnA$ SnAff = f)a  
Check if code contains patterns that could escape signal-based timeouts.

This performs static analysis (no execution) to detect code patterns that
could bypass SIGALRM-based timeout enforcement. Use this to decide whether
to use backend="process" instead of backend="signal".

Returns (safe: bool, details: dict)

safe == True  -> no escape patterns detected (signal backend should work).
safe == False -> escape patterns found (recommend backend="process").

details includes:
  - signal_tampering: list of signal manipulation patterns found
  - exception_catching: list of exception catching patterns found
  - warnings: list of warning messages

Signal Tampering Patterns (code can disable/ignore the timeout signal):
-----------------------------------------------------------------------
1. signal.signal(SIGALRM, SIG_IGN) - Ignores the alarm signal entirely
   Example that escapes:
       import signal
       signal.signal(signal.SIGALRM, signal.SIG_IGN)
       while True: pass  # Runs forever, timeout never fires

2. signal.setitimer(ITIMER_REAL, 0) - Disables the timer completely
   Example that escapes:
       import signal
       signal.setitimer(signal.ITIMER_REAL, 0)
       while True: pass  # Timer disabled, runs forever

3. signal.alarm(0) - Cancels any pending alarm
   Example that escapes:
       import signal
       signal.alarm(0)
       while True: pass  # Alarm cancelled, runs forever

4. signal.pthread_sigmask(SIG_BLOCK, [SIGALRM]) - Blocks signal delivery
   Example that escapes:
       import signal
       signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGALRM])
       while True: pass  # Signal blocked, runs forever

Exception Catching Patterns (only dangerous INSIDE A LOOP):
-----------------------------------------------------------
The signal backend raises TimeoutError when time expires. If code catches
this exception INSIDE A LOOP, it can suppress the timeout and continue.

NOTE: Exception catching OUTSIDE a loop is safe because control returns
to the caller after the handler. These patterns are only flagged when
detected inside a while/for loop.

5. except TimeoutError in loop - Catches and continues looping
   ESCAPES (inside loop):
       while True:
           try:
               do_work()
           except TimeoutError:
               pass  # Caught! Loop continues, runs forever

   SAFE (outside loop):
       try:
           do_work()
       except TimeoutError:
           return "default"  # Returns to caller, does NOT escape

6. except Exception in loop - Catches TimeoutError (inherits from Exception)
   ESCAPES (inside loop):
       while True:
           try:
               do_work()
           except Exception:
               pass  # TimeoutError caught, runs forever

7. except BaseException in loop - Catches everything including TimeoutError

8. Bare except: in loop - Catches all exceptions
   ESCAPES (inside loop):
       while True:
           try:
               do_work()
           except:
               pass  # All exceptions caught, runs forever

Why use backend="process" instead:
----------------------------------
The process backend runs code in a subprocess and uses SIGKILL to terminate
it on timeout. SIGKILL cannot be caught, ignored, or blocked by any code,
making it immune to all escape patterns above.
Fr-   )r.   signal_tamperingexception_catchingwarningsNc                      > \ rS rSrS rS\R                  4S jrS\R                  4S jr	S\R                  4S jrS\R                  4S jrS\R                  4U U4S jjrS\R                   4U4S	 jjrS
rg)9check_signal_escape_patterns.<locals>.SignalEscapeVisitor   c                 0    SU l         S1U l        SU l        g )NFsignalr	   )imports_signalsignal_aliases
loop_depthr8   s    r)   __init__Bcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.__init__   s    "'D#+*DDOr=   r4   c                     UR                    HT  nUR                  S:X  d  M  SU l        UR                  (       d  M/  U R                  R                  UR                  5        MV     U R                  U5        g )Nrj   T)r&   r    rk   asnamerl   r   generic_visitr8   r4   r9   s      r)   r;   Fcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.visit_Import   sU    ::)*.D'|||++//=	 $
 t$r=   c                    UR                   S:X  ad  SU l        UR                   HM  nUR                  S;   d  M  U R                  R                  UR                  =(       d    UR                  5        MO     U R                  U5        g )Nrj   T)rj   SIGALRMSIG_IGN	setitimerITIMER_REALpthread_sigmask	SIG_BLOCKalarm)rA   rk   r&   r    rl   r   rr   rs   rt   s      r)   rC   Jcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.visit_ImportFrom   sh    {{h&&*#!ZZEzz &^ ^++//0J

K ( t$r=   c                 z    U =R                   S-  sl         U R                  U5        U =R                   S-  sl         g Nr?   rm   rs   r8   r4   s     r)   visit_WhileEcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.visit_While   ,    OOq Ot$OOq Or=   c                 z    U =R                   S-  sl         U R                  U5        U =R                   S-  sl         g r   r   r   s     r)   	visit_ForCcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.visit_For  r   r=   c                   > UR                   nS n[        U[        R                  5      (       a  [        UR                  [        R
                  5      (       a4  UR                  R                  U R                  ;   a  SUR                   3nOf[        UR                  [        R                  5      (       a   O;[        U[        R
                  5      (       a  UR                  S;   a  UR                  nU(       Ga  US;   aV  [        UR                  5      S:  a<  UR                  S   nT" US5      (       a  TR                  SUR                  SS	.5        OUS
;   aV  [        UR                  5      S:  a<  UR                  S   nT" US5      (       a  TR                  SUR                  SS	.5        OKUS;   a   TR                  SUR                  SS	.5        O%US;   a  TR                  SUR                  SS	.5        U R                  U5        g )Nzsignal.)rj   ry   r}   r{   )zsignal.signalrj   r?   r	   )rw   zsignal.SIGALRMsignal_handler_overridezOverrides SIGALRM handlertypelinedescription)zsignal.setitimerry   )rz   zsignal.ITIMER_REALtimer_manipulationzManipulates ITIMER_REAL timer)zsignal.alarmr}   alarm_manipulationzManipulates alarm timer)zsignal.pthread_sigmaskr{   signal_maskz(Modifies signal mask (may block SIGALRM))func
isinstancerJ   	AttributevalueNameidrl   attrr^   argsappendlinenors   )r8   r4   r   	func_namearg0_ast_name_matchesrc   s        r)   
visit_CallDcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.visit_Call
  s   99DI $..djj#((33zz}}(;(;;&-dii[$9	

CMM::D#((++77QQ $I  ;;499~*#yy|,T3PQQ,33(A(,/J5  "CC499~*#yy|,T3XYY,33(<(,/N5  ";;$++ 4 $'@-  "OO$++ - $'Q-  t$r=   c                 V  > U R                   S:X  a  U R                  U5        g UR                  c!  TR                  SUR                  SS.5        GOG[        UR                  [        R                  5      (       aj  UR                  R                  S;   aO  TR                  SUR                  R                   S3UR                  SUR                  R                   S	3S.5        O[        UR                  [        R                  5      (       a  UR                  R                   Hq  n[        U[        R                  5      (       d  M$  UR                  S;   d  M6  TR                  SUR                   S3UR                  SUR                   S	3S.5        Ms     U R                  U5        g )
Nr	   bare_except_in_loopz>Bare except in loop catches TimeoutError and continues loopingr   )TimeoutErrorBaseExceptionr$   catches__in_loopzCatches z, in loop - may suppress timeout and continue)rm   rs   r   r   r   r   rJ   r   r   r   elts)r8   r4   eltrd   s      r)   visit_ExceptHandlerMcheck_signal_escape_patterns.<locals>.SignalEscapeVisitor.visit_ExceptHandlerD  sL    !#""4( yy "))1 KK#c+ 
 DIIsxx0099<<#QQ&--"*499<<. A $)1$)),,?k'l/ 
 DIIsyy1199>>C!#sxx0066%SS.55*2366(((C(,19#&&Am/n7  * t$r=   )rk   rm   rl   N)rF   rG   rH   rI   ro   rJ   rK   r;   rL   rC   Whiler   Forr   Callr   ExceptHandlerr   rM   )r   rd   rc   s   r)   SignalEscapeVisitorrg      su    	 
	%SZZ 	%	% 	%	!CII 	!
	!#'' 	!
8	%388 8	% 8	%t 	%C,=,=  	%  	%r=   r   c                 $   [        U [        R                  5      (       a  U R                  U;   $ [        U [        R                  5      (       a  / nU n[        U[        R                  5      (       aH  UR                  UR                  5        UR                  n[        U[        R                  5      (       a  MH  [        U[        R                  5      (       a  UR                  UR                  5        SR                  [        U5      5      nX!;   $ g)z4Check if an AST node matches any of the given names.r6   F)
r   rJ   r   r   r   r   r   r   joinreversed)r4   r&   	full_namecurrents       r)   r   7check_signal_escape_patterns.<locals>._ast_name_matchesf  s    dCHH%%77e##cmm,,IGWcmm44  .!-- Wcmm44 '388,,  ,)!45I%%r=   z9Code imports 'signal' module - review manually for safetyr	   )rc   rd   re   )rJ   rY   rZ   r[   r\   rk   r   r^   )
r+   r_   r`   re   r   visitoris_safer   rd   rc   s
          @@@r)   r   r      s    v
yy H{% {%coo {%z  "#GMM$ &6ST "#q(IS1C-D-IG,0  G  
$QC( ""$	
 
 	

s   B. .
C8C	C	Cr4   returnc                     [        U [        R                  5      =(       aP    [        [        U SS 5      [        R                  5      =(       a$    [        U R
                  R
                  [        5      $ )Nr   )r   rJ   Exprr   Constantr   strr4   s    r)   _is_docstring_stmtr     sJ    4" 	.wtWd3S\\B	.tzz''-r=   c                     [        U [        R                  5      (       a  g[        U [        R                  5      (       a  [	        S U R
                   5       5      $ g)NTc              3   8   #    U  H  n[        U5      v   M     g 7frP   )_is_safe_literal)rS   r`   s     r)   rU   #_is_safe_literal.<locals>.<genexpr>  s     :	1#A&&	s   F)r   rJ   r   r   allr   r   s    r)   r   r     s?    $%%$		"":		:::r=   Trequire_constant_defaultsr   r   c          	         U R                   n/ nUR                   H6  nU(       a  [        U5      (       d  [        S5      eUR	                  U5        M8     UR
                   H;  nUc  M  U(       a  [        U5      (       d  [        S5      eUR	                  U5        M=     [        US/ 5      UR                   UR                  UR                  (       a  UR                  /O/ UR                  (       a  UR                  /O/ 4 H7  nU H.  n[        USS 5      c  M  UR	                  UR                  5        M0     M9     [        U SS 5      b  UR	                  U R                  5        U H  n[        R                  " U5       H  n[        U[        R                  5      (       a  [        S5      e[        U[        R                   [        R"                  [        R$                  [        R&                  45      (       d  M|  [        S5      e   M     g )Nz8Only simple literal default argument values are allowed.z@Only simple literal default keyword argument values are allowed.posonlyargs
annotationreturnsz0Function signature contains a call (disallowed).z?Function signature contains executable constructs (disallowed).)r   defaultsr   RuntimeErrorr   kw_defaultsr   
kwonlyargsvarargkwargr   r   rJ   walkr   r   LambdaYield	YieldFromAwait)	r   r   r   	sig_nodesdgroupar4   ns	            r)   _ensure_no_calls_in_signaturer     s   99DI]]$-=a-@-@YZZ  =(1A!1D1D"#effQ	  	mR(		"

 Aq,-9  .  tY%1&$A!SXX&&"#UVV!cjj#))S]]CIINOO"#dee	   r=   Fallow_asyncallow_decoratorsallow_nested_defsr   sourcer   r   r   c                T    [         R                  " U SS9n[	        UR
                  5      nU(       a  [        US   5      (       a  USS  nU(       d  [        S5      e[        U5      S:w  a  [        S5      eUS   n[        U[         R                  [         R                  45      (       d  [        S5      e[        U[         R                  5      (       a  U(       d  [        S	5      eUR                  (       a  U(       d  [        S
5      eU(       dl  [         R                  " U5       HR  n	XL a  M	  [        U	[         R                  [         R                  [         R                  45      (       d  MI  [        S5      e   [        XS9  XX4$ ! [         a  n[        SU 35      UeS nAff = f)Nexec)moder-   r	   r?   zNo function found.z,Only a single top-level function is allowed.z-Top-level node must be a function definition.z Async functions are not allowed.z=Decorators are not allowed (they execute at definition time).z)Nested functions/classes are not allowed.r   )rJ   rY   rZ   r   listbodyr   r^   r   FunctionDefAsyncFunctionDefdecorator_listr   ClassDefr   )
r   r   r   r   r   r_   r`   r   r   r   s
             r)   validate_single_function_sourcer     sV   7yyf- 		?D"47++ABx/00
4yA~IJJ7DdS__c.B.BCDDJKK$,,--k=>>#3Z[[$Ay!coos/C/CS\\RSS"#NOO	   "$\:9  7]1#./Q67s   F	 	
F'F""F'full)r   r   r   r   builtins_policyr   c                   [        U UUUUS9u  pgUS:X  a  [        R                  nGOfUS:X  GaT  0 S[        R                  _S[        R                  _S[        R
                  _S[        R                  _S[        R                  _S	[        R                  _S
[        R                  _S[        R                  _S[        R                  _S[        R                  _S[        R                  _S[        R                  _S[        R                  _S[        R                   _S[        R"                  _S[        R$                  _S[        R&                  _[        R(                  [        R*                  [        R,                  S.EnO[/        S5      eSU0n	0 n
 [1        USS[2        R4                  R6                  SS9n[9        XU
5        U
R?                  UR@                  5      =(       d    U	R?                  UR@                  5      n[C        U[D        RF                  5      (       d  [=        S5      eU$ ! [:         a  n[=        SU 35      UeSnAff = f)z
builtins_policy:
  - "full": expose the standard Python builtins (what you asked for).
  - "allowlist": expose a small safe subset (shown below).
r   r   	allowlistabsr   anybooldict	enumeratefloatintr^   r   maxminpowranger   roundr   )sumtuplezipz-builtins_policy must be 'full' or 'allowlist'__builtins__z<user_code>r   T)filenamer   flagsdont_inheritz$Failed while defining the function: Nz"Compiled object is not a function.)$r   _py_builtins__dict__r   r   r   r   r   r   r   r   r^   r   r   r   r   r   r   r   r   r   r   r   
ValueErrorcompiler   annotationscompiler_flagr   r$   r   getr    r   typesFunctionType)r   r   r   r   r   r   r_   	func_nodeexposed_builtinsgloblocr+   r`   fns                 r)   load_single_functionr    s]    6!+-$=OD & '00	K	'
<##
<##
 <##
 L%%	

 L%%
 //
 \''
 <##
 <##
 L%%
 <##
 <##
 <##
 \''
 --
  \''!
" <###
$  ##!''##)
. HII,-D
C
N$**88
 	T 
	 	<DHHY^^$<Bb%,,--?@@I  NA!EFAMNs   1H/ /
I9IIc                 ^    [        U 5      n[        R                  " UR                  0 5      nU$ )z=
Creates a singular Python function which disallows globals.
)r  r  r	  __code__)functionfs     r)   r   r   -  s)     	X&A1::r*AHr=   c                       U " U6 $ ! [          a+  n[        USS 5      [        R                  :X  a   S nAM6  e S nAff = f)Nerrno)OSErrorr   r  EINTR)r   r   r`   s      r)   _retry_eintrr  8  s?    
	; 	q'4(EKK7	s    
=88=g?)strictleewaysecondsr  r  c          	   #   
  ^^#    U S::  a  [        S5      e[        [        S5      (       d  [        S5      e[        R
                  " 5       [        R                  " 5       La  [        S5      e[        R                  " 5       nX0-   n[        R                  " [        R                  5      n[        R                  " [        R                  5      u  pgUS::  a  U O
[        X5      mSmUU4S jn[        US	S
5        [!        [        R                  [        R                  U5          [        R"                  " [        R                  S
5        [!        [        R(                  [        R                  T5        Sv   [        R                  " [        R*                  5      n	 [!        [        R                  [        R*                  [        R,                  5         [!        [        R(                  [        R                  S5        [!        [        R                  [        R                  U5        US:w  d  US:w  aY  [/        [        R                  " 5       U-
  S5      n
[/        Xj-
  S5      n[!        [        R(                  [        R                  X5        [!        [        R                  [        R*                  U	5        U(       a<  T(       d4  [        R                  " 5       nXU-   :  a  [1        SU S SX-
  S S35      eggg! [$        [&        4 a     GNf = f! [!        [        R                  [        R                  U5        f = f! [!        [        R                  [        R*                  U	5        f = f! [        R                  " [        R*                  5      n	 [!        [        R                  [        R*                  [        R,                  5         [!        [        R(                  [        R                  S5        [!        [        R                  [        R                  U5        O.! [!        [        R                  [        R                  U5        f = fUS:w  d  US:w  aY  [/        [        R                  " 5       U-
  S5      n
[/        Xj-
  S5      n[!        [        R(                  [        R                  X5        [!        [        R                  [        R*                  U	5        O.! [!        [        R                  [        R*                  U	5        f = fU(       a<  T(       d4  [        R                  " 5       nXU-   :  a  [1        SU S SX-
  S S35      ef f f = f7f)u  
Enforce a wall-clock time limit using SIGALRM/ITIMER_REAL.

- Earliest deadline wins (respects any currently armed ITIMER_REAL).
- EINTR-safe setup/teardown; resists Ctrl+C during cleanup.
- strict=True: 'fail-closed' — if body returns after the deadline and the
  SIGALRM handler didn't get to run, raise TimeoutError on exit anyway.
- Unix-like OS, main thread only. Process-wide SIGALRM: not composable with other users.
r	   seconds must be > 0ry   z2time_limit requires Unix setitimer/SIGALRM supportz,time_limit must be used from the main threadg        Fc                 (   > Sm[        STS S35      e)NTTimed out after gs)r   )signumframedeadlinefireds     r)   _handlertime_limit.<locals>._handler_  s    -hq\;<<r=   __time_limit_handler__TNzExceeded time limit (r   u"   s) without interrupt; elapsed ≈ z.3fzbs. The protected code likely blocked in a C extension or another SIGALRM user clobbered the timer.)r  hasattrrj   NotImplementedError	threadingcurrent_threadmain_threadr   time	monotonic	getsignalrw   	getitimerrz   r   setattrr  siginterruptAttributeErrorr  ry   SIGINTrx   r   r   )r  r  r  startdeadline_atold_handlerprev_remainingprev_intervalr&  
old_sigintelapsed	remainingnowr$  r%  s                @@r)   
time_limitr?  B  s     !|.//6;''!"VWW!)>)>)@@IJJNNE/K""6>>2K$*$4$4V5G5G$H!N )C/wS5QHE= H.59%	5 	V%%v'9'98D %%fmm4
	Cv~~FIV--v/A/A3GV]]FNNKH $(<dnn.6< 8#>	V--v/A/A9\zB %.."C6)) #+GA; 7##&;s"3 4vv  *  61 ( 		 V]]FNNKH zB %%fmm4
	Cv~~FIV--v/A/A3GV]]FNNKHV]]FNNKH $(<dnn.6< 8#>	V--v/A/A9\zBLzB %.."C6)) #+GA; 7##&;s"3 4vv  *  6s   DU#%K6 -M) 5$U7L; )L ;BL; 	A-U6L
M) 	L

M) +L88L; ;+M&&U)%U	7S)P0*S+QA(S-*U	+TAU		Uc                       \ rS rSrSrg)RemoteTracebackErrori  rE   N)rF   rG   rH   rI   rM   rE   r=   r)   rA  rA    s    r=   rA  spawng      ?start_method
kill_gracec                   [         R                  " U5      nUR                  SS9u  pxS n	UR                  XXU4S9n
SU
l        U
R                  5         UR                  5          UR                  U5      (       aS  UR                  5       u  pU
R                  5         US:X  a  U UR                  5         $ Uu  pn[        U SU SU 35      eU
R                  5         U
R                  U5        U
R                  5       (       a!   U
R                  5         U
R                  5         [        SUS	 S
35      e! [         a     $ f = f! U
R                  5         f = f! [          a^     U
R                  5         U
R                  U5        U
R                  5       (       a   U
R                  5         U
R                  5         e ! e = ff = f!  UR                  5         f ! [         a     f f = f= f)NF)duplexc                     U" U0 U=(       d    0 D6nU R                  SU45         U R                  5         g ! [         aP  nU R                  SUR                  R                  [	        U5      [
        R                  " 5       445         S nANgS nAff = f! [         a     g f = f!  U R                  5         f ! [         a     f f = f= f)Nokerr)	sendr   	__class__rF   r   	traceback
format_exccloser$   )
entry_connr  r   kwresr`   s         r)   _child"_run_in_subprocess.<locals>._child  s    		Q%28%COOT3K(  "	  	]OOUQ[[%9%93q69CWCWCY$Z[\\	]
    " s]   $8 B 
BABB% BB% 
B"!B"%C'B87C8
CCCC)targetr   rI  z: z
Remote traceback:
r  r   r!  )mpget_contextPipeProcessdaemonr6  rO  pollrecvr   r$   rA  	terminateis_alivekillr   KeyboardInterrupt)r   r  r   kwargsrD  rE  ctxparent_conn
child_connrS  prockindpayloadr    msgtbs                   r)   _run_in_subprocessrj    s   
..
&C!hheh4K
 ;;fF+K;LDDKJJL"G$$',,.MDIIKt|2	1 !(2*dV2cU:OPRt+TUU NNIIj!}} IIKIIK!1'!A>??  		 IIK 		NNIIj!}}				E		 		s   %?E %D56AE E  E 5
EEEE 
G%AF<;G<F>>GG G(GG(
G%"G($G%%G(>   forkrB  
forkserverrj   rk  )backendrD  rE  rm  rD  rE  .c                   ^ ^^^ T S::  a  [        S5      eT[        ;  a  [        S[        [        5       ST< 35      eS[        S[        4   S[        S[        4   4UUU U4S jjnU$ )	a  
Decorator that enforces a time limit.

backend:
  - "signal": uses SIGALRM (fast, in-process; only cooperative C code).
  - "process": runs function in a child and kills it on timeout (robust).
  - "auto": uses signal backend if function source is safe, otherwise process.

If backend="signal" but the function contains patterns that could escape
signal-based timeouts (detected via check_signal_escape_patterns), or if
the function source cannot be inspected, automatically falls back to
the process backend.

start_method (only used when backend="process" or auto fallback):
  - "fork": copies parent process memory (fast, works in notebooks/Colab).
  - "spawn": starts fresh Python interpreter (slower, safer for CUDA).
  - "forkserver": reuses a server process for forking (balance of both).
r	   r  z%Unsloth: start_method must be one of z, got r   .r   c                    >^ ^ TmTS;   a6   [         R                  " T 5      n[        U5      u  p#U(       d  SmOTS:X  a  Sm[        T 5      S[        4UU UUU	4S jj5       nU$ ! [        [        4 a    Sm N6f = f)N)rj   autoprocessrp  rj   r   c            	         > TS:X  a  [        T5         T" U 0 UD6sS S S 5        $ TS:X  a  [        TTXTTS9$ [        S5      e! , (       d  f       g = f)Nrj   rq  rC  z.backend must be 'signal', 'process', or 'auto')r?  rj  r  )r   ra  effective_backendr   rE  r  rD  s     r)   wrapper;execute_with_time_limit.<locals>.decorator.<locals>.wrapper  sb     H,(00 )("i/)$7CPZ\ \ !!QRR )(s   A
A)inspect	getsourcer   r  	TypeErrorr   r   )
r   r   safe_rt  rs  rm  rE  r  rD  s
   `    @r)   	decorator*execute_with_time_limit.<locals>.decorator  s    #((	. **406v>(1%&(0%
 
t	S 	S 	S 
	S  Y' .$-!.s   ,A$ A$ $A98A9)r  _VALID_START_METHODSr]   r   r   )r  rm  rD  rE  r{  s   ```` r)   r   r     sz    2 !|.////3F;O4P3QQWXdWgh
 	
a( Xc1f-=  4 r=   c                   .    \ rS rSrSrSS jrS rS rSrg)	r   i  z
Benchmarks functions correctly by wiping cache away
Benchmarker(trials = 1, timeout = 10).benchmark(output_function["matmul"], [(A_list, B_list)])
c                     [         R                  " S[         R                  S9U l        Xl        X l        US:  d   eX0l        g )Nl        )dtyper	   )npzerosuint8buffertrialsloopstimeout)r8   r  r  r  s       r)   ro   Benchmarker.__init__  s4    hh5rxxH
{{r=   c                 ~    U =R                   S-  sl         [        U R                   S S S2   R                  5       5      $ )Nr?   i   )r  r   r   rn   s    r)   thrashBenchmarker.thrash  s1    q4;;vv&**,--r=   c                    [        U5      U R                  :X  d   e/ n/ nSn[        U R                  5       H  n[        R
                  " 5         [        R                  " 5         U R                  5         [        R                  " 5       n[        U R                  5       H)  n [        U R                  5         U" X(   6   S S S 5        M+     [        R                  " 5       n
[        R                   " 5         UR                  X-
  [#        SU R                  5      -  5        M     [%        [&        R(                  " U5      5      [%        [&        R*                  " U5      5      [%        [        U5      S:  a  [&        R,                  " U5      OS5      UUS.$ ! , (       d  f       GM  = f! [         a  n	US-  n S n	A	GM  S n	A	f[         a&  n	UR                  [        U	5      5         S n	A	GML  S n	A	ff = f)Nr	   r?   )	median_nsmean_nsstdev_ns
exceptionstimeouts)r^   r  r   r  gccollectdisabler  r.  perf_counter_nsr?  r  r   r$   r   r   enabler   r   
statisticsmedianfmeanpstdev)r8   r  	argumentssamplesr  	timed_outrz  t_startir`   t_ends              r)   	benchmarkBenchmarker.benchmark  sh   9~+++
	t{{#AJJLJJLKKM**,G4::&.#DLL1 ),/ 21 ' ((*EIIKNNEOAtzz0BBC $" Z..w78:++G45#g,:JJ--g6PQR%"
 	
 21# #NI  .%%c!f--.sB   "F&7F?F&
F#F&#F&&
G/0F<<G/	G**G/)r  r  r  r  N)   r?      )	rF   rG   rH   rI   __doc__ro   r  r  rM   rE   r=   r)   r   r     s    .

r=   r   c                    [         R                   " [         R                  [         R                  5      n UR                  S5        UR	                  X45      nUS:X  a   UR                  5         g UR                  5         g! [         R                   a(  n[        SU 35         SnAUR                  5         gSnAff = f! UR                  5         f = f)z8Check if the port like localhost:8000 is open or closed r?   r	   TFzSocket error: N)socketAF_INETSOCK_STREAM
settimeout
connect_exrO  r.   print)hostportsockresultr`   s        r)   r   r   E  s    ==););<D$.Q; 	

 
 	

	 << qc"#

	 	

s)   )B B>B9$C 9B>>C Cworking_directoryc                    [         R                  R                  U SSS5      n[         R                  R                  U SSSS5      n[         R                  R                  U S5      n[         R                  R                  U5      (       a  U  [         R                   U 3$ [         R                  R                  U5      (       a  U$ U  [         R                   U 3$ )z
Auto-detect OpenEnv version and return correct PYTHONPATH.

OpenEnv structure changed at commit 83dda10 ("move envs to root"):
- New structure (commit 151+): envs/ at root, openenv in src/
- Old structure (commits 514-152): envs/ in src/
envsopenspiel_envz	client.pysrc)ospathr   r   pathsep)r  root_client
src_clientsrc_paths       r)   _get_openenv_pythonpathr  W  s     '',,0&/;WK/Q\]Jww||-u5H	ww~~k""#$RZZL
;;	
	#	# $$RZZL
;;r=   i  z!envs.openspiel_env.server.app:appr  serverc                   ^
 [        U5      [        L d   e[        U 5      [        L a  U S:  a  U S::  d   e[        U5      [        L d   eUc   e[        U5      [        L d   e[	        U5      nUR                  S5      U:w  a  [        U5      nXdS'   SU  3m
U
4S jnU" U5      nSnUGc  [        R                  " SS5      n SU  3m
[        SU  3S	S
9  [        R                  " [        R                  SSUSSS[        U 5      /U[        R                  [        R                  SUS9nSn	[        SU 5      (       dR  [        R                   " S5        U	S-  S:X  a
  [        SS	S
9  U	S-  n	U	S:X  a  [#        S5      e[        SU 5      (       d  MR  [        5         U" T
S9nU" U5      nUb  OUS-  nUS:X  a  [#        S5      eUc  GM  Ub  X4$ g)z?Finds a new port or checks if the old open port actually works r	   i  N
PYTHONPATHzhttp://localhost:c                    > U bP   [         R                  " T S3SS9R                  nSU;  a%  [        U S5      (       a  U R	                  5         S n U $ U $ U $ !    N= f!   S n  U $ = f)Nz/healthg?)r  s   healthyrO  )requestsr  contentr)  rO  )rq  request	localhosts     r)   check_openenv_works+launch_openenv.<locals>.check_openenv_works  s{    
",,)G'<LTTW,'1J1J "G  #N  !D
s(   9A A A A AA A%i(#  z0Unsloth: Creating new OpenEnv process at port =  )endz-muvicornz--hostz0.0.0.0z--portT)envstdoutstderrtextcwdr  g{Gz?
   r6   r?   ip  zZUnsloth: We tried launching a new OpenEnv Localhost for 60 seconds, but we still failed :()base_urlr  zRUnsloth: We tried launching a new OpenEnv process 30 times, but we still failed :()r   r   r   r   r  r  randomrandintr  
subprocessPopenr   
executablePIPEr   r.  sleepr   )r  openenv_processr  r  environmentopenenv_classcorrect_pythonpathr  r  wait_trialsr  s             @r)   r   r   n  s     $$$:t/@@@!"c)))$$$<3 11BC|$(::;'$6L!#D6*I */:O F

!~~dG,'v.	@GrR$**^^T9fh	8UXY]U^_____#
 {D11JJtR1$c$1Kd""#  A  A {D11 	'9=-o>&!R<stt9 
!: "$$ #r=   )A__all__rJ   rv  r   r   pathlibr
   	functoolsr  r   builtinsr  r  r  r.  r  numpyr  rj   
contextlibr   r   r+  r  typingr   r   r   r   r   	lru_cacher*   r   r   r   stmtr   r   ASTr   r   r   r  r   r  r   r?  multiprocessingrV  rM  r   rA  rj  	frozensetr}  r   r   r  r  r  r  r   r  r   r   rE   r=   r)   <module>r     s  "   
           %    0 0CL  2 1s 1d Ds DJ SXX $  377 t  VZ  f  ft  fB  "#&*&& & 	&
 &  $&N  !"&*!DD D 	D
 D  $D DJ   15t J J$ Ju J JV   	< 	 ELX[ 7p  !@A 
 :: : 	:
 : xQ (36"223:v +
 +
X 
     <s <s <0 "6H%H% H% 	H%R r=   