Skip to content

Class construction with Generic classes and __init_subclass__ throws AttributeError #114326

Open
@treykeown

Description

@treykeown

Bug report

Bug description:

An AttributeError will be thrown in some cases involving classes which implement __init_subclass__ and are generic.

I don't know for sure that this is the only case that triggers the issue, but I encountered this when I had the following:

  1. A non-generic Base class which implements __init_subclass__
  2. A subclass Middle which is generic
  3. A subclass Bug of Middle which utilizes __class_getitem__
from typing import Generic, TypeVar

T = TypeVar("T")

class BaseOk:
    """No issues with generic classes without __init_subclass__"""

class OtherBaseOk(Generic[T]):
    """It's ok to have __init_subclass__ if the base is Generic"""
    def __init_subclass__(cls, **kwargs):
        print(f"OtherBaseOk: Initializing subclass {cls.__name__}")

class BaseBuggy:
    """This will trigger the bug for a Generic subclass with a non-generic subclass"""
    def __init_subclass__(cls, **kwargs):
        print(f"BaseBuggy: Initializing subclass {cls.__name__}")

# These will construct without issue.
class OkGeneric(BaseOk, Generic[T]): ...
class Ok(OkGeneric[int]): ...

# This is also ok
class OtherOk(OtherBaseOk[int]): ...

# These cause a bug
class BugGeneric(BaseBuggy, Generic[T]): ...
class NotBug(BugGeneric): ...
class Bug(BugGeneric[int]): ...  # Issue is here
# class AlsoBug(BugGeneric[T], Generic[T]): ...  # This would also trigger an issue

# `Bug` will never be built correctly.
raise Exception("This is never hit.")
$ python3 --version
Python 3.12.1
$ python3 '<...>/init_subclass_generic_bug.py'
OtherBaseOk: Initializing subclass OtherOk
BaseBuggy: Initializing subclass BugGeneric
BaseBuggy: Initializing subclass NotBug
Traceback (most recent call last):
  File "<...>/init_subclass_generic_bug.py", line 28, in <module>
    class Bug(BugGeneric[int]): ...  # Issue is here
              ~~~~~~~~~~^^^^^
  File "/opt/homebrew/Cellar/python@3.12/3.12.1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/typing.py", line 381, in inner
    return _caches[func](*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.12/3.12.1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/typing.py", line 1062, in _generic_class_getitem
    for param in cls.__parameters__:
                 ^^^^^^^^^^^^^^^^^^
AttributeError: type object 'BugGeneric' has no attribute '__parameters__'

I used Generic[] here, but I first encountered this in code which uses PEP 695 syntax, so I believe it applies equally to both.

CPython versions tested on:

3.12

Operating systems tested on:

macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions