-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime checkable protocols potential raising error with custom getattribute #105134
Comments
Thanks! Looks like the root cause here is probably a bug in |
One thing I noticed from exploring DictWrapper is it strangely satisfies d = _DictWrapper()
assert isinstance(d, dict) # Passes
assert issubclass(_DictWrapper, dict) # Fails This looks to come from library wrapt being used to make DictWrapper behave like a dict. It relies mainly on ObjectProxy for this. My rough gut is there's likely a reproducing example only using wrapt/ObjectProxy without needing tensorflow. It feels like it partially proxies dict but not enough here. |
Yes, so here's a repro that doesn't involve >>> import inspect
>>> from tensorflow.python.trackable.data_structures import _DictWrapper
>>> inspect.getattr_static(_DictWrapper(), 'bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\alexw\AppData\Local\Programs\Python\Python311\Lib\inspect.py", line 1825, in getattr_static
instance_result = _check_instance(obj, attr)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\AppData\Local\Programs\Python\Python311\Lib\inspect.py", line 1772, in _check_instance
instance_dict = object.__getattribute__(obj, "__dict__")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: this __dict__ descriptor does not support '_DictWrapper' objects I think there's probably bugs in CPython and [either tensorflow or wrapt] here. The |
Interesting! It looks like >>> import inspect, wrapt
>>> class Foo: pass
...
>>> class Bar(Foo, wrapt.ObjectProxy): pass
...
>>> inspect.getattr_static(Bar({}), 'bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\alexw\AppData\Local\Programs\Python\Python311\Lib\inspect.py", line 1825, in getattr_static
instance_result = _check_instance(obj, attr)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\AppData\Local\Programs\Python\Python311\Lib\inspect.py", line 1772, in _check_instance
instance_dict = object.__getattribute__(obj, "__dict__")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: this __dict__ descriptor does not support 'Bar' objects But on >>> import inspect, wrapt
>>> class Foo: pass
...
>>> class Bar(Foo, wrapt.ObjectProxy): pass
...
>>> inspect.getattr_static(Bar({}), 'bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\alexw\coding\cpython\Lib\inspect.py", line 1867, in getattr_static
raise AttributeError(attr)
AttributeError: bar Lots of changes have been made to |
It reproduces with the |
Here's a repro that doesn't involve Unfortunately it involves a 3,000-line C extension (I've just vendored |
This issue looks pretty related: |
The I think it's only possible for |
Haven't had a chance to investigate much, but here's the C stack trace (on main) for where the
|
I have this on my list to take a look at, but it may be some time next week before I can get to it. |
I looked into this a bit. Here's what's happening:
I'm not 100% sure about the logic behind Given all that, the question remains about what So my recommendation would be to close this issue as not a bug in Python. |
Thanks so much for the in-depth investigation @carljm! This confirms my suspicions, and I agree with your conclusion. |
Bug report
I'm unsure if this is more tensorflow bug or python bug but it does trace to this pr and error message traces to cpython source. I've also commented on issue in tensorflow side here.
With typing extensions an error message is produced of,
Your environment
I've tested on cpython 3.9.16 and 3.10.10 where using typing works. I'd suspect 3.11 will work as well. Using typing_extensions 4.6 triggers error with inspect.getattr_static usage. Reported here instead of typing extensions as adding getattr static there was backport from here. I'd expect this to reproduce on 3.12 although installing tf on 3.12 is likely tricky and easier to test with typing extensions. The _DictWrapper class is here and is like a subclass of
__dict__
with a custom getattribute to do some extra tracking of elements.I used latest version of tensorflow (2.12). The underlying error message comes from this line. As this can be triggered in attribute access unsure whether it should be TypeError vs AttributeError. If it was attribute error getattr static would catch it and be fine. If it needs to be type error then it's unclear to me whether tensorflow class is breaking some assumption or if getattr static should also catch type errors here. In particular it's interesting that
object.__getattribute__
can raise TypeError and inspect.getattr_static can fail.I'll try to look tomorrow if I can make a more self contained example that doesn't require tensorflow.
The text was updated successfully, but these errors were encountered: