Description
I've been cleaning up inheritance mismatches. I've found that several modules with a C implementation fudge the module name of their classes. For example:
ReferenceType
is a class defined in the _weakref
C implementation, and then imported from there into the weakref
module. Because it's a C implementation, it's free to declare it's own qualified name, and calls itself weakref.ReferenceType
: https://github.com/python/cpython/blob/main/Objects/weakrefobject.c#L368C1-L368C1
The intention, I believe, being that this class canonically lives in the weakref
module, and the fact that it's being defined in _weakref
is an implementation detail which is hidden at runtime. Typeshed declares the class in _weakref.pyi
, which means it gets a qualified name of _weakref.ReferenceType
I can see two possible arguments:
- Typeshed should continue to follow the layout of implementation over the declared implementation. e.g.
ReferenceType
is defined in_weakref
originally, so that's the correct place for it.
OR
- Typeshed should follow the declared implementation over the layout. e.g.
ReferenceType
considers itself to live in theweakref
module, that's where the majority of users will get it from, so that's the correct place for it.
This pattern pops up in a lot of places: in _ast
, _decimal
, and _sqlite3
are some of the others I've noticed. I suspect the current state of typeshed is inconsistent on this issue, since not all modules that have a C implementation currently have a _foo.pyi
stub file.
Is there a consensus among typeshed's maintainers here? I'm a little biased towards option 2 at the moment, since I'm trying to make as many inheritances match as I can, but I think there's a good argument for either side, and this is, in the end, a very minor issue with not much practical effect.