Sorry for answering so late, but I've stayed in a very rural area of Afghanistan and enjoyed my life :-) I also realized that this discussion has been removed from python-ideas, sorry! 2013/9/15 Nick Coghlan <ncoghlan@gmail.com>
On 15 September 2013 16:06, David Halter <davidhalter88@gmail.com> wrote:
2013/9/15 Nick Coghlan <ncoghlan@gmail.com>
If introspection tools want to show all the operations available *on the class*, then they need to include "dir(type(cls))" as well. So there
may be
a legitimate feature request for a new section in the pydoc output showing "class only" methods and attributes.
How about adding a keyword argument to `dir`: ``dir(object, with_class_methods=False)``?
I get that there are compatibility issues with changing the default `dir` functionality. But at the same time adding such an option could make it easier for beginners, why type attributes are not being listed (because one could read that in the `dir` docstring).
It's actually the metaclass methods/attributes that are missing. The trick with dir is it *stops at the class*, and thus always leaves out the metaclass. While in a important sense "classes are just objects", attribute access is a critical area where they're *different* from most other objects, because they play different roles in the descriptor protocol.
That means the question is whether it is worth adding an appropriate flag to dir(), over updating introspection tools (like IDLE's tab completion as Chris points out) to consider "dir(type(cls))" when appropriate.
"dir" currently works roughly as follows for instances:
- check the instance - check the class MRO
And for classes:
- check the class MRO
If an "include_metaclass" flag is added, then setting it to True has an obvious meaning for classes:
- check the class MRO - check the metaclass MRO
But what does "include_metaclass=True" mean for instances? You can't access metaclass attributes and methods from an instance - the attribute lookup only traverses one step. So, it could be reasonable to have "include_metaclass=True" do nothing for instances, and only change dir() behaviour for classes.
Good point. I haven't thought about this, but an "include_metaclass" option for dir can also be quite confusing (in the case of instances).
On the other hand, if the flag was called "include_class", then it would need to be tri-valued:
None: use appropriate default based on the kind of object True: default for instances, forces inclusion of the metaclass MRO for classes False: default for classes, forces omission of the class MRO (and thus all descriptors) for instances
Alternatively, if we don't change dir() at all and just document that getting a complete list of attributes means doing "sorted(set(dir(obj) + dir(type(obj))", we'd have something that works for all versions of Python, rather than something that was only available in 3.4+:
Yes, IMHO that's the least we should do. But I would strongly suggest to adjust the `dir` method docstrings (not only the online docs). I think that the current documentation really needs improvement (it is quite confusing now).
def full_dir(obj): ... return sorted(set(dir(obj) + dir(tyape(obj)))) ...
len(set(full_dir(1)) - set(dir(1))) 0 len(set(full_dir(int)) - set(dir(int))) 19 len(set(dir(type)) - set(dir(object))) 19
That's why my preference is for the latter approach - this isn't new behaviour, and it's introspection tools that don't handle metaclasses properly that need updating, rather than changing the dir() builtin.
Well, I would still opt for changing dir, but I can understand that that would cause serious backwards-compatibility issues. If you would do that, it would be something for a Python 4 (and we're not even close to that). So for now that really leaves us with documenting it better. I don't really like the "include_metaclass" option. Maybe your "include_class" might make a little bit more sense. But even that one would complicate things. Cheers! Dave
participants (1)
-
David Halter