Fix SF#1516184 and add a test to prevent regression.
diff --git a/Lib/inspect.py b/Lib/inspect.py
index bf7f006..311fe7e 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -355,40 +355,37 @@
             return None
     if os.path.exists(filename):
         return filename
-    # Ugly but necessary - '<stdin>' and '<string>' mean that getmodule()
-    # would infinitely recurse, because they're not real files nor loadable
-    # 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__'):
+    # only return a non-existent filename if the module has a PEP 302 loader
+    if hasattr(getmodule(object, filename), '__loader__'):
         return filename
 
-def getabsfile(object):
+def getabsfile(object, _filename=None):
     """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
     normalizes the result as much as possible."""
     return os.path.normcase(
-        os.path.abspath(getsourcefile(object) or getfile(object)))
+        os.path.abspath(_filename or getsourcefile(object) or getfile(object)))
 
 modulesbyfile = {}
 
-def getmodule(object):
+def getmodule(object, _filename=None):
     """Return the module an object was defined in, or None if not found."""
     if ismodule(object):
         return object
     if hasattr(object, '__module__'):
         return sys.modules.get(object.__module__)
     try:
-        file = getabsfile(object)
+        file = getabsfile(object, _filename)
     except TypeError:
         return None
     if file in modulesbyfile:
         return sys.modules.get(modulesbyfile[file])
     for module in sys.modules.values():
         if ismodule(module) and hasattr(module, '__file__'):
-            modulesbyfile[
-                os.path.realpath(
-                        getabsfile(module))] = module.__name__
+            f = getabsfile(module)
+            modulesbyfile[f] = modulesbyfile[
+                os.path.realpath(f)] = module.__name__
     if file in modulesbyfile:
         return sys.modules.get(modulesbyfile[file])
     main = sys.modules['__main__']