hdl.dsl: don't allow inheriting from Module.
authorwhitequark <whitequark@whitequark.org>
Sat, 1 Feb 2020 02:15:45 +0000 (02:15 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 1 Feb 2020 02:15:45 +0000 (02:15 +0000)
`Module` is an object with a lot of complex and sometimes fragile
behavior that overrides Python attribute accessors and so on.
To prevent user designs from breaking when it is changed, it is not
supposed to be inherited from (unlike in Migen), but rather returned
from the elaborate() method. This commit makes sure it will not be
inherited from by accident (most likely by users familiar with
Migen).

Fixes #286.

nmigen/hdl/dsl.py
nmigen/test/test_hdl_dsl.py

index 986ecc0c4efe34a8b836eba2bac10334d8d02aa8..247e07ef9bb0bf00118167704e6a61259f819809 100644 (file)
@@ -148,6 +148,11 @@ class FSM:
 
 
 class Module(_ModuleBuilderRoot, Elaboratable):
+    @classmethod
+    def __init_subclass__(cls):
+        raise SyntaxError("Instead of inheriting from `Module`, inherit from `Elaboratable` "
+                          "and return a `Module` from the `elaborate(self, platform)` method")
+
     def __init__(self):
         _ModuleBuilderRoot.__init__(self, self, depth=0)
         self.submodules    = _ModuleBuilderSubmodules(self)
index 1ef32fa3e6377e60625f6ebfd95a330d9c84ebc6..7573941d166acb5a41c99d4e3737546655353364 100644 (file)
@@ -19,6 +19,13 @@ class DSLTestCase(FHDLTestCase):
         self.c3 = Signal()
         self.w1 = Signal(4)
 
+    def test_cant_inherit(self):
+        with self.assertRaises(SyntaxError,
+                msg="Instead of inheriting from `Module`, inherit from `Elaboratable` and "
+                    "return a `Module` from the `elaborate(self, platform)` method"):
+            class ORGate(Module):
+                pass
+
     def test_d_comb(self):
         m = Module()
         m.d.comb += self.c1.eq(1)