class BaseStructureError(Exception):
def __init_subclass__(cls) -> None:
if cls is BaseStructureError:
raise RuntimeError
class StructureFoundError[T: object = object](BaseStructureError):
def __init__(self, structure: T, *args: object) -> None:
self.structure = structure
super().__init__(structure, *args)
class SynAlreadyTakenError[T: object = object](StructureFoundError[T]): pass
Why does this code give me the following error:
File "...\errors.py", line 17, in <generic parameters of SynAlreadyTakenError>
class SynAlreadyTakenError[T: object = object](StructureFoundError[T]): pass
~~~~~~~~~~~~~~~~~~~^^^
File "...\typing.py", line 399, in inner
return _caches[func](*args, **kwds)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "...\typing.py", line 1143, in _generic_class_getitem
for param in cls.__parameters__:
^^^^^^^^^^^^^^^^^^
AttributeError: type object 'StructureFoundError' has no attribute '__parameters__'
Is this an actual Python interpreter bug or am I missing something obvious?
In PEP 695 nothing was said about class cls[T: x = x](): … being valid syntax, so it has not been implemented in any way. Therefore the error likely stems from there.
Sadly, instead of raising a SyntaxError there, it just continue, but does not set __parameters__, which means that typing’s internals cannot parameterize your generic.
For context, I used Python 3.14rc3 in my example but just tried on Python 3.14.0 and the same issue occurs. I mean PEP 696 specified type defaults for type parameters, so this SHOULD work from my knowledge.
class Base:
def __init_subclass__(cls) -> None:
pass
class Sub[T](Base): pass
class SubSub(Sub[object]): pass
New code:
class Base:
def __init_subclass__(cls) -> None:
super().__init_subclass__()
class Sub[T](Base): pass
class SubSub(Sub[object]): pass
In a nutshell, I forgot to call super().__init_subclass__. I didn’t really expect that to be an issue because I thought it was just a simple hook you can use optionally, but apparently not.
This error message is pretty unfortunate. I’d be open to a PR to enhance the error message here, probably suggesting that if the .__parameters__ attribute does not exist, you probably forgot to call super().__init_subclass__().