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?

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