_unused: extract must-use logic from hdl.ir.
authorwhitequark <whitequark@whitequark.org>
Sat, 1 Feb 2020 01:35:05 +0000 (01:35 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 1 Feb 2020 01:35:05 +0000 (01:35 +0000)
nmigen/_unused.py [new file with mode: 0644]
nmigen/compat/fhdl/module.py
nmigen/hdl/ir.py

diff --git a/nmigen/_unused.py b/nmigen/_unused.py
new file mode 100644 (file)
index 0000000..e0c67a7
--- /dev/null
@@ -0,0 +1,45 @@
+import sys
+import warnings
+
+from ._utils import get_linter_option
+
+
+__all__ = ["UnusedMustUse", "MustUse"]
+
+
+class UnusedMustUse(Warning):
+    pass
+
+
+class MustUse:
+    _MustUse__silence = False
+    _MustUse__warning = UnusedMustUse
+
+    def __new__(cls, *args, src_loc_at=0, **kwargs):
+        frame = sys._getframe(1 + src_loc_at)
+        self = super().__new__(cls)
+        self._MustUse__used    = False
+        self._MustUse__context = dict(
+            filename=frame.f_code.co_filename,
+            lineno=frame.f_lineno,
+            source=self)
+        return self
+
+    def __del__(self):
+        if self._MustUse__silence:
+            return
+        if hasattr(self, "_MustUse__used") and not self._MustUse__used:
+            if get_linter_option(self._MustUse__context["filename"],
+                                 self._MustUse__warning.__name__, bool, True):
+                warnings.warn_explicit(
+                    "{!r} created but never used".format(self), self._MustUse__warning,
+                    **self._MustUse__context)
+
+
+_old_excepthook = sys.excepthook
+def _silence_elaboratable(type, value, traceback):
+    # Don't show anything if the interpreter crashed; that'd just obscure the exception
+    # traceback instead of helping.
+    MustUse._MustUse__silence = True
+    _old_excepthook(type, value, traceback)
+sys.excepthook = _silence_elaboratable
index c403a5e9880bbc61dcc64843f43d77fd53e1e367..e5b7796b7de99b32bcbda7fc1df4ee597ab647ea 100644 (file)
@@ -95,7 +95,7 @@ class _CompatModuleClockDomains(_CompatModuleProxy):
 
 
 class CompatModule(ir.Elaboratable):
-    _Elaboratable__silence = True
+    _MustUse__silence = True
 
     # Actually returns another nMigen Elaboratable (nmigen.dsl.Module), not a Fragment.
     def get_fragment(self):
index 26dec85a4c13d86d646e5696829c47136ebdf9b4..5d4a1c57d9afda472721edd18a51fbe84968968e 100644 (file)
@@ -6,6 +6,7 @@ import traceback
 import sys
 
 from .._utils import *
+from .._unused import *
 from .ast import *
 from .cd import *
 
@@ -13,41 +14,12 @@ from .cd import *
 __all__ = ["UnusedElaboratable", "Elaboratable", "DriverConflict", "Fragment", "Instance"]
 
 
-class UnusedElaboratable(Warning):
+class UnusedElaboratable(UnusedMustUse):
     pass
 
 
-class Elaboratable(metaclass=ABCMeta):
-    _Elaboratable__silence = False
-
-    def __new__(cls, *args, src_loc_at=0, **kwargs):
-        frame = sys._getframe(1 + src_loc_at)
-        self = super().__new__(cls)
-        self._Elaboratable__used    = False
-        self._Elaboratable__context = dict(
-            filename=frame.f_code.co_filename,
-            lineno=frame.f_lineno,
-            source=self)
-        return self
-
-    def __del__(self):
-        if self._Elaboratable__silence:
-            return
-        if hasattr(self, "_Elaboratable__used") and not self._Elaboratable__used:
-            if get_linter_option(self._Elaboratable__context["filename"],
-                                 "UnusedElaboratable", bool, True):
-                warnings.warn_explicit(
-                    "{!r} created but never used".format(self), UnusedElaboratable,
-                    **self._Elaboratable__context)
-
-
-_old_excepthook = sys.excepthook
-def _silence_elaboratable(type, value, traceback):
-    # Don't show anything if the interpreter crashed; that'd just obscure the exception
-    # traceback instead of helping.
-    Elaboratable._Elaboratable__silence = True
-    _old_excepthook(type, value, traceback)
-sys.excepthook = _silence_elaboratable
+class Elaboratable(MustUse, metaclass=ABCMeta):
+    _MustUse__warning = UnusedElaboratable
 
 
 class DriverConflict(UserWarning):
@@ -63,7 +35,7 @@ class Fragment:
                 return obj
             elif isinstance(obj, Elaboratable):
                 code = obj.elaborate.__code__
-                obj._Elaboratable__used = True
+                obj._MustUse__used = True
                 obj = obj.elaborate(platform)
             elif hasattr(obj, "elaborate"):
                 warnings.warn(