classification
Title: typing: Classes that inherit `Generic[...]` indirectly aren't considered generic.
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: John Lennon, gvanrossum, levkivskyi
Priority: normal Keywords:

Created on 2019-10-13 08:31 by John Lennon, last changed 2019-10-13 10:43 by levkivskyi. This issue is now closed.

Messages (4)
msg354568 - (view) Author: John Lennon (John Lennon) Date: 2019-10-13 08:31
Given the file `example.py` with the following contents:


```python

from typing import Generic, TypeVar

KT = TypeVar("KT")
VT = TypeVar("VT")


class GenericMapping(Generic[KT, VT]):
    pass


class SomeImplMapping(GenericMapping):
    pass


a: GenericMapping[int, float]
b: SomeImplMapping[int, float]
```


I would expect `SomeImplMapping` to be generic as well as `GenericMapping`. However, currently this code fails with the following error:

```sh
Traceback (most recent call last):
  File "adt.py", line 18, in <module>
    b: SomeImplMapping[int, float]
  File "/usr/local/lib/python3.7/typing.py", line 254, in inner
    return func(*args, **kwds)
  File "/usr/local/lib/python3.7/typing.py", line 841, in __class_getitem__
    _check_generic(cls, params)
  File "/usr/local/lib/python3.7/typing.py", line 204, in _check_generic
    raise TypeError(f"{cls} is not a generic class")
TypeError: <class '__main__.SomeImplMapping'> is not a generic class
```


If I understand everything correctly, that's because `typing` doesn't check bases of the class to have `__parameters__` attribute:

https://github.com/python/cpython/blob/master/Lib/typing.py#L210

I did not found the restriction that only direct childs of `Generic[..]` class can be generic in the docs, so I think this is a bug.
msg354569 - (view) Author: John Lennon (John Lennon) Date: 2019-10-13 08:41
However, if I change the signature to:

```python

class SomeImplMapping(GenericMapping[KT, VT]):

```

Everything works just fine. And that's not really clear for me: we already have declared the generic types, we can not change the amount of those arguments, so why do we have to pass the same generic parameters again?

And even if that's the designed way to do things, I would expect the first example to fail not because of the type substitution, but for deriving the `GenericMapping` without generic type arguments provided (as if I'll try to derive `Generic` instead of `Generic[...]`).
msg354570 - (view) Author: John Lennon (John Lennon) Date: 2019-10-13 08:58
BTW I don't mind creating a PR for that issue if there will be an agreement on what is the desired behavior here.
msg354572 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2019-10-13 10:43
The docs for typing module are clear about this:
```
Using a generic class without specifying type parameters assumes Any for each position.
```
There is also an example involving a base class.
History
Date User Action Args
2019-10-13 10:43:13levkivskyisetstatus: open -> closed
resolution: not a bug
messages: + msg354572

stage: resolved
2019-10-13 08:58:18John Lennonsetmessages: + msg354570
2019-10-13 08:43:44xtreaksetnosy: + gvanrossum, levkivskyi
2019-10-13 08:41:51John Lennonsetmessages: + msg354569
2019-10-13 08:31:23John Lennoncreate