Allan Daemon <rea....@gmail.com> added the comment:

> I actually have no idea where dir() gets its information.

I will share what I find out already, so it may hopefully be helpful.

The dir function used is the general object.__dir__ function, defined in 
Objects/typeobject.c:type___dir___impl(), that just takes everything from 
__dict__ of the class and its bases.

But the GenericAlias is trying hard pretending to be the origin class, so when 
you ask for the __dict__, it gives the original class, not the GenericAlias:

>>> list[int].__dict__ == list.__dict__
True

There are also some other things that seems a bit strange, but it may just be 
right:

>>> list.__class__
<class 'type'>
>>> list[int].__class__
<class 'type'>

>>> type(list)
<class 'type'>
>>> type(list[int])
<class 'types.GenericAlias'>

This happens because of the tp_getattro function 
genericaliasobject.c:ga_getattro(), that takes the attributes from the origin 
except for the following names, that are taken from the GenericAlias itself:
    "__origin__",
    "__args__",
    "__parameters__",
    "__mro_entries__",
    "__reduce_ex__",
    "__reduce__",

So, when the dir() is getting the __dict__, it gets list.__dict__ and base 
(object) instead of GenericAlias. Looking the ga_getattro() calls when dir() is 
fired, it also gets the __class__ attribute after getting the __dict__. Adding 
one or another makes the dir() showing up the GenericAlias attributes, but 
others went missing.

An idea to solve this spefic issue could be overriding the __dir__ method, 
something like this python code (written in c, of course):

def __dir__(self):
    r = super().__dir__()
    return r + attribute_names_list + method_names_list


But I wonder what else should not be forwarded to origin.

----------
components: +Interpreter Core -Documentation, Library (Lib)

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41780>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to