hdl.ir: make UnusedElaboratable a real warning.
authorwhitequark <whitequark@whitequark.org>
Wed, 10 Jul 2019 12:46:46 +0000 (12:46 +0000)
committerwhitequark <whitequark@whitequark.org>
Wed, 10 Jul 2019 12:46:54 +0000 (12:46 +0000)
Before this commit, it was a print statement, and therefore, command
interpreter options like -Wignore did not affect it. There is no API
to access the warning filter list, so it was turned into a real
warning; and further, since Python 3.6, tracemalloc can be used
as a standard method to display traceback to allocation site instead
of the ad-hoc traceback logic that was used in Elaboratable before.

nmigen/hdl/ir.py

index 2e9fbe1d5a78fc185ffaa239e125401ca7a5362f..773bb8eac13bef48c272028f948d7d8aeca8273a 100644 (file)
@@ -10,26 +10,30 @@ from .ast import *
 from .cd import *
 
 
-__all__ = ["Elaboratable", "DriverConflict", "Fragment", "Instance"]
+__all__ = ["UnusedElaboratable", "Elaboratable", "DriverConflict", "Fragment", "Instance"]
+
+
+class UnusedElaboratable(Warning):
+    pass
 
 
 class Elaboratable(metaclass=ABCMeta):
     _Elaboratable__silence = False
 
-    def __new__(cls, *args, **kwargs):
+    def __new__(cls, *args, src_loc_at=0, **kwargs):
         self = super().__new__(cls)
-        self._Elaboratable__traceback = traceback.extract_stack()[:-1]
-        self._Elaboratable__used      = False
+        self._Elaboratable__src_loc = traceback.extract_stack(limit=2 + src_loc_at)[0]
+        self._Elaboratable__used    = False
         return self
 
     def __del__(self):
         if self._Elaboratable__silence:
             return
         if hasattr(self, "_Elaboratable__used") and not self._Elaboratable__used:
-            print("Warning: elaboratable created but never used\n",
-                  "Constructor traceback (most recent call last):\n",
-                  *traceback.format_list(self._Elaboratable__traceback),
-                  file=sys.stderr, sep="")
+            warnings.warn_explicit("{!r} created but never used".format(self), UnusedElaboratable,
+                                   filename=self._Elaboratable__src_loc.filename,
+                                   lineno=self._Elaboratable__src_loc.lineno,
+                                   source=self)
 
 
 _old_excepthook = sys.excepthook