hdl.ast: make it impossible to construct *Castable
instances.
Fixes #1072.
This commit is contained in:
parent
ace7aea375
commit
09854fa775
|
@ -191,6 +191,12 @@ class ShapeCastable:
|
||||||
The source code of the :mod:`amaranth.lib.data` module can be used as a reference for
|
The source code of the :mod:`amaranth.lib.data` module can be used as a reference for
|
||||||
implementing a fully featured shape-castable object.
|
implementing a fully featured shape-castable object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if type(self) is ShapeCastable:
|
||||||
|
raise TypeError("Can't instantiate abstract class ShapeCastable")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
if cls.as_shape is ShapeCastable.as_shape:
|
if cls.as_shape is ShapeCastable.as_shape:
|
||||||
raise TypeError(f"Class '{cls.__name__}' deriving from 'ShapeCastable' must override "
|
raise TypeError(f"Class '{cls.__name__}' deriving from 'ShapeCastable' must override "
|
||||||
|
@ -1616,6 +1622,12 @@ class ValueCastable:
|
||||||
from :class:`ValueCastable` is mutable, it is up to the user to ensure that it is not mutated
|
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`.
|
in a way that changes its representation after the first call to :meth:`as_value`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if type(self) is ValueCastable:
|
||||||
|
raise TypeError("Can't instantiate abstract class ValueCastable")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
if not hasattr(cls, "as_value"):
|
if not hasattr(cls, "as_value"):
|
||||||
raise TypeError(f"Class '{cls.__name__}' deriving from `ValueCastable` must override "
|
raise TypeError(f"Class '{cls.__name__}' deriving from `ValueCastable` must override "
|
||||||
|
|
|
@ -191,6 +191,11 @@ class ShapeCastableTestCase(FHDLTestCase):
|
||||||
sc = MockShapeCastable(MockShapeCastable(unsigned(1)))
|
sc = MockShapeCastable(MockShapeCastable(unsigned(1)))
|
||||||
self.assertEqual(Shape.cast(sc), unsigned(1))
|
self.assertEqual(Shape.cast(sc), unsigned(1))
|
||||||
|
|
||||||
|
def test_abstract(self):
|
||||||
|
with self.assertRaisesRegex(TypeError,
|
||||||
|
r"^Can't instantiate abstract class ShapeCastable$"):
|
||||||
|
ShapeCastable()
|
||||||
|
|
||||||
|
|
||||||
class ShapeLikeTestCase(FHDLTestCase):
|
class ShapeLikeTestCase(FHDLTestCase):
|
||||||
def test_construct(self):
|
def test_construct(self):
|
||||||
|
@ -1400,6 +1405,11 @@ class ValueCastableTestCase(FHDLTestCase):
|
||||||
vc = MockValueCastable(MockValueCastable(Signal()))
|
vc = MockValueCastable(MockValueCastable(Signal()))
|
||||||
self.assertIsInstance(Value.cast(vc), Signal)
|
self.assertIsInstance(Value.cast(vc), Signal)
|
||||||
|
|
||||||
|
def test_abstract(self):
|
||||||
|
with self.assertRaisesRegex(TypeError,
|
||||||
|
r"^Can't instantiate abstract class ValueCastable$"):
|
||||||
|
ValueCastable()
|
||||||
|
|
||||||
|
|
||||||
class ValueLikeTestCase(FHDLTestCase):
|
class ValueLikeTestCase(FHDLTestCase):
|
||||||
def test_construct(self):
|
def test_construct(self):
|
||||||
|
|
Loading…
Reference in a new issue