Typing: TypeError: descriptor '__subclasses__' of 'type' object needs an argument

Created on 24 Aug 2016  路  8Comments  路  Source: python/typing

Behold:

ExcInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]]

produces a traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "typing.py", line 656, in __getitem__
    return Union[arg, type(None)]
  File "typing.py", line 556, in __getitem__
    dict(self.__dict__), parameters)
  File "typing.py", line 516, in __new__
    for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
  File "typing.py", line 516, in <genexpr>
    for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
  File "typing.py", line 1090, in __subclasscheck__
    if super(GenericMeta, self).__subclasscheck__(cls):
  File "/Users/guido/v/lib/python2.7/abc.py", line 179, in __subclasscheck__
    for scls in cls.__subclasses__():
TypeError: descriptor '__subclasses__' of 'type' object needs an argument
bug help wanted

Most helpful comment

@devxpy, typing will only get upgraded with Python if you are on Python 3.5+. Since this issue was fixed in August 2016, I believe any 3.5 release above 3.5.3 should work.

All 8 comments

FWIW a sufficient repro is

Optional[Type[BaseException]]

I also have a tentative fix -- simply don't inherit Type from type. That makes this problem go away and still passes the test. But I'm not sure how comfortable I am with that. Then again, I don't think subclassing Type[] is valid anyways, nor would using it in an isinstance() call. And I'm willing to give up subclass() calls too.

@ilevkivskyi What do you think?

@gvanrossum I am fine with your fix.

I would say that for every class from collections.abc that also appears in typing it should be possible to use issubclass and probably also isinstance provided it is used without type parameters (the logic here is that Any declares a fallback to dynamic typing and, e.g., Container without a type parameter means Container[Any]). So that one can use issubclass(cls, typing.Container) instead of issubclass(cls, collections.abc.Container). However, the same logic does not necessarily apply to built-in classes. I think, e.g., List[Any] could be treated as list, but equivalently we could just prohibit using List or List[Any] - what is the point of using those while there is much shorter and well known equivalent list.

In any case, we could fine-tune some details later (if necessary) in the process of resolution of #136

OK, that's sound reasoning. I will merge the fix.

This is still an issue on Python 3.5, mypy 0.641.

@devxpy: Do you have an example of code that fails. At least the second examples by @gvanrossum above pass fine for me with Python 3.5.6. What version of Python 3.5 were you using?

@srittau Sorry for not providing this earlier

$ python
Python 3.5.2 (default, Sep 26 2018, 15:59:34) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Optional, Type
>>> Optional[Type[BaseException]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/dev/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 649, in __getitem__
    return Union[arg, type(None)]
  File "/home/dev/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 552, in __getitem__
    dict(self.__dict__), parameters, _root=True)
  File "/home/dev/.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 "/home/dev/.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 "/home/dev/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 1077, in __subclasscheck__
    if super().__subclasscheck__(cls):
  File "/home/dev/.local/share/virtualenvs/zproc-eGzboTzC/lib/python3.5/abc.py", line 225, in __subclasscheck__
    for scls in cls.__subclasses__():
TypeError: descriptor '__subclasses__' of 'type' object needs an argument
>>> 

Will update to 3.5.6 now..

@devxpy, typing will only get upgraded with Python if you are on Python 3.5+. Since this issue was fixed in August 2016, I believe any 3.5 release above 3.5.3 should work.

I am on an Ubuntu 16.04.6 system, and I am getting this error for python 3.5.6
I compiled python 3.5.6 from https://www.python.org/ftp/python/3.5.6/Python-3.5.6.tgz

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FuegoFro picture FuegoFro  路  8Comments

zsluedem picture zsluedem  路  3Comments

mjr129 picture mjr129  路  3Comments

ChadBailey picture ChadBailey  路  5Comments

mitar picture mitar  路  5Comments