mirror of https://github.com/python/cpython
Fix SF#1516184 and add a test to prevent regression.
This commit is contained in:
parent
b9cb84fe96
commit
5d86bdb3ae
|
@ -355,40 +355,37 @@ def getsourcefile(object):
|
||||||
return None
|
return None
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
return filename
|
return filename
|
||||||
# Ugly but necessary - '<stdin>' and '<string>' mean that getmodule()
|
# only return a non-existent filename if the module has a PEP 302 loader
|
||||||
# would infinitely recurse, because they're not real files nor loadable
|
if hasattr(getmodule(object, filename), '__loader__'):
|
||||||
# Note that this means that writing a PEP 302 loader that uses '<'
|
|
||||||
# at the start of a filename is now not a good idea. :(
|
|
||||||
if filename[:1]!='<' and hasattr(getmodule(object), '__loader__'):
|
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def getabsfile(object):
|
def getabsfile(object, _filename=None):
|
||||||
"""Return an absolute path to the source or compiled file for an object.
|
"""Return an absolute path to the source or compiled file for an object.
|
||||||
|
|
||||||
The idea is for each object to have a unique origin, so this routine
|
The idea is for each object to have a unique origin, so this routine
|
||||||
normalizes the result as much as possible."""
|
normalizes the result as much as possible."""
|
||||||
return os.path.normcase(
|
return os.path.normcase(
|
||||||
os.path.abspath(getsourcefile(object) or getfile(object)))
|
os.path.abspath(_filename or getsourcefile(object) or getfile(object)))
|
||||||
|
|
||||||
modulesbyfile = {}
|
modulesbyfile = {}
|
||||||
|
|
||||||
def getmodule(object):
|
def getmodule(object, _filename=None):
|
||||||
"""Return the module an object was defined in, or None if not found."""
|
"""Return the module an object was defined in, or None if not found."""
|
||||||
if ismodule(object):
|
if ismodule(object):
|
||||||
return object
|
return object
|
||||||
if hasattr(object, '__module__'):
|
if hasattr(object, '__module__'):
|
||||||
return sys.modules.get(object.__module__)
|
return sys.modules.get(object.__module__)
|
||||||
try:
|
try:
|
||||||
file = getabsfile(object)
|
file = getabsfile(object, _filename)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return None
|
return None
|
||||||
if file in modulesbyfile:
|
if file in modulesbyfile:
|
||||||
return sys.modules.get(modulesbyfile[file])
|
return sys.modules.get(modulesbyfile[file])
|
||||||
for module in sys.modules.values():
|
for module in sys.modules.values():
|
||||||
if ismodule(module) and hasattr(module, '__file__'):
|
if ismodule(module) and hasattr(module, '__file__'):
|
||||||
modulesbyfile[
|
f = getabsfile(module)
|
||||||
os.path.realpath(
|
modulesbyfile[f] = modulesbyfile[
|
||||||
getabsfile(module))] = module.__name__
|
os.path.realpath(f)] = module.__name__
|
||||||
if file in modulesbyfile:
|
if file in modulesbyfile:
|
||||||
return sys.modules.get(modulesbyfile[file])
|
return sys.modules.get(modulesbyfile[file])
|
||||||
main = sys.modules['__main__']
|
main = sys.modules['__main__']
|
||||||
|
|
|
@ -178,6 +178,16 @@ class TestRetrievingSourceCode(GetSourceBase):
|
||||||
def test_getfile(self):
|
def test_getfile(self):
|
||||||
self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
|
self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
|
||||||
|
|
||||||
|
def test_getmodule_recursion(self):
|
||||||
|
from new import module
|
||||||
|
name = '__inspect_dummy'
|
||||||
|
m = sys.modules[name] = module(name)
|
||||||
|
m.__file__ = "<string>" # hopefully not a real filename...
|
||||||
|
m.__loader__ = "dummy" # pretend the filename is understood by a loader
|
||||||
|
exec "def x(): pass" in m.__dict__
|
||||||
|
self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
|
||||||
|
del sys.modules[name]
|
||||||
|
|
||||||
class TestDecorators(GetSourceBase):
|
class TestDecorators(GetSourceBase):
|
||||||
fodderFile = mod2
|
fodderFile = mod2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue