From: Nick Coghlan Date: Sat, 14 Jul 2012 14:07:43 +0000 (+1000) Subject: Merge fix for #15230 from 3.2 X-Git-Tag: v3.3.0b2~219 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2f54b98c8c40ab2190db59ae66d23f795b92daa2;p=python Merge fix for #15230 from 3.2 --- 2f54b98c8c40ab2190db59ae66d23f795b92daa2 diff --cc Lib/runpy.py index 71c175fe65,7cb4668a01..8ca325b0a3 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@@ -233,8 -243,9 +234,9 @@@ def run_path(path_name, init_globals=No """ if run_name is None: run_name = "" + pkg_name = run_name.rpartition(".")[0] importer = _get_importer(path_name) - if isinstance(importer, imp.NullImporter): + if isinstance(importer, (type(None), imp.NullImporter)): # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files code = _get_code_from_file(path_name) diff --cc Lib/test/test_runpy.py index de44df07ba,85eb76fa79..c39e281d93 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@@ -156,63 -217,84 +219,88 @@@ class RunModuleTestCase(unittest.TestCa try: os.rmdir(fullname) except OSError as ex: - if verbose: print(ex) # Persist with cleaning up + if verbose > 1: print(ex) # Persist with cleaning up try: os.rmdir(top) - if verbose: print(" Removed package tree") + if verbose > 1: print(" Removed package tree") except OSError as ex: - if verbose: print(ex) # Persist with cleaning up + if verbose > 1: print(ex) # Persist with cleaning up + + def _fix_ns_for_legacy_pyc(self, ns, alter_sys): + char_to_add = "c" if __debug__ else "o" + ns["__file__"] += char_to_add + if alter_sys: + ns["run_argv0"] += char_to_add + - def _check_module(self, depth): + def _check_module(self, depth, alter_sys=False): pkg_dir, mod_fname, mod_name = ( - self._make_pkg("x=1\n", depth)) + self._make_pkg(example_source, depth)) forget(mod_name) + expected_ns = example_namespace.copy() + expected_ns.update({ + "__name__": mod_name, + "__file__": mod_fname, + "__package__": mod_name.rpartition(".")[0], + }) + if alter_sys: + expected_ns.update({ + "run_argv0": mod_fname, + "run_name_in_sys_modules": True, + "module_in_sys_modules": True, + }) + def create_ns(init_globals): + return run_module(mod_name, init_globals, alter_sys=alter_sys) try: - if verbose: print("Running from source:", mod_name) - d1 = run_module(mod_name) # Read from source - self.assertIn("x", d1) - self.assertEqual(d1["x"], 1) - del d1 # Ensure __loader__ entry doesn't keep file open + if verbose > 1: print("Running from source:", mod_name) + self.check_code_execution(create_ns, expected_ns) + importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths - if verbose: print("Running from compiled:", mod_name) + importlib.invalidate_caches() - d2 = run_module(mod_name) # Read from bytecode - self.assertIn("x", d2) - self.assertEqual(d2["x"], 1) - del d2 # Ensure __loader__ entry doesn't keep file open + if verbose > 1: print("Running from compiled:", mod_name) + self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) + self.check_code_execution(create_ns, expected_ns) finally: self._del_pkg(pkg_dir, depth, mod_name) - if verbose: print("Module executed successfully") + if verbose > 1: print("Module executed successfully") - def _check_package(self, depth): + def _check_package(self, depth, alter_sys=False): pkg_dir, mod_fname, mod_name = ( - self._make_pkg("x=1\n", depth, "__main__")) - pkg_name, _, _ = mod_name.rpartition(".") + self._make_pkg(example_source, depth, "__main__")) + pkg_name = mod_name.rpartition(".")[0] forget(mod_name) + expected_ns = example_namespace.copy() + expected_ns.update({ + "__name__": mod_name, + "__file__": mod_fname, + "__package__": pkg_name, + }) + if alter_sys: + expected_ns.update({ + "run_argv0": mod_fname, + "run_name_in_sys_modules": True, + "module_in_sys_modules": True, + }) + def create_ns(init_globals): + return run_module(pkg_name, init_globals, alter_sys=alter_sys) try: - if verbose: print("Running from source:", pkg_name) - d1 = run_module(pkg_name) # Read from source - self.assertIn("x", d1) - self.assertTrue(d1["x"] == 1) - del d1 # Ensure __loader__ entry doesn't keep file open + if verbose > 1: print("Running from source:", pkg_name) + self.check_code_execution(create_ns, expected_ns) + importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case loader caches paths - if verbose: print("Running from compiled:", pkg_name) + if verbose > 1: print("Running from compiled:", pkg_name) + importlib.invalidate_caches() - d2 = run_module(pkg_name) # Read from bytecode - self.assertIn("x", d2) - self.assertTrue(d2["x"] == 1) - del d2 # Ensure __loader__ entry doesn't keep file open + self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) + self.check_code_execution(create_ns, expected_ns) finally: self._del_pkg(pkg_dir, depth, pkg_name) - if verbose: print("Package executed successfully") + if verbose > 1: print("Package executed successfully") def _add_relative_modules(self, base_dir, source, depth): if depth <= 1: @@@ -224,18 -306,20 +312,18 @@@ module_dir = os.path.join(module_dir, pkg_name) # Add sibling module sibling_fname = os.path.join(module_dir, "sibling.py") - sibling_file = open(sibling_fname, "w") - sibling_file.close() + create_empty_file(sibling_fname) - if verbose: print(" Added sibling module:", sibling_fname) + if verbose > 1: print(" Added sibling module:", sibling_fname) # Add nephew module uncle_dir = os.path.join(parent_dir, "uncle") self._add_pkg_dir(uncle_dir) - if verbose: print(" Added uncle package:", uncle_dir) + if verbose > 1: print(" Added uncle package:", uncle_dir) cousin_dir = os.path.join(uncle_dir, "cousin") self._add_pkg_dir(cousin_dir) - if verbose: print(" Added cousin package:", cousin_dir) + if verbose > 1: print(" Added cousin package:", cousin_dir) nephew_fname = os.path.join(cousin_dir, "nephew.py") - nephew_file = open(nephew_fname, "w") - nephew_file.close() + create_empty_file(nephew_fname) - if verbose: print(" Added nephew module:", nephew_fname) + if verbose > 1: print(" Added nephew module:", nephew_fname) def _check_relative_imports(self, depth, run_name=None): contents = r"""\ @@@ -260,11 -347,10 +352,11 @@@ from ..uncle.cousin import nephe os.remove(mod_fname) make_legacy_pyc(mod_fname) unload(mod_name) # In case the loader caches paths - if verbose: print("Running from compiled:", mod_name) + if verbose > 1: print("Running from compiled:", mod_name) + importlib.invalidate_caches() d2 = run_module(mod_name, run_name=run_name) # Read from bytecode - self.assertIn("__package__", d2) - self.assertTrue(d2["__package__"] == pkg_name) + self.assertEqual(d2["__name__"], expected_name) + self.assertEqual(d2["__package__"], pkg_name) self.assertIn("sibling", d2) self.assertIn("nephew", d2) del d2 # Ensure __loader__ entry doesn't keep file open diff --cc Misc/NEWS index 89b1147fcd,1b2f4f41eb..5bdf2df382 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -28,146 -16,6 +28,151 @@@ Core and Builtin - Issue #15033: Fix the exit status bug when modules invoked using -m swith, return the proper failure return value (1). Patch contributed by Jeff Knupp. +- Issue #15229: An OSError subclass whose __init__ doesn't call back + OSError.__init__ could produce incomplete instances, leading to crashes + when calling str() on them. + +Library +------- + ++- Issue #15230: runpy.run_path now correctly sets __package__ as described ++ in the documentation ++ +- Issue #15315: Support VS 2010 in distutils cygwincompiler. + +- Issue #15294: Fix a regression in pkgutil.extend_path()'s handling of + nested namespace packages. + +- Issue #15056: imp.cache_from_source() and source_from_cache() raise + NotImplementedError when sys.implementation.cache_tag is set to None. + +- Issue #15256: Grammatical mistake in exception raised by imp.find_module(). + +- Issue #5931: wsgiref environ variable SERVER_SOFTWARE will specify an + implementation specific term like Cpython, Jython instead of generic "Python" + +- Issue #13248: Remove obsolete argument "max_buffer_size" of BufferedWriter + and BufferedRWPair, from the io module. + +- Issue #13248: Remove obsolete argument "version" of argparse.ArgumentParser. + +- Issue #14814: implement more consistent ordering and sorting behaviour + for ipaddress objects + +- Issue #14814: ipaddress network objects correctly return NotImplemented + when compared to arbitrary objects instead of raising TypeError + +- Issue #14990: Correctly fail with SyntaxError on invalid encoding + declaration. + +- Issue #14814: ipaddress now provides more informative error messages when + constructing instances directly (changes permitted during beta due to + provisional API status) + +- Issue #15247: FileIO now raises an error when given a file descriptor + pointing to a directory. + +- Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open. + +- Issue #15166: Implement imp.get_tag() using sys.implementation.cache_tag. + +- Issue #15210: Catch KeyError when imprortlib.__init__ can't find + _frozen_importlib in sys.modules, not ImportError. + +- Issue #15030: importlib.abc.PyPycLoader now supports the new source size + header field in .pyc files. + +- Issue #5346: Preserve permissions of mbox, MMDF and Babyl mailbox + files on flush(). + +- Issue #10571: Fix the "--sign" option of distutils' upload command. + Patch by Jakub Wilk. + +- Issue #9559: If messages were only added, a new file is no longer + created and renamed over the old file when flush() is called on an + mbox, MMDF or Babyl mailbox. + +- Issue 10924: Fixed mksalt() to use a RNG that is suitable for cryptographic + purpose. + +C API +----- + +- Issues #15169, #14599: Strip out the C implementation of + imp.source_from_cache() used by PyImport_ExecCodeModuleWithPathnames() and + used the Python code instead. Leads to PyImport_ExecCodeModuleObject() to not + try to infer the source path from the bytecode path as + PyImport_ExecCodeModuleWithPathnames() does. + +Extension Modules +----------------- + +- Issue #15194: Update libffi to the 3.0.11 release. + +Tools/Demos +----------- + +- Issue #12605: The gdb hooks for debugging CPython (within Tools/gdb) have + been enhanced to show information on more C frames relevant to CPython within + the "py-bt" and "py-bt-full" commands: + * C frames that are waiting on the GIL + * C frames that are garbage-collecting + * C frames that are due to the invocation of a PyCFunction + +Documentation +------------- + +- Issue #15053: Copy Python 3.3 import lock change notice to all relevant + functions in imp instead of just at the top of the relevant section. + +- Issue #15288: Link to the term "loader" in notes in pkgutil about how things + won't work as expected in Python 3.3 and mark the requisite functions as + "changed" since they will no longer work with modules directly imported by + import itself. + +- Issue #13557: Clarify effect of giving two different namespaces to exec or + execfile(). + +Tests +----- + ++- Issue #15230: Adopted a more systematic approach in the runpy tests ++ +- Issue #15300: Ensure the temporary test working directories are in the same + parent folder when running tests in multiprocess mode from a Python build. + Patch by Chris Jerdonek. + +- Issue #15284: Skip {send,recv}msg tests in test_socket when IPv6 is not + enabled. Patch by Brian Brazil. + +- Issue #15277: Fix a resource leak in support.py when IPv6 is disabled. + Patch by Brian Brazil. + +Build +----- + +- Issue #14330: For cross builds, don't use host python, use host search paths + for host compiler. + +- Issue #15235: Allow Berkley DB versions up to 5.3 to build the dbm module. + +- Issue #15268: Search curses.h in /usr/include/ncursesw. + + +What's New in Python 3.3.0 Beta 1? +================================== + +*Release date: 27-Jun-2012* + +Core and Builtins +----------------- + +- Fix a (most likely) very rare memory leak when calling main() and not being + able to decode a command-line argument. + +- Issue #14815: Use Py_ssize_t instead of long for the object hash, to + preserve all 64 bits of hash on Win64. + - Issue #12268: File readline, readlines and read() or readall() methods no longer lose data when an underlying read system call is interrupted. IOError is no longer raised due to a read system call returning EINTR