Optional [Type [Foo]] raises a TypeError in Python 3.5.2

This code:

#!/usr/bin/env python from typing import Optional, Type class Foo(object): pass class Bar(Foo): pass def test_me() -> Optional[Type[Foo]]: print("Hi there!") return Bar if __name__ == "__main__": test_me() 

raises TypeError by 3.5.2:

 Traceback (most recent call last): File "./test.py", line 11, in <module> def test_me() -> Optional[Type[Foo]]: File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 649, in __getitem__ return Union[arg, type(None)] File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 552, in __getitem__ dict(self.__dict__), parameters, _root=True) File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 512, in __new__ for t2 in all_params - {t1} if not isinstance(t2, TypeVar)): File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 512, in <genexpr> for t2 in all_params - {t1} if not isinstance(t2, TypeVar)): File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 1077, in __subclasscheck__ if super().__subclasscheck__(cls): File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/abc.py", line 225, in __subclasscheck__ for scls in cls.__subclasses__(): TypeError: descriptor '__subclasses__' of 'type' object needs an argument 

whereas it works fine on 3.6. Same problem if I specify optionally as Union[None, Type[Foo]] .

Is there a workaround for 3.5.2 but still definitely annotate the return type?

+6
source share
3 answers

This is a bug in Python 3.5.2.

Optional[cls] is a wrapper for Union[cls, type(None)] that uses __subclasses__() to determine whether one class is a subclass of another.

However, Type is a subclass of type in Python 3.5.2, which means that

 Union[Type[anything], anything_else] 

eventually call

 type.__subclasses__() 

... which is a problem because type is a metaclass, and therefore it will be called with the class whose subclasses are searched, just as when calling the instance method in a regular class, you need to provide an instance of yourself, for example str.upper('foo') .

The problem is fixed in Python 3.5.3 (and, as you noticed, 3.6) when Type no longer a subclass of type .

+5
source

thanks Zero Piraeus

i had the same problem i am using python 3.5.2 i am editing the file usr / lib / python3.5 / typing.py

 class Type(type, Generic[CT_co], extra=type): 

CHANGED ON

 class Type(Generic[CT_co], extra=type): 

then it is fixed ...

0
source

I had the same issue in Python 3.2

I just installed the lower version of pandas

 pandas==0.24.2 

The default version is installed.

 pandas==0.25.1 

Hope this helps.

0
source

Source: https://habr.com/ru/post/1265763/


All Articles