Commit 9a5af128 authored by Barry Warsaw's avatar Barry Warsaw

merge

parents dadebab4 233f6845
...@@ -74,5 +74,7 @@ check the ``long_description`` from the command line:: ...@@ -74,5 +74,7 @@ check the ``long_description`` from the command line::
:mod:`docutils` will display a warning if there's something wrong with your :mod:`docutils` will display a warning if there's something wrong with your
syntax. Because PyPI applies additional checks (e.g. by passing ``--no-raw`` syntax. Because PyPI applies additional checks (e.g. by passing ``--no-raw``
to ``rst2html.py`` in the command above), running the command above without to ``rst2html.py`` in the command above), being able to run the command above
warnings is not sufficient for PyPI to convert the content successfully. without warnings does not guarantee that PyPI will convert the content
successfully.
...@@ -19,7 +19,7 @@ An Introduction to the ipaddress module ...@@ -19,7 +19,7 @@ An Introduction to the ipaddress module
Creating Address/Network/Interface objects Creating Address/Network/Interface objects
========================================== ==========================================
Since :mod:`ipaddress` is a module for inspecting and manipulating IP address, Since :mod:`ipaddress` is a module for inspecting and manipulating IP addresses,
the first thing you'll want to do is create some objects. You can use the first thing you'll want to do is create some objects. You can use
:mod:`ipaddress` to create objects from strings and integers. :mod:`ipaddress` to create objects from strings and integers.
...@@ -183,10 +183,10 @@ Finding out how many individual addresses are in a network:: ...@@ -183,10 +183,10 @@ Finding out how many individual addresses are in a network::
>>> net6.numhosts >>> net6.numhosts
4294967296 4294967296
Iterating through the 'usable' addresses on a network:: Iterating through the "usable" addresses on a network::
>>> net4 = ipaddress.ip_network('192.0.2.0/24') >>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> for x in net4.iterhosts(): >>> for x in net4.hosts():
print(x) print(x)
192.0.2.1 192.0.2.1
192.0.2.2 192.0.2.2
...@@ -294,7 +294,7 @@ Getting more detail when instance creation fails ...@@ -294,7 +294,7 @@ Getting more detail when instance creation fails
When creating address/network/interface objects using the version-agnostic When creating address/network/interface objects using the version-agnostic
factory functions, any errors will be reported as :exc:`ValueError` with factory functions, any errors will be reported as :exc:`ValueError` with
a generic error message that simply says the passed in value was not a generic error message that simply says the passed in value was not
recognised as an object of that type. The lack of a specific error is recognized as an object of that type. The lack of a specific error is
because it's necessary to know whether the value is *supposed* to be IPv4 because it's necessary to know whether the value is *supposed* to be IPv4
or IPv6 in order to provide more detail on why it has been rejected. or IPv6 in order to provide more detail on why it has been rejected.
......
...@@ -23,7 +23,7 @@ tracebacks: ...@@ -23,7 +23,7 @@ tracebacks:
* Only ASCII is supported. The ``backslashreplace`` error handler is used on * Only ASCII is supported. The ``backslashreplace`` error handler is used on
encoding. encoding.
* Each string is limited to 100 characters. * Each string is limited to 500 characters.
* Only the filename, the function name and the line number are * Only the filename, the function name and the line number are
displayed. (no source code) displayed. (no source code)
* It is limited to 100 frames and 100 threads. * It is limited to 100 frames and 100 threads.
......
...@@ -1506,6 +1506,9 @@ are always available. They are listed here in alphabetical order. ...@@ -1506,6 +1506,9 @@ are always available. They are listed here in alphabetical order.
If you simply want to import a module (potentially within a package) by name, If you simply want to import a module (potentially within a package) by name,
use :func:`importlib.import_module`. use :func:`importlib.import_module`.
.. versionchanged:: 3.3
Negative values for *level* are no longer supported.
.. rubric:: Footnotes .. rubric:: Footnotes
......
This diff is collapsed.
...@@ -248,8 +248,8 @@ class PyShellEditorWindow(EditorWindow): ...@@ -248,8 +248,8 @@ class PyShellEditorWindow(EditorWindow):
def ranges_to_linenumbers(self, ranges): def ranges_to_linenumbers(self, ranges):
lines = [] lines = []
for index in range(0, len(ranges), 2): for index in range(0, len(ranges), 2):
lineno = int(float(ranges[index])) lineno = int(float(ranges[index].string))
end = int(float(ranges[index+1])) end = int(float(ranges[index+1].string))
while lineno < end: while lineno < end:
lines.append(lineno) lines.append(lineno)
lineno += 1 lineno += 1
......
...@@ -297,8 +297,20 @@ def _lock_unlock_module(name): ...@@ -297,8 +297,20 @@ def _lock_unlock_module(name):
else: else:
lock.release() lock.release()
# Frame stripping magic ###############################################
# Finder/loader utility code ################################################## def _call_with_frames_removed(f, *args, **kwds):
"""remove_importlib_frames in import.c will always remove sequences
of importlib frames that end with a call to this function
Use it instead of a normal call in places where including the importlib
frames introduces unwanted noise into the traceback (e.g. when executing
module code)
"""
return f(*args, **kwds)
# Finder/loader utility code ###############################################
"""Magic word to reject .pyc files generated by other Python versions. """Magic word to reject .pyc files generated by other Python versions.
It should change for each incompatible change to the bytecode. It should change for each incompatible change to the bytecode.
...@@ -629,19 +641,12 @@ class BuiltinImporter: ...@@ -629,19 +641,12 @@ class BuiltinImporter:
"""Load a built-in module.""" """Load a built-in module."""
is_reload = fullname in sys.modules is_reload = fullname in sys.modules
try: try:
return cls._exec_module(fullname) return _call_with_frames_removed(_imp.init_builtin, fullname)
except: except:
if not is_reload and fullname in sys.modules: if not is_reload and fullname in sys.modules:
del sys.modules[fullname] del sys.modules[fullname]
raise raise
@classmethod
def _exec_module(cls, fullname):
"""Helper for load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
return _imp.init_builtin(fullname)
@classmethod @classmethod
@_requires_builtin @_requires_builtin
def get_code(cls, fullname): def get_code(cls, fullname):
...@@ -687,7 +692,7 @@ class FrozenImporter: ...@@ -687,7 +692,7 @@ class FrozenImporter:
"""Load a frozen module.""" """Load a frozen module."""
is_reload = fullname in sys.modules is_reload = fullname in sys.modules
try: try:
m = cls._exec_module(fullname) m = _call_with_frames_removed(_imp.init_frozen, fullname)
# Let our own module_repr() method produce a suitable repr. # Let our own module_repr() method produce a suitable repr.
del m.__file__ del m.__file__
return m return m
...@@ -714,13 +719,6 @@ class FrozenImporter: ...@@ -714,13 +719,6 @@ class FrozenImporter:
"""Return if the frozen module is a package.""" """Return if the frozen module is a package."""
return _imp.is_frozen_package(fullname) return _imp.is_frozen_package(fullname)
@classmethod
def _exec_module(cls, fullname):
"""Helper for load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
return _imp.init_frozen(fullname)
class WindowsRegistryImporter: class WindowsRegistryImporter:
...@@ -850,15 +848,9 @@ class _LoaderBasics: ...@@ -850,15 +848,9 @@ class _LoaderBasics:
else: else:
module.__package__ = module.__package__.rpartition('.')[0] module.__package__ = module.__package__.rpartition('.')[0]
module.__loader__ = self module.__loader__ = self
self._exec_module(code_object, module.__dict__) _call_with_frames_removed(exec, code_object, module.__dict__)
return module return module
def _exec_module(self, code_object, module_dict):
"""Helper for _load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
exec(code_object, module_dict)
class SourceLoader(_LoaderBasics): class SourceLoader(_LoaderBasics):
...@@ -956,8 +948,9 @@ class SourceLoader(_LoaderBasics): ...@@ -956,8 +948,9 @@ class SourceLoader(_LoaderBasics):
raise ImportError(msg.format(bytecode_path), raise ImportError(msg.format(bytecode_path),
name=fullname, path=bytecode_path) name=fullname, path=bytecode_path)
source_bytes = self.get_data(source_path) source_bytes = self.get_data(source_path)
code_object = compile(source_bytes, source_path, 'exec', code_object = _call_with_frames_removed(compile,
dont_inherit=True) source_bytes, source_path, 'exec',
dont_inherit=True)
_verbose_message('code object from {}', source_path) _verbose_message('code object from {}', source_path)
if (not sys.dont_write_bytecode and bytecode_path is not None and if (not sys.dont_write_bytecode and bytecode_path is not None and
source_mtime is not None): source_mtime is not None):
...@@ -1093,7 +1086,8 @@ class ExtensionFileLoader: ...@@ -1093,7 +1086,8 @@ class ExtensionFileLoader:
"""Load an extension module.""" """Load an extension module."""
is_reload = fullname in sys.modules is_reload = fullname in sys.modules
try: try:
module = self._exec_module(fullname, self.path) module = _call_with_frames_removed(_imp.load_dynamic,
fullname, self.path)
_verbose_message('extension module loaded from {!r}', self.path) _verbose_message('extension module loaded from {!r}', self.path)
return module return module
except: except:
...@@ -1113,12 +1107,6 @@ class ExtensionFileLoader: ...@@ -1113,12 +1107,6 @@ class ExtensionFileLoader:
"""Return None as extension modules have no source code.""" """Return None as extension modules have no source code."""
return None return None
def _exec_module(self, fullname, path):
"""Helper for load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
return _imp.load_dynamic(fullname, path)
class _NamespacePath: class _NamespacePath:
"""Represents a namespace package's path. It uses the module name """Represents a namespace package's path. It uses the module name
...@@ -1472,7 +1460,7 @@ def _find_and_load_unlocked(name, import_): ...@@ -1472,7 +1460,7 @@ def _find_and_load_unlocked(name, import_):
parent = name.rpartition('.')[0] parent = name.rpartition('.')[0]
if parent: if parent:
if parent not in sys.modules: if parent not in sys.modules:
_recursive_import(import_, parent) _call_with_frames_removed(import_, parent)
# Crazy side-effects! # Crazy side-effects!
if name in sys.modules: if name in sys.modules:
return sys.modules[name] return sys.modules[name]
...@@ -1550,13 +1538,6 @@ def _gcd_import(name, package=None, level=0): ...@@ -1550,13 +1538,6 @@ def _gcd_import(name, package=None, level=0):
_lock_unlock_module(name) _lock_unlock_module(name)
return module return module
def _recursive_import(import_, name):
"""Common exit point for recursive calls to the import machinery
This simplifies the process of stripping importlib from tracebacks
"""
return import_(name)
def _handle_fromlist(module, fromlist, import_): def _handle_fromlist(module, fromlist, import_):
"""Figure out what __import__ should return. """Figure out what __import__ should return.
...@@ -1575,7 +1556,7 @@ def _handle_fromlist(module, fromlist, import_): ...@@ -1575,7 +1556,7 @@ def _handle_fromlist(module, fromlist, import_):
fromlist.extend(module.__all__) fromlist.extend(module.__all__)
for x in fromlist: for x in fromlist:
if not hasattr(module, x): if not hasattr(module, x):
_recursive_import(import_, _call_with_frames_removed(import_,
'{}.{}'.format(module.__name__, x)) '{}.{}'.format(module.__name__, x))
return module return module
......
...@@ -7,6 +7,7 @@ import signal ...@@ -7,6 +7,7 @@ import signal
import subprocess import subprocess
import sys import sys
from test import support, script_helper from test import support, script_helper
from test.script_helper import assert_python_ok
import tempfile import tempfile
import unittest import unittest
...@@ -256,6 +257,20 @@ faulthandler._read_null() ...@@ -256,6 +257,20 @@ faulthandler._read_null()
finally: finally:
sys.stderr = orig_stderr sys.stderr = orig_stderr
def test_disabled_by_default(self):
# By default, the module should be disabled
code = "import faulthandler; print(faulthandler.is_enabled())"
rc, stdout, stderr = assert_python_ok("-c", code)
stdout = (stdout + stderr).strip()
self.assertEqual(stdout, b"False")
def test_sys_xoptions(self):
# Test python -X faulthandler
code = "import faulthandler; print(faulthandler.is_enabled())"
rc, stdout, stderr = assert_python_ok("-X", "faulthandler", "-c", code)
stdout = (stdout + stderr).strip()
self.assertEqual(stdout, b"True")
def check_dump_traceback(self, filename): def check_dump_traceback(self, filename):
""" """
Explicitly call dump_traceback() function and check its output. Explicitly call dump_traceback() function and check its output.
......
...@@ -785,11 +785,13 @@ class ImportTracebackTests(unittest.TestCase): ...@@ -785,11 +785,13 @@ class ImportTracebackTests(unittest.TestCase):
sys.path[:] = self.old_path sys.path[:] = self.old_path
rmtree(TESTFN) rmtree(TESTFN)
def create_module(self, mod, contents): def create_module(self, mod, contents, ext=".py"):
with open(os.path.join(TESTFN, mod + ".py"), "w") as f: fname = os.path.join(TESTFN, mod + ext)
with open(fname, "w") as f:
f.write(contents) f.write(contents)
self.addCleanup(unload, mod) self.addCleanup(unload, mod)
importlib.invalidate_caches() importlib.invalidate_caches()
return fname
def assert_traceback(self, tb, files): def assert_traceback(self, tb, files):
deduped_files = [] deduped_files = []
...@@ -857,16 +859,14 @@ class ImportTracebackTests(unittest.TestCase): ...@@ -857,16 +859,14 @@ class ImportTracebackTests(unittest.TestCase):
def _setup_broken_package(self, parent, child): def _setup_broken_package(self, parent, child):
pkg_name = "_parent_foo" pkg_name = "_parent_foo"
def cleanup(): self.addCleanup(unload, pkg_name)
rmtree(pkg_name) pkg_path = os.path.join(TESTFN, pkg_name)
unload(pkg_name) os.mkdir(pkg_path)
os.mkdir(pkg_name)
self.addCleanup(cleanup)
# Touch the __init__.py # Touch the __init__.py
init_path = os.path.join(pkg_name, '__init__.py') init_path = os.path.join(pkg_path, '__init__.py')
with open(init_path, 'w') as f: with open(init_path, 'w') as f:
f.write(parent) f.write(parent)
bar_path = os.path.join(pkg_name, 'bar.py') bar_path = os.path.join(pkg_path, 'bar.py')
with open(bar_path, 'w') as f: with open(bar_path, 'w') as f:
f.write(child) f.write(child)
importlib.invalidate_caches() importlib.invalidate_caches()
......
...@@ -10,6 +10,10 @@ What's New in Python 3.3.0 Beta 2? ...@@ -10,6 +10,10 @@ What's New in Python 3.3.0 Beta 2?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #15508: Fix the docstring for __import__ to have the proper default
value of 0 for 'level' and to not mention negative levels since they are
not supported.
- Issue #15425: Eliminated traceback noise from more situations involving - Issue #15425: Eliminated traceback noise from more situations involving
importlib importlib
...@@ -342,6 +346,9 @@ Core and Builtins ...@@ -342,6 +346,9 @@ Core and Builtins
Library Library
------- -------
- Issue #9803: Don't close IDLE on saving if breakpoint is open.
Patch by Roger Serwy.
- Issue #12288: Consider '0' and '0.0' as valid initialvalue - Issue #12288: Consider '0' and '0.0' as valid initialvalue
for tkinter SimpleDialog. for tkinter SimpleDialog.
......
...@@ -195,7 +195,7 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -195,7 +195,7 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
} }
PyDoc_STRVAR(import_doc, PyDoc_STRVAR(import_doc,
"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\ "__import__(name, globals={}, locals={}, fromlist=[], level=0) -> module\n\
\n\ \n\
Import a module. Because this function is meant for use by the Python\n\ Import a module. Because this function is meant for use by the Python\n\
interpreter and not for general use it is better to use\n\ interpreter and not for general use it is better to use\n\
...@@ -208,8 +208,7 @@ empty list to emulate ``import name''.\n\ ...@@ -208,8 +208,7 @@ empty list to emulate ``import name''.\n\
When importing a module from a package, note that __import__('A.B', ...)\n\ When importing a module from a package, note that __import__('A.B', ...)\n\
returns package A when fromlist is empty, but its submodule B when\n\ returns package A when fromlist is empty, but its submodule B when\n\
fromlist is not empty. Level is used to determine whether to perform \n\ fromlist is not empty. Level is used to determine whether to perform \n\
absolute or relative imports. -1 is the original strategy of attempting\n\ absolute or relative imports. 0 is absolute while a positive number\n\
both absolute and relative imports, 0 is absolute, a positive number\n\
is the number of parent directories to search relative to the current module."); is the number of parent directories to search relative to the current module.");
......
...@@ -1153,9 +1153,7 @@ static void ...@@ -1153,9 +1153,7 @@ static void
remove_importlib_frames(void) remove_importlib_frames(void)
{ {
const char *importlib_filename = "<frozen importlib._bootstrap>"; const char *importlib_filename = "<frozen importlib._bootstrap>";
const char *exec_funcname = "_exec_module"; const char *remove_frames = "_call_with_frames_removed";
const char *get_code_funcname = "get_code";
const char *recursive_import = "_recursive_import";
int always_trim = 0; int always_trim = 0;
int trim_get_code = 0; int trim_get_code = 0;
int in_importlib = 0; int in_importlib = 0;
...@@ -1163,18 +1161,8 @@ remove_importlib_frames(void) ...@@ -1163,18 +1161,8 @@ remove_importlib_frames(void)
PyObject **prev_link, **outer_link = NULL; PyObject **prev_link, **outer_link = NULL;
/* Synopsis: if it's an ImportError, we trim all importlib chunks /* Synopsis: if it's an ImportError, we trim all importlib chunks
from the traceback. If it's a SyntaxError, we trim any chunks that from the traceback. We always trim chunks
end with a call to "get_code", We always trim chunks which end with a call to "_call_with_frames_removed". */
which end with a call to "_exec_module". */
/* Thanks to issue 15425, we also strip any chunk ending with
* _recursive_import. This is used when making a recursive call to the
* full import machinery which means the inner stack gets stripped early
* and the normal heuristics won't fire properly for outer frames. A
* more elegant mechanism would be nice, as this one can misfire if
* builtins.__import__ has been replaced with a custom implementation.
* However, the current approach at least gets the job done.
*/
PyErr_Fetch(&exception, &value, &base_tb); PyErr_Fetch(&exception, &value, &base_tb);
if (!exception || Py_VerboseFlag) if (!exception || Py_VerboseFlag)
...@@ -1207,14 +1195,8 @@ remove_importlib_frames(void) ...@@ -1207,14 +1195,8 @@ remove_importlib_frames(void)
if (in_importlib && if (in_importlib &&
(always_trim || (always_trim ||
(PyUnicode_CompareWithASCIIString(code->co_name, PyUnicode_CompareWithASCIIString(code->co_name,
exec_funcname) == 0) || remove_frames) == 0)) {
(PyUnicode_CompareWithASCIIString(code->co_name,
recursive_import) == 0) ||
(trim_get_code &&
PyUnicode_CompareWithASCIIString(code->co_name,
get_code_funcname) == 0)
)) {
PyObject *tmp = *outer_link; PyObject *tmp = *outer_link;
*outer_link = next; *outer_link = next;
Py_XINCREF(next); Py_XINCREF(next);
......
This diff is collapsed.
...@@ -356,10 +356,6 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) ...@@ -356,10 +356,6 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
_PyImportHooks_Init(); _PyImportHooks_Init();
/* initialize the faulthandler module */
if (_PyFaulthandler_Init())
Py_FatalError("Py_Initialize: can't initialize faulthandler");
/* Initialize _warnings. */ /* Initialize _warnings. */
_PyWarnings_Init(); _PyWarnings_Init();
...@@ -368,6 +364,10 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) ...@@ -368,6 +364,10 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
import_init(interp, sysmod); import_init(interp, sysmod);
/* initialize the faulthandler module */
if (_PyFaulthandler_Init())
Py_FatalError("Py_Initialize: can't initialize faulthandler");
_PyTime_Init(); _PyTime_Init();
if (initfsencoding(interp) < 0) if (initfsencoding(interp) < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment