Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
bpo-38337: Change getattr to inspect.getattr_static#16521
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
the-knights-who-say-ni commentedOct 1, 2019
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed thePSF contributor agreement (CLA). CLA MissingOur records indicate the following people have not signed the CLA: @jnsdrtlf For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please followthe steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day We also demand...A SHRUBBERY! You cancheck yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
should we add a test case ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thanks @jnsdrtlf, and welcome to CPython! 😎
I have a minor change to suggest for the NEWS entry, but otherwise this looks like a good improvement.
I also agree that adding regression test is probably a good idea.
Misc/NEWS.d/next/Library/2019-10-01-12-23-37.bpo-38337.QmLSXW.rst OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Actually, from looking at the test failures... I'm not sure if this is the desired behavior (and the docs are ambiguous). Maybe@1st1 can shed some light on the "correct" behavior of this function? |
Since |
brandtbucher commentedOct 1, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Okay then. So this probably doesn't need a new test, but the ~4 failing ones should be updated! |
I think it needs a new test. Basically an object with a property and a test ensuring that the property was discovered by getmembers, but the getter code wasn't run. |
As suggested by@brandtbucherCo-Authored-By: Brandt Bucher <brandtbucher@gmail.com>
Sounds good! I will get back to work and write a test later today. |
Make sure inspect.getmembers won't call properties or other dynamic attributes
The test @types.DynamicClassAttributedefeggs(self):return'spam' to be called. It asserts whether There is also some wierd behaviour when overwriting Failing tests:
|
Lib/test/test_inspect.py Outdated
@@ -1191,6 +1191,27 @@ def f(self): | |||
self.assertIn(('f', b.f), inspect.getmembers(b)) | |||
self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod)) | |||
def test_getmembers_static(self): | |||
class Foo: | |||
def __init__(bar): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Usedef __init__(self, bar):
please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Oups 🤦♂ Fixed in commit b415224
This comment has been minimized.
This comment has been minimized.
3j14 commentedOct 7, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Another inconsistent behaviour:
However, the following code does not return any properties: classFoo:def__init__(self,data):self._bar=data@propertydefbar(self):print('--BAR--')returnself._barinspect.getmembers(Foo('test'),inspect.isdatadescriptor) Result
Expected (new result) [('__class__',<attribute'__class__'of'object'objects>), ('__dict__',<attribute'__dict__'of'Foo'objects>), ('__weakref__',<attribute'__weakref__'of'Foo'objects>), ('bar',<propertyobjectat0x...>)] Is this correct so far? I am still confused about how |
Additionally, classFoo:passinspect.getattr_static(Foo('test'),'__class__') returns classFoo:pass# Will return [] if getattr_static is usedinspect.getmembers(Foo('test'),inspect.isclass) |
@@ -347,7 +347,10 @@ def getmembers(object, predicate=None): | |||
# like calling their __get__ (see bug #1785), so fall back to | |||
# looking in the __dict__. | |||
try: | |||
value = getattr_static(object, key) | |||
if isinstance(getattr_static(object, key), property): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Why can't we always usegetattr_static
? If there's a reason for not using it always, please describe that in a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This is related to my latest comment. Sorry, I didn't make this clear:
getattr_static(...,'__class__')
returns<attribute '__class__' of 'object' objects>
whereasgetattr
would return<class '__main__.Foo'>
. What should getmembers return? Usinggetattr_static
for every attribute doesn't seem to be the solution. It works fine with methods, functions and properties, but some edge cases seem to requiregetattr
(such as__class__
). It is not clear what the expected behaviour is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Got it, well, describe this in a comment :)
3j14 commentedOct 8, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
In3ac2093, I've changed
This feels more like a temporary fix - could be reverted to the first fix I've committed - although I am just not sure which is better. At this point,I am not sure what the actual expected behaviour should be. Someone should review this and the test case that is currently failing, as it expects a different behaviour (return the actual value of the property). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Jonas, I thought about this PR for some time and I think we should reject it. Modifyinggetmembers
in any way would break backwards compatibility in a very non-obvious way for many users. The ship to fix it has sailed.
We can add a new functiongetmembers_static
that would usegetattr_static
instead ofgetattr
. It must be a new distinct function, though.
bedevere-bot commentedOct 8, 2019
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
3j14 commentedOct 10, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@1st1 I share your thoughts on that. It does not seem to be obvious, what As for introducing a function
Is there a better place to discuss such questions? |
I think it would be better if you could post this to the python-ideas mailing list. I've very limited time and would hate to get this thing staled because of me. |
Or post it here:https://discuss.python.org/c/ideas |
I added a link to the discussion on the bug tracker. |
jaymegordo commentedAug 30, 2020
This would be very helpful, running into the same issue with inspect.getmembers evaluating@Property decorated methods. getmembers_static would solve it. |
Uh oh!
There was an error while loading.Please reload this page.
When calling
inspect.getmembers
on a class that has a property (@property
), the property will be called by thegetattr
call ingetmembers
.Example:
Result:
Expected (new result):
https://bugs.python.org/issue38337