-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Description
Feature or enhancement
Proposal:
This issue aims to propose a new feature on top of fixing gh-85795.
gh-85795 stems from the necessity of using super()
inside methods of typing.NamedTuple
subclasses.
The documentation does not explicitly state it as unsupported, nor does it disrecommend the use of it.
Consequently, that behavior should be supported and the converse is considered a bug.
As in the StackOverflow question here, the developer tried their own implementation of __repr__
in the subclass.
And that's how I encountered the issue, too! I think it is very useful to be able to override the default NamedTuple
representation and add additional info on top of it/tweak it somehow. For that reason, one would intuitively use super().__repr__()
, since we inherit from NamedTuple
.
However, that is impossible with the current model of behavior in typed named tuples.
Typed named tuples are constructed from the existing implementation of tuple subclass factory collections.namedtuple
that does not insert anything other than tuple
above the final class in the MRO. Inheritance from NamedTuple
is only possible due to __mro_entries__
hacks on the typing.NamedTuple
function. To reference the default representation method of named tuples via super().__repr__()
, a middleman class representing the default implementations of named tuple methods between the underlying class and tuple
would be necessary. That is currently most likely impossible for backward compatibility reasons, something I learned from #126706 (comment), and does not appeal to me in terms of cost/benefit ratio.
Hence, since __repr__
is the only default method of NamedTuple
useful to be referenced in typing.NamedTuple
subclasses, and all other come from tuple
or object
, I propose adding _repr
to the named tuple interface. The default __repr__
implementation would be a direct wrapper of it. In typing.NamedTuple
, _repr
could not be overridden, but __repr__
could, to enable extendability with an optional reuse of _repr
.
In NamedTuple
subclasses all super().__repr__()
calls would resolve to tuple.__repr__()
.
This introduces no breaking changes, is additive only and retains the stable behavior of default __repr__
of named tuples.
With proper documentation, it can hint advanced named tuple users in how to create their own implementations of __repr__
reusing the existing __repr__
default implementation.
Example
class Import(NamedTuple):
target: str
def __repr__(self) -> str:
# super().__repr__() -> ('target',)
# self._repr() -> Import(target='target')
return f'<Token {self._repr()}>' # <Token Import(target='target')>
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response