Skip to content

Commit

Permalink
[internal] Use f_globals instead of inspect.getmodule in `collect…
Browse files Browse the repository at this point in the history
…_rules` (pantsbuild#16357)

While working on pantsbuild#7369, I discovered that `inspect.getmodule` requires relevant modules to exist on the filesystem. PyOxidizer's importer imports from memory, so finding rules by `inspect.getmodule` will not work.

This change uses the `f_globals` attribute on the callling frame to get the global objects of the frame that invokes `collect_rules`. I believe this is functionally equivalent.

[ci skip-rust]
[ci skip-build-wheels]
  • Loading branch information
Christopher Neugebauer authored and cczona committed Sep 1, 2022
1 parent 623008c commit a1a4ff0
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/python/pants/engine/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,15 @@ def collect_rules(*namespaces: Union[ModuleType, Mapping[str, Any]]) -> Iterable
currentframe = inspect.currentframe()
assert isinstance(currentframe, FrameType)
caller_frame = currentframe.f_back
caller_module = inspect.getmodule(caller_frame)
assert isinstance(caller_module, ModuleType)
namespaces = (caller_module,)
assert isinstance(caller_frame, FrameType)

global_items = caller_frame.f_globals
namespaces = (global_items,)

def iter_rules():
for namespace in namespaces:
mapping = namespace.__dict__ if isinstance(namespace, ModuleType) else namespace
for name, item in mapping.items():
for item in mapping.values():
if not callable(item):
continue
rule = getattr(item, "rule", None)
Expand Down

0 comments on commit a1a4ff0

Please sign in to comment.