@@ -229,7 +229,6 @@ def dynamic_getattr(self, tx: "InstructionTranslator", name):
229
229
# (1) the tensor is a traceable tensor subclass
230
230
# (2) We are getattr'ing an inner tensor from that subclass
231
231
if not self .source and is_traceable_wrapper_subclass (fake_val ):
232
- fake_val = self .proxy .node .meta ["example_value" ]
233
232
attrs , ctx = fake_val .__tensor_flatten__ ()
234
233
proxy = getattr (self .as_proxy (), name )
235
234
example_value = getattr (fake_val , name )
@@ -245,14 +244,19 @@ def dynamic_getattr(self, tx: "InstructionTranslator", name):
245
244
return VariableTracker .build (tx , example_value )
246
245
247
246
if not (self .source and self .source .subguards_allowed ()):
248
- raise NotImplementedError
247
+ return
248
+
249
+ from ..guards import get_closure_vars , GuardBuilder
249
250
250
251
# For local source, we associate the real value. We use this real value
251
252
# for implementing getattr fallthrough on the variable tracker base class.
252
-
253
253
# Note - this scope construction is mirrored in guards
254
254
# A subsequent PR will introduce a util.
255
- scope = {"L" : tx .output .local_scope , "G" : tx .output .global_scope }
255
+ scope = {
256
+ "L" : tx .output .local_scope ,
257
+ "G" : tx .output .global_scope ,
258
+ ** get_closure_vars (),
259
+ }
256
260
try :
257
261
# We raise in case we get a typerror bug w/ SuperSource.
258
262
# SuperSource has bugs in it atm, and can produce code like
@@ -261,23 +265,24 @@ def dynamic_getattr(self, tx: "InstructionTranslator", name):
261
265
# Which is incorrect, and violates the invariant that all sources should be eval()-able against the scope.
262
266
_input_associated_real_value = eval (self .source .name (), scope )
263
267
except Exception as exc :
264
- raise NotImplementedError from exc
268
+ msg = f"{ exc !r} raised in eval('{ self .source .name ()} ')"
269
+ raise NotImplementedError (msg ) from exc
265
270
271
+ real_value = getattr (_input_associated_real_value , name )
266
272
if _input_associated_real_value is None :
267
- raise NotImplementedError
273
+ return
268
274
269
275
if object_has_getattribute (_input_associated_real_value ):
270
- raise NotImplementedError
276
+ return
271
277
272
278
if get_custom_getattr (_input_associated_real_value ):
273
- raise NotImplementedError
279
+ return
274
280
275
- real_value = getattr (_input_associated_real_value , name )
276
281
if callable (real_value ):
277
282
# Callables have more nuanced handling, and we should let the existing system delegate here.
278
283
# Raising was past behavior and so should always be sound to fall back.
279
284
# Note - at a certain point we may want to handle
280
- raise NotImplementedError
285
+ return
281
286
282
287
attr_source = AttrSource (self .source , name )
283
288
install_guard (attr_source .make_guard (GuardBuilder .HASATTR ))
@@ -1215,8 +1220,6 @@ def var_getattr(self, tx: "InstructionTranslator", name):
1215
1220
from ..utils import numpy_attr_wrapper
1216
1221
from .builder import wrap_fx_proxy
1217
1222
1218
- result = None
1219
-
1220
1223
example_value = self .as_proxy ().node .meta ["example_value" ]
1221
1224
example_ndarray = tnp .ndarray (example_value )
1222
1225
@@ -1235,7 +1238,7 @@ def insert_into_graph():
1235
1238
(self .as_proxy (), name ),
1236
1239
{},
1237
1240
)
1238
- result = NumpyNdarrayVariable .create (tx , proxy )
1241
+ return NumpyNdarrayVariable .create (tx , proxy )
1239
1242
1240
1243
# These are awkward to implement. The standard playbook for torch._numpy
1241
1244
# interop is to trace a call into the torch._numpy wrapper which works for
@@ -1264,9 +1267,8 @@ def insert_into_graph():
1264
1267
unimplemented (f"TODO: add support for ndarray.{ name } " )
1265
1268
elif name in ["__version__" ]:
1266
1269
unimplemented ("delegate np.__version__ to NumPy" )
1267
- if result is None :
1268
- raise NotImplementedError
1269
- return result
1270
+ else :
1271
+ return super ().var_getattr (tx , name )
1270
1272
1271
1273
@staticmethod
1272
1274
def patch_args (name , args , kwargs ):
0 commit comments