Implement inspect.getmembers_static

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:

  1. 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.
  2. 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 .
  3. 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.
  4. Why should getmembers return the value of the member (getattr) anyway?

Any suggestions or ideas?

1 Like

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).

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

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.