Skip to content

Commit ad6569e

Browse files
committed
Modify MustUse to iterate the stack frame and collate options from all frames.
Options in closer frames take precedence
1 parent 5689b6b commit ad6569e

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

amaranth/_unused.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ class MustUse:
1818
def __new__(cls, *args, src_loc_at=0, **kwargs):
1919
frame = sys._getframe(1 + src_loc_at)
2020
self = super().__new__(cls)
21-
self._MustUse__used = False
21+
22+
self._MustUse__used = False
23+
self._MustUse__frame = frame
2224
self._MustUse__context = dict(
2325
filename=frame.f_code.co_filename,
2426
lineno=frame.f_lineno,
@@ -31,7 +33,7 @@ def __del__(self):
3133
if getattr(self._MustUse__warning, "_MustUse__silence", False):
3234
return
3335
if hasattr(self, "_MustUse__used") and not self._MustUse__used:
34-
if get_linter_option(self._MustUse__context["filename"],
36+
if get_linter_option(self._MustUse__frame,
3537
self._MustUse__warning.__qualname__, bool, True):
3638
warnings.warn_explicit(
3739
f"{self!r} created but never used", self._MustUse__warning,

amaranth/_utils.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def decorator_like(*args, **kwargs):
7575
return decorator_like
7676

7777

78+
7879
def get_linter_options(filename):
7980
first_line = linecache.getline(filename, 1)
8081
if first_line:
@@ -84,8 +85,30 @@ def get_linter_options(filename):
8485
return dict()
8586

8687

87-
def get_linter_option(filename, name, type, default):
88-
options = get_linter_options(filename)
88+
def get_linter_option(frame, name, type, default):
89+
"""
90+
Get given linter option for a given stack frame. This iterates down the frames, collating options of the form:
91+
92+
.. code::
93+
# amaranth: {name}=value
94+
95+
The earliest option value in the stack takes precedence
96+
97+
Returns
98+
-------
99+
:class:`bool` or :class:`int`
100+
Option value
101+
"""
102+
103+
options = {}
104+
while frame:
105+
f_opts = get_linter_options(frame.f_code.co_filename)
106+
options = f_opts | options
107+
if frame.f_back is None:
108+
break
109+
else:
110+
frame = frame.f_back
111+
89112
if name not in options:
90113
return default
91114

0 commit comments

Comments
 (0)