jnsdrtlf
(Jonas Drotleff)
1
As discussed in this Pull Request, inspect.getmembers will call properties and other dynamic attributes, as it is using the getattr method. I proposed changing this to getattr_static, however, this will break compatibility with existing code.
Yury Selivanov (1st1) proposed to implement a getmembers_static function instead, that will use getattr_static. However, there are still many open questions:
- What should
getmembers_static return? Is getattr_static appropriate for every member? This would break some predicates (e.g. isclass , see comment above). There does not seem to be a “simple” solution.
- A technical question: The new method should pass most of the same tests as
getmembers . Would one just copy and paste the old ones? It would also share most of the code - except for maybe 1 line - with getmembers .
- Is there a reason for
getmembers to return a list of tuples? I would have suggested to use a dict instead, which feels more intuitive on first though.
- Why should getmembers return the value of the member (
getattr) anyway?
Any suggestions or ideas?
1 Like
encukou
(Petr Viktorin)
2
That would make it pretty much the same as dir(). Is that what you’re looking for?
I disagree with Yuri’s comment on the PR:
Since inspect.getmembers is an introspection function it shouldn’t run any actual code (i.e. executing getters). It should compute its result statically.
Generally, you can’t introspect something without running code. Any class could, for example, override dir to run some code.
The general assumption is that calling dir or getting an attribute should be “safe” – it shouldn’t be destructive, it shouldn’t take too long. But there are no actual safeguards against that. It’s hard to define what “safe” is: getting an attribute could legitimately fill a cache or even contact a database server. For something like a RPC proxy, even listing attributes would need to contact the network.
Petr, quoting from the entry you just linked to
Note Because dir() is supplied primarily as a convenience for use at
an interactive prompt, it tries to supply an interesting set of names
more than it tries to supply a rigorously or consistently defined set of
names, and its detailed behavior may change across releases.
In other words, dir is not designed to be used programmatically. It
is for interactive use.
I agree with Yuri, and disagree with you, about introspection code. One
reason for using introspection is specifically to avoid running code. If
you only care what the returned value of a member is, there’s no point
in using “introspection” when you can just do instance.member.
Introspection tools like “getmembers_static” are for the cases you want
to avoid that (if at all possible).
jnsdrtlf
(Jonas Drotleff)
4
In other words, dir is not designed to be used programmatically
I get your point and I’d generally agree with you. However, if I’m not mistaken, getmembers itself uses dir directly
jnsdrtlf
(Jonas Drotleff)
5
Sorry for the long delay, I’ve been sidetracked by some personal projects and studying. However, I still think that this issues is somewhat relevant but I do not feel like I am able to come to any conclusion about how getmembers should work. In some of my projects, getmembers still causes some side effects which lead me to implement my own getmembers_static.
@encukou clarified my third question, however the others are still not answered. I personally feel like there is a need for a method that returns all members with optional predicates just like getmembers but without any side effects. I’d love to get some more opinions on this and possibly an assessment on whether this is worth any effort. Maybe this issue is just too irrelevant.