Eu tenho um código que funcionou no Python 3.6 e falha no Python 3.8. Parece resumir-se a chamar a super
subclasse de typing.NamedTuple
, como abaixo:
<ipython-input-2-fea20b0178f3> in <module>
----> 1 class Test(typing.NamedTuple):
2 a: int
3 b: float
4 def __repr__(self):
5 return super(object, self).__repr__()
RuntimeError: __class__ not set defining 'Test' as <class '__main__.Test'>. Was __classcell__ propagated to type.__new__?
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: #def __repr__(self):
...: # return super(object, self).__repr__()
...:
>>> # works
O objetivo desta super(object, self).__repr__
chamada é usar o padrão em '<__main__.Test object at 0x7fa109953cf8>'
__repr__
vez de imprimir todo o conteúdo dos elementos da tupla (o que aconteceria por padrão). Existem algumas perguntas sobre como super
resultar em erros semelhantes, mas eles:
- Consulte a versão sem parâmetros
super()
- Já falhei no Python 3.6 (funcionou para mim antes da atualização 3.6 -> 3.8)
- Não consigo entender como corrigir isso de qualquer maneira, já que não é uma metaclasse personalizada sobre a qual tenho controle, mas a fornecida pelo stdlib
typing.NamedTuple
.
Minha pergunta é como posso corrigir isso, mantendo a compatibilidade com o Python 3.6 (caso contrário, eu usaria em @dataclasses.dataclass
vez de herdar typing.NamedTuple
)?
Uma questão paralela é como isso pode falhar no momento da definição, uma vez que a super
chamada incorreta está dentro de um método que ainda nem foi executado. Por exemplo:
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: def __repr__(self):
...: return foo
funciona (até chamarmos de __repr__
) mesmo que foo
seja uma referência indefinida. É super
mágico a esse respeito?
__repr__ = object.__repr__
em sua definição de classe funciona para mim em Python3.6 e Python3.8
typing.NamedTuple
; typing.NamedTupleMeta
, isso está fazendo algumas travessuras. super()
requer __class__
estar disponível em tempo de compilação , o que não é o caso aqui, aparentemente. Veja também: Forneça um __classcell__
exemplo para a metaclasse do Python 3.6
super
próprio objeto, não uma representação da suaTest
instância.