Skip to content

Commit 909b828

Browse files
committed
gh-92041: Resolve frame modules from globals
1 parent 09b6317 commit 909b828

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

Lib/inspect.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,14 @@ def getmodule(object, _filename=None):
930930
"""Return the module an object was defined in, or None if not found."""
931931
if ismodule(object):
932932
return object
933+
if istraceback(object):
934+
object = object.tb_frame
935+
if isframe(object):
936+
object_globals = object.f_globals
937+
module = sys.modules.get(object_globals.get('__name__'))
938+
if module is not None and module.__dict__ is object_globals:
939+
return module
940+
return None
933941
if hasattr(object, '__module__'):
934942
return sys.modules.get(object.__module__)
935943

Lib/test/test_inspect/test_inspect.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,22 @@ def test_getmodule(self):
831831
self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
832832
# Check filename override
833833
self.assertEqual(inspect.getmodule(None, modfile), mod)
834+
# Check frame and traceback objects
835+
self.assertIs(inspect.getmodule(inspect.currentframe()),
836+
sys.modules[__name__])
837+
try:
838+
1 / 0
839+
except ZeroDivisionError as error:
840+
self.assertIs(inspect.getmodule(error.__traceback__),
841+
sys.modules[__name__])
842+
843+
def test_getmodule_unregistered_exec_frame(self):
844+
namespace = {"inspect": inspect, "__name__": "not_registered"}
845+
exec(compile("frame = inspect.currentframe()", modfile, "exec"),
846+
namespace)
847+
# The frame globals are authoritative, even though the code filename
848+
# happens to match an imported module.
849+
self.assertIsNone(inspect.getmodule(namespace["frame"]))
834850

835851
def test_getmodule_file_not_found(self):
836852
# See bpo-45406
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve :func:`inspect.getmodule` performance for frame and traceback objects by resolving their module directly from the frame globals.

0 commit comments

Comments
 (0)