From b5b2c9b8a4381a5b488aa647f78ad56abd1ad646 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 3 Aug 2019 12:30:39 +0000 Subject: [PATCH] hdl.ir: warn if .elaborate() returns None. Fixes #164. --- nmigen/hdl/ir.py | 9 +++++++++ nmigen/test/test_hdl_ir.py | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/nmigen/hdl/ir.py b/nmigen/hdl/ir.py index 773bb8e..bb2cd0e 100644 --- a/nmigen/hdl/ir.py +++ b/nmigen/hdl/ir.py @@ -52,10 +52,12 @@ class DriverConflict(UserWarning): class Fragment: @staticmethod def get(obj, platform): + code = None while True: if isinstance(obj, Fragment): return obj elif isinstance(obj, Elaboratable): + code = obj.elaborate.__code__ obj._Elaboratable__used = True obj = obj.elaborate(platform) elif hasattr(obj, "elaborate"): @@ -65,9 +67,16 @@ class Fragment: .format(type(obj)), category=RuntimeWarning, stacklevel=2) + code = obj.elaborate.__code__ obj = obj.elaborate(platform) else: raise AttributeError("Object '{!r}' cannot be elaborated".format(obj)) + if obj is None and code is not None: + warnings.warn_explicit( + message=".elaborate() returned None; missing return statement?", + category=UserWarning, + filename=code.co_filename, + lineno=code.co_firstlineno) def __init__(self): self.ports = SignalDict() diff --git a/nmigen/test/test_hdl_ir.py b/nmigen/test/test_hdl_ir.py index b30238f..2ad5eb2 100644 --- a/nmigen/test/test_hdl_ir.py +++ b/nmigen/test/test_hdl_ir.py @@ -7,12 +7,21 @@ from ..hdl.mem import * from .tools import * +class BadElaboratable(Elaboratable): + def elaborate(self, platform): + return + + class FragmentGetTestCase(FHDLTestCase): def test_get_wrong(self): with self.assertRaises(AttributeError, msg="Object 'None' cannot be elaborated"): Fragment.get(None, platform=None) + with self.assertRaises(AttributeError, + msg="Object 'None' cannot be elaborated"): + Fragment.get(BadElaboratable(), platform=None) + class FragmentGeneratedTestCase(FHDLTestCase): def test_find_subfragment(self): -- 2.30.2