Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(23409)

Delta Between Two Patch Sets: Lib/runpy.py

Issue 14285: Traceback wrong on ImportError while executing a package
Left Patch Set: Created 3 years, 9 months ago
Right Patch Set: Created 3 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Doc/using/cmdline.rst ('k') | Lib/test/test_cmd_line_script.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """runpy.py - locating and running Python code using the module namespace 1 """runpy.py - locating and running Python code using the module namespace
2 2
3 Provides support for locating and running Python scripts using the Python 3 Provides support for locating and running Python scripts using the Python
4 module namespace instead of the native filesystem. 4 module namespace instead of the native filesystem.
5 5
6 This allows Python code to play nicely with non-filesystem based PEP 302 6 This allows Python code to play nicely with non-filesystem based PEP 302
7 importers when locating support scripts as well as when importing modules. 7 importers when locating support scripts as well as when importing modules.
8 """ 8 """
9 # Written by Nick Coghlan <ncoghlan at gmail.com> 9 # Written by Nick Coghlan <ncoghlan at gmail.com>
10 # to implement PEP 338 (Executing Modules as Scripts) 10 # to implement PEP 338 (Executing Modules as Scripts)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): 93 with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname):
94 mod_globals = temp_module.module.__dict__ 94 mod_globals = temp_module.module.__dict__
95 _run_code(code, mod_globals, init_globals, 95 _run_code(code, mod_globals, init_globals,
96 mod_name, mod_spec, pkg_name, script_name) 96 mod_name, mod_spec, pkg_name, script_name)
97 # Copy the globals of the temporary module, as they 97 # Copy the globals of the temporary module, as they
98 # may be cleared when the temporary module goes away 98 # may be cleared when the temporary module goes away
99 return mod_globals.copy() 99 return mod_globals.copy()
100 100
101 # Helper to get the loader, code and filename for a module 101 # Helper to get the loader, code and filename for a module
102 def _get_module_details(mod_name, error=ImportError): 102 def _get_module_details(mod_name, error=ImportError):
103 # Import each ancestor package to avoid catching initialization errors 103 if mod_name.startswith("."):
104 dot = 0 104 raise error("Relative module names not supported")
105 while True: 105 pkg_name, _, _ = mod_name.rpartition(".")
106 dot = mod_name.find(".", dot) 106 if pkg_name:
107 if dot < 0: 107 # Try importing the parent to avoid catching initialization errors
108 break 108 try:
109 package = mod_name[:dot] 109 __import__(pkg_name)
110 try: 110 except ImportError as err:
111 if importlib.util.find_spec(package) is None: 111 # If the parent or higher ancestor package is missing, this is an
112 raise ImportError("No module named {!r}".format(package)) 112 # error that we may want to catch. But do not allow other errors
113 except (ImportError, AttributeError, TypeError, ValueError) as ex: 113 # to be caught.
114 msg = "Error while finding spec for {!r} ({}: {})" 114 if err.name is None or (err.name != pkg_name and
115 raise error(msg.format(mod_name, type(ex), ex)) from ex 115 not pkg_name.startswith(err.name + ".")):
116 __import__(package) 116 raise
117 dot += 1 117 raise error(format(err))
118 118
119 try: 119 try:
120 spec = importlib.util.find_spec(mod_name) 120 spec = importlib.util.find_spec(mod_name)
121 except (ImportError, AttributeError, TypeError, ValueError) as ex: 121 except (ImportError, AttributeError, TypeError, ValueError) as ex:
122 # This hack fixes an impedance mismatch between pkgutil and 122 # This hack fixes an impedance mismatch between pkgutil and
123 # importlib, where the latter raises other errors for cases where 123 # importlib, where the latter raises other errors for cases where
124 # pkgutil previously raised ImportError 124 # pkgutil previously raised ImportError
125 msg = "Error while finding spec for {!r} ({}: {})" 125 msg = "Error while finding spec for {!r} ({}: {})"
126 raise error(msg.format(mod_name, type(ex), ex)) from ex 126 raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex
127 if spec is None: 127 if spec is None:
128 raise error("No module named %s" % mod_name) 128 raise error("No module named %s" % mod_name)
129 if spec.submodule_search_locations is not None: 129 if spec.submodule_search_locations is not None:
130 if mod_name == "__main__" or mod_name.endswith(".__main__"): 130 if mod_name == "__main__" or mod_name.endswith(".__main__"):
131 raise error("Cannot use package as __main__ module") 131 raise error("Cannot use package as __main__ module")
132 try: 132 try:
133 pkg_main_name = mod_name + ".__main__" 133 pkg_main_name = mod_name + ".__main__"
134 return _get_module_details(pkg_main_name, error) 134 return _get_module_details(pkg_main_name, error)
135 except error as e: 135 except error as e:
136 raise error(("%s; %r is a package and cannot " + 136 raise error(("%s; %r is a package and cannot " +
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 pass 275 pass
276 276
277 277
278 if __name__ == "__main__": 278 if __name__ == "__main__":
279 # Run the module specified as the next command line argument 279 # Run the module specified as the next command line argument
280 if len(sys.argv) < 2: 280 if len(sys.argv) < 2:
281 print("No module specified for execution", file=sys.stderr) 281 print("No module specified for execution", file=sys.stderr)
282 else: 282 else:
283 del sys.argv[0] # Make the requested module sys.argv[0] 283 del sys.argv[0] # Make the requested module sys.argv[0]
284 _run_module_as_main(sys.argv[0]) 284 _run_module_as_main(sys.argv[0])
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+