lib.data: warn if a field is shadowed by an attribute of the view.
Fixes #796.
This commit is contained in:
parent
f96604f667
commit
2a45d0e9ad
|
@ -1,5 +1,6 @@
|
||||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||||
from collections.abc import Mapping, Sequence
|
from collections.abc import Mapping, Sequence
|
||||||
|
import warnings
|
||||||
|
|
||||||
from amaranth.hdl import *
|
from amaranth.hdl import *
|
||||||
from amaranth.hdl.ast import ShapeCastable, ValueCastable
|
from amaranth.hdl.ast import ShapeCastable, ValueCastable
|
||||||
|
@ -599,6 +600,12 @@ class View(ValueCastable):
|
||||||
raise ValueError("View target is {} bit(s) wide, which is not compatible with "
|
raise ValueError("View target is {} bit(s) wide, which is not compatible with "
|
||||||
"the {} bit(s) wide view layout"
|
"the {} bit(s) wide view layout"
|
||||||
.format(len(cast_target), cast_layout.size))
|
.format(len(cast_target), cast_layout.size))
|
||||||
|
for name, field in cast_layout:
|
||||||
|
if isinstance(name, str) and name[0] != "_" and hasattr(type(self), name):
|
||||||
|
warnings.warn("View layout includes a field {!r} that will be shadowed by "
|
||||||
|
"the view attribute '{}.{}.{}'"
|
||||||
|
.format(name, type(self).__module__, type(self).__qualname__, name),
|
||||||
|
SyntaxWarning, stacklevel=1)
|
||||||
self.__orig_layout = layout
|
self.__orig_layout = layout
|
||||||
self.__layout = cast_layout
|
self.__layout = cast_layout
|
||||||
self.__target = cast_target
|
self.__target = cast_target
|
||||||
|
|
|
@ -465,6 +465,22 @@ class ViewTestCase(FHDLTestCase):
|
||||||
r"^View layout must be a layout, not <.+?>$"):
|
r"^View layout must be a layout, not <.+?>$"):
|
||||||
View(object(), Signal(1))
|
View(object(), Signal(1))
|
||||||
|
|
||||||
|
def test_layout_conflict_with_attr(self):
|
||||||
|
with self.assertWarnsRegex(SyntaxWarning,
|
||||||
|
r"^View layout includes a field 'as_value' that will be shadowed by the view "
|
||||||
|
r"attribute 'amaranth\.lib\.data\.View\.as_value'$"):
|
||||||
|
View(StructLayout({"as_value": unsigned(1)}), Signal(1))
|
||||||
|
|
||||||
|
def test_layout_conflict_with_attr_derived(self):
|
||||||
|
class DerivedView(View):
|
||||||
|
def foo(self):
|
||||||
|
pass
|
||||||
|
with self.assertWarnsRegex(SyntaxWarning,
|
||||||
|
r"^View layout includes a field 'foo' that will be shadowed by the view "
|
||||||
|
r"attribute 'tests\.test_lib_data\.ViewTestCase\."
|
||||||
|
r"test_layout_conflict_with_attr_derived\.<locals>.DerivedView\.foo'$"):
|
||||||
|
DerivedView(StructLayout({"foo": unsigned(1)}), Signal(1))
|
||||||
|
|
||||||
def test_target_wrong_type(self):
|
def test_target_wrong_type(self):
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r"^View target must be a value-castable object, not <.+?>$"):
|
r"^View target must be a value-castable object, not <.+?>$"):
|
||||||
|
|
Loading…
Reference in a new issue