
    ȅi"                        S r SSKrSSKJrJrJr  SSKJrJrJ	r	J
r
  SSKJr  SSKrSSKJr  SSKJrJrJr  SSKJr  S	S
KJr  S	SKJr  S	SKJrJrJr  SSKJr  SSK J!r!  SSK"J#r#  SSK$J%r%  SSK&J'r'J(r(  \	(       a  SSK)J*r*  \" S5      r+\
" S5      r,S\-S\\\+\,4   /\\+\,4   4   4S jr. " S S\(5      r/ " S S\'5      r0g)a  
This module implements variable tracking for TorchScript objects during Dynamo tracing.

The TorchScriptObjectVariable class provides specialized handling for TorchScript
objects with strong safety guarantees by:
- Enforcing method-call-only access to prevent unsafe attribute manipulation
- Converting graph breaks into hard errors via _raise_hard_error_if_graph_break
- Proper proxy and source tracking for TorchScript method calls
- Integration with higher-order operators for method call handling

Key safety features:
- Strict validation that only method calls are allowed (no direct attribute access)
- Immediate error reporting for potentially unsafe operations
- Proper source tracking for debugging and guard installation
- Safe handling of TorchScript object method calls through torchbind

The module ensures that TorchScript objects are handled safely during tracing
by limiting operations to known-safe patterns and failing fast for unsafe usage.
    N)CallableIterableSequence)AnyOptionalTYPE_CHECKINGTypeVar)	ParamSpec)Source)is_opaque_reference_typeis_opaque_typeis_opaque_value_type)Proxy   )graph_break_hints)	skip_code)unimplementedUnsafeScriptObjectErrorUnsupported   )VariableTracker)ConstantVariable)ConstDictVariable)TupleVariable)UserDefinedObjectVariableUserDefinedVariable)InstructionTranslator_P_Treasonreturnc                 \    S[         [        [        4   S[         [        [        4   4S jnU$ )Nfnr!   c                    ^  [         R                  " T 5      S[        R                  S[        R                  S[
        4U 4S jj5       nU$ )Nargskwargsr!   c                  f   >  T" U 0 UD6$ ! [          a  n[        UR                  5      UeS nAff = fN)r   r   msg)r%   r&   er#   s      _/home/james-whalen/.local/lib/python3.13/site-packages/torch/_dynamo/variables/script_object.pygraph_break_as_hard_errorQ_raise_hard_error_if_graph_break.<locals>.deco.<locals>.graph_break_as_hard_error8   s9    <4*6** <-aee4!;<s    
0+0)	functoolswrapsr   r%   r&   r   )r#   r,   s   ` r+   deco._raise_hard_error_if_graph_break.<locals>.deco7   sC    			<RWW 	<		 	<b 	< 
	< )(    )r   r   r   )r    r0   s     r+    _raise_hard_error_if_graph_breakr3   4   s.    )"b&! )hr2v&6 ) Kr2   c                      ^  \ rS rSrSrS\S\SS4U 4S jjrS\4S jrS\4S	 jr	S\4S
 jr
S\4S jrSSS\\   S\\\4   S\4S jrSrU =r$ )OpaqueObjectClassVariableD   z
A variable that represents an opaque object class (not instance).
Since UserDefinedClassVariable has some special handling for side effects,
we have a separate class here which will directly return the object when
__init__ is called.
valuer&   r!   Nc                 2   > [         TU ]  " S0 UD6  Xl        g )N )super__init__r7   )selfr7   r&   	__class__s      r+   r;   "OpaqueObjectClassVariable.__init__L   s    "6"
r2   c                     U R                   $ r(   r7   r<   s    r+   as_python_constant,OpaqueObjectClassVariable.as_python_constantP       zzr2   c                 >    [        [        U R                  5      5      $ r(   )r   typer7   rA   s    r+   is_python_hashable,OpaqueObjectClassVariable.is_python_hashableS   s    #D$455r2   c                     U R                   $ r(   r@   rA   s    r+   as_proxy"OpaqueObjectClassVariable.as_proxyV   rD   r2   c                 N    U R                   R                   SU R                   S3$ )N())r=   __name__r7   rA   s    r+   __repr__"OpaqueObjectClassVariable.__repr__Y   s$    ..))*!DJJ<q99r2   txr   r%   c           	         [        U R                  5      (       aD  [        U R                  R                  R                  5        [        SSU R                   S3SS/S9  [        [        U5      5      n[        UR                  5        VVs0 s H  u  pV[        U5      U_M     snn5      nU R                  " UR                  5       0 UR                  5       D6n[        R                  X5      $ s  snnf )Nz:An opaque object was created in the middle of the program.zOpaque object type: .z}Opaque objects cannot be created inside the torch.compile region. They must be created before entering the compiled function.zsPlease create the opaque object before calling torch.compile and pass it in as an argument or as a global variable.gb_typecontextexplanationhints)r   r7   r   r;   __code__r   r   listr   itemsr   rB   TorchScriptObjectVariablecreate)	r<   rR   r%   r&   var_argskv
var_kwargs
opaque_objs	            r+   call_function'OpaqueObjectClassVariable.call_function\   s     $DJJ//djj))223T.tzzl!<RM !d,&06?a !#?

 ZZ))+
,,.


 )//
GG @s   C.
r@   )rO   
__module____qualname____firstlineno____doc__r   r;   rB   boolrG   rJ   strrP   r   r   dictrd   __static_attributes____classcell__r=   s   @r+   r5   r5   D   s    c S T C 6D 6# :# :"H#"H '"H S/)*	"H
 
"H "Hr2   r5   c                   >  ^  \ rS rSr% 0 r\\S 4   \S'   \S\	S\
4S j5       r\S\S\S\SS 4S	 j5       r SS\S\S\\   S\SS
4
U 4S jjjrS\4S jr\" S5      SSS\S\4U 4S jj5       r\" S5      SSS\S\\   S\\\4   S\4
S j5       rS\4U 4S jjrSrU =r$ )r]      _fake_script_object_cacheuser_clsr!   c                 Z    [        U[        R                  5      =(       d    [        U5      $ r(   )
issubclasstorchScriptObjectr   )clsrs   s     r+   is_matching_cls)TorchScriptObjectVariable.is_matching_cls   s    (E$6$67S>(;SSr2   proxyr7   optionsc                     [        X40 UD6$ r(   )r]   )r{   r7   r|   s      r+   r^    TorchScriptObjectVariable.create   s    (AAAr2   Nsourcer&   c                    > [         TU ]  " U40 UD6  Xl        [        U R                  [        R
                  R                  5      (       a"  X R                  R                  R                  S'   X0l	        g )Nexample_value)
r:   r;   r{   
isinstancerv   fxr   nodemetar   )r<   r{   r7   r   r&   r=   s        r+   r;   "TorchScriptObjectVariable.__init__   sP     	)&)
djj%((..1149JJOO  1r2   c                     U R                   $ r(   )r{   rA   s    r+   rJ   "TorchScriptObjectVariable.as_proxy   rD   r2   z<Dynamo cannot safely trace script object due to graph break.rR   r   namec           
        > SSK Jn  SSKJn  SSKJn  [        [        U R                  5      5      (       a  [        TU ])  X5      nU$ [        U R                  S5      (       aA  [        U R                  R                  5      (       a  [        SS	U R                   S
U 3SS/S9  [        U R                  US 5      nUcO  [        SS	U R                   SU 3SU R                   SU S3SU SU R                   S3/[         R"                  QS9  [%        U5      (       d  [        SS	U R                   SU 3SS/S9  U R                  c   eUR'                  UU" U R                  U5      U US9$ )Nr   )call_torchbindr   )
AttrSourcer   ) TorchHigherOrderOperatorVariablescript_class_namez9Attempted to access attributes/methods on an OpaqueObjectvalue=z, attr=z:Attribute/method access of OpaqueObjects is not supported.z?Use custom operators instead of direct attribute/method access.rU   z.FakeScriptObject missing method implementation	, method=zTorchScript object z doesn't define the method rT   zEnsure the method z is implemented in z@Attempted to access non-callable attribute of TorchScript objectzWAttribute accesses of TorchScript objects to non-callable attributes are not supported.z-Use method calls instead of attribute access.)r   script_obj_varmethod_name)!torch._higher_order_ops.torchbindr   r   r   higher_order_opsr   r   rF   r7   r:   var_getattrhasattrr   r   r   getattrr   
USER_ERRORcallablemake)	r<   rR   r   r   r   r   resmethodr=   s	           r+   r   %TorchScriptObjectVariable.var_getattr   s    	E'FTZZ 011'%b/CJ4::233JJ((9
 9
 S GD6:XU	 T40>H IdV<1$**=XY]X^^_`(.A$**QO&11	 Z IdV<uC	 {{&&&/44dkk40	 5 
 	
r2   r%   c                 F    [        SSU R                   SU 3SU S3S/S9  g )Nz'Weird method call on TorchScript objectr   r   zThis particular method call (zn) is not supported (e.g. calling `__setattr__`). Most method calls to TorchScript objects should be supported.zAvoid calling this method.rU   )r   r7   )r<   rR   r   r%   r&   s        r+   call_method%TorchScriptObjectVariable.call_method   s@     	=TZZL	$8/v 6P P -
	
r2   c                 ~   > [        [        U R                  5      5      (       a  U R                  $ [        TU ]  5       $ r(   )r   rF   r7   r:   rB   )r<   r=   s    r+   rB   ,TorchScriptObjectVariable.as_python_constant   s/    TZZ 011::w)++r2   )r{   r   r(   )rO   rf   rg   rh   rr   rl   int__annotations__classmethodrF   rj   ry   staticmethodr   r   r^   r   r   r;   rJ   r3   rk   r   r   r   r   rB   rm   rn   ro   s   @r+   r]   r]      sZ   HJtC)D$DEJTt T T T Be BC BC B<W B B DH#&080@SV	 %  &F2
5 2
S 2
_ 2
2
p &F
#
 
 sm	

 S#X
 


&,C , ,r2   r]   )1ri   r.   collections.abcr   r   r   typingr   r   r   r	   typing_extensionsr
   rv   torch._guardsr   torch._library.opaque_objectr   r   r   torch.fx.proxyr    r   
eval_framer   excr   r   r   baser   constantr   dictsr   listsr   user_definedr   r   torch._dynamo.symbolic_convertr   r   r   rk   r3   r5   r]   r9   r2   r+   <module>r      s   (  8 8 8 8 '    
 !   " E E ! & $   H Dt_T]xB (2r6"223 :H 3 :Hzk, 9 k,r2   