hdl._ast: deprecate ValueCastable.lowermethod
.
This commit is contained in:
parent
e2fd819742
commit
0da439cce1
|
@ -1262,9 +1262,6 @@ class ValueCastable:
|
||||||
if cls.shape is ValueCastable.shape:
|
if cls.shape is ValueCastable.shape:
|
||||||
raise TypeError(f"Class '{cls.__name__}' deriving from 'ValueCastable' must override "
|
raise TypeError(f"Class '{cls.__name__}' deriving from 'ValueCastable' must override "
|
||||||
"the 'shape' method")
|
"the 'shape' method")
|
||||||
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")
|
|
||||||
|
|
||||||
# The signatures and definitions of these methods are weird because they are present here for
|
# The signatures and definitions of these methods are weird because they are present here for
|
||||||
# documentation (and error checking above) purpose only and should not affect control flow.
|
# documentation (and error checking above) purpose only and should not affect control flow.
|
||||||
|
@ -1333,17 +1330,10 @@ class ValueCastable:
|
||||||
"""
|
"""
|
||||||
return super().shape(*args, **kwargs) # :nocov:
|
return super().shape(*args, **kwargs) # :nocov:
|
||||||
|
|
||||||
|
# TODO(amaranth-0.6): remove
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@deprecated("`ValueCastable.lowermethod` is no longer required and will be removed in Amaranth 0.6")
|
||||||
def lowermethod(func):
|
def lowermethod(func):
|
||||||
"""Decorator to memoize lowering methods.
|
|
||||||
|
|
||||||
Ensures the decorated method is called only once, with subsequent method calls returning
|
|
||||||
the object returned by the first first method call.
|
|
||||||
|
|
||||||
This decorator is required to decorate the :pc:`as_value` method of :pc:`ValueCastable`
|
|
||||||
subclasses. This is to ensure that Amaranth's view of representation of all values stays
|
|
||||||
internally consistent.
|
|
||||||
"""
|
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper_memoized(self, *args, **kwargs):
|
def wrapper_memoized(self, *args, **kwargs):
|
||||||
# Use `in self.__dict__` instead of `hasattr` to avoid interfering with custom
|
# Use `in self.__dict__` instead of `hasattr` to avoid interfering with custom
|
||||||
|
|
|
@ -178,7 +178,6 @@ class Record(ValueCastable):
|
||||||
raise AttributeError("{} does not have a field '{}'. Did you mean one of: {}?"
|
raise AttributeError("{} does not have a field '{}'. Did you mean one of: {}?"
|
||||||
.format(reference, item, ", ".join(self.fields))) from None
|
.format(reference, item, ", ".join(self.fields))) from None
|
||||||
|
|
||||||
@ValueCastable.lowermethod
|
|
||||||
def as_value(self):
|
def as_value(self):
|
||||||
return Cat(self.fields.values())
|
return Cat(self.fields.values())
|
||||||
|
|
||||||
|
|
|
@ -638,7 +638,6 @@ class View(ValueCastable):
|
||||||
"""
|
"""
|
||||||
return self.__orig_layout
|
return self.__orig_layout
|
||||||
|
|
||||||
@ValueCastable.lowermethod
|
|
||||||
def as_value(self):
|
def as_value(self):
|
||||||
"""Get underlying value.
|
"""Get underlying value.
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,6 @@ class EnumView(ValueCastable):
|
||||||
"""Returns the underlying enum type."""
|
"""Returns the underlying enum type."""
|
||||||
return self.enum
|
return self.enum
|
||||||
|
|
||||||
@ValueCastable.lowermethod
|
|
||||||
def as_value(self):
|
def as_value(self):
|
||||||
"""Returns the underlying value."""
|
"""Returns the underlying value."""
|
||||||
return self.target
|
return self.target
|
||||||
|
|
|
@ -1040,7 +1040,6 @@ class ArrayTestCase(FHDLTestCase):
|
||||||
|
|
||||||
def test_index_value_castable(self):
|
def test_index_value_castable(self):
|
||||||
class MyValue(ValueCastable):
|
class MyValue(ValueCastable):
|
||||||
@ValueCastable.lowermethod
|
|
||||||
def as_value(self):
|
def as_value(self):
|
||||||
return Signal()
|
return Signal()
|
||||||
|
|
||||||
|
@ -1328,7 +1327,6 @@ class MockValueCastable(ValueCastable):
|
||||||
def shape(self):
|
def shape(self):
|
||||||
return Value.cast(self.dest).shape()
|
return Value.cast(self.dest).shape()
|
||||||
|
|
||||||
@ValueCastable.lowermethod
|
|
||||||
def as_value(self):
|
def as_value(self):
|
||||||
return self.dest
|
return self.dest
|
||||||
|
|
||||||
|
@ -1340,9 +1338,10 @@ class MockValueCastableChanges(ValueCastable):
|
||||||
def shape(self):
|
def shape(self):
|
||||||
return unsigned(self.width)
|
return unsigned(self.width)
|
||||||
|
|
||||||
@ValueCastable.lowermethod
|
with _ignore_deprecated():
|
||||||
def as_value(self):
|
@ValueCastable.lowermethod
|
||||||
return Signal(self.width)
|
def as_value(self):
|
||||||
|
return Signal(self.width)
|
||||||
|
|
||||||
|
|
||||||
class MockValueCastableCustomGetattr(ValueCastable):
|
class MockValueCastableCustomGetattr(ValueCastable):
|
||||||
|
@ -1352,29 +1351,16 @@ class MockValueCastableCustomGetattr(ValueCastable):
|
||||||
def shape(self):
|
def shape(self):
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
@ValueCastable.lowermethod
|
with _ignore_deprecated():
|
||||||
def as_value(self):
|
@ValueCastable.lowermethod
|
||||||
return Const(0)
|
def as_value(self):
|
||||||
|
return Const(0)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
|
|
||||||
class ValueCastableTestCase(FHDLTestCase):
|
class ValueCastableTestCase(FHDLTestCase):
|
||||||
def test_not_decorated(self):
|
|
||||||
with self.assertRaisesRegex(TypeError,
|
|
||||||
r"^Class 'MockValueCastableNotDecorated' deriving from 'ValueCastable' must "
|
|
||||||
r"decorate the 'as_value' method with the 'ValueCastable.lowermethod' decorator$"):
|
|
||||||
class MockValueCastableNotDecorated(ValueCastable):
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def shape(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def as_value(self):
|
|
||||||
return Signal()
|
|
||||||
|
|
||||||
def test_no_override(self):
|
def test_no_override(self):
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r"^Class 'MockValueCastableNoOverrideAsValue' deriving from 'ValueCastable' must "
|
r"^Class 'MockValueCastableNoOverrideAsValue' deriving from 'ValueCastable' must "
|
||||||
|
|
|
@ -4,7 +4,6 @@ import unittest
|
||||||
from types import SimpleNamespace as NS
|
from types import SimpleNamespace as NS
|
||||||
|
|
||||||
from amaranth import *
|
from amaranth import *
|
||||||
from amaranth.hdl._ast import ValueCastable
|
|
||||||
from amaranth.lib import data, enum
|
from amaranth.lib import data, enum
|
||||||
from amaranth.lib.wiring import Flow, In, Out, Member
|
from amaranth.lib.wiring import Flow, In, Out, Member
|
||||||
from amaranth.lib.wiring import SignatureError, SignatureMembers, FlippedSignatureMembers
|
from amaranth.lib.wiring import SignatureError, SignatureMembers, FlippedSignatureMembers
|
||||||
|
|
|
@ -728,7 +728,6 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
|
||||||
|
|
||||||
def test_value_castable(self):
|
def test_value_castable(self):
|
||||||
class MyValue(ValueCastable):
|
class MyValue(ValueCastable):
|
||||||
@ValueCastable.lowermethod
|
|
||||||
def as_value(self):
|
def as_value(self):
|
||||||
return Signal()
|
return Signal()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue