hdl.ast: Test *Castable subclasses on definition.
The __init_subclass__ method fires on class definition rather than use. It also has the bonus impact that no __new__ method is defined, so the classes can be correctly detected as mix-in classes by modules such as enum.
This commit is contained in:
parent
a0307c343d
commit
5f094a23eb
2 changed files with 17 additions and 30 deletions
|
|
@ -41,12 +41,10 @@ class ShapeCastable:
|
|||
a richer description of the shape than what is supported by the core Amaranth language, yet
|
||||
still be transparently used with it.
|
||||
"""
|
||||
def __new__(cls, *args, **kwargs):
|
||||
self = super().__new__(cls)
|
||||
if not hasattr(self, "as_shape"):
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
if not hasattr(cls, "as_shape"):
|
||||
raise TypeError(f"Class '{cls.__name__}' deriving from `ShapeCastable` must override "
|
||||
f"the `as_shape` method")
|
||||
return self
|
||||
|
||||
|
||||
class Shape:
|
||||
|
|
@ -1319,15 +1317,13 @@ class ValueCastable:
|
|||
from :class:`ValueCastable` is mutable, it is up to the user to ensure that it is not mutated
|
||||
in a way that changes its representation after the first call to :meth:`as_value`.
|
||||
"""
|
||||
def __new__(cls, *args, **kwargs):
|
||||
self = super().__new__(cls)
|
||||
if not hasattr(self, "as_value"):
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
if not hasattr(cls, "as_value"):
|
||||
raise TypeError(f"Class '{cls.__name__}' deriving from `ValueCastable` must override "
|
||||
"the `as_value` method")
|
||||
if not hasattr(self.as_value, "_ValueCastable__memoized"):
|
||||
if not hasattr(cls.as_value, "_ValueCastable__memoized"):
|
||||
raise TypeError(f"Class '{cls.__name__}' deriving from `ValueCastable` must decorate "
|
||||
"the `as_value` method with the `ValueCastable.lowermethod` decorator")
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def lowermethod(func):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue