This commit is contained in:
Barry Warsaw 2012-07-31 16:03:25 -04:00
commit 9a5af1288d
14 changed files with 3742 additions and 3695 deletions

View File

@ -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
syntax. Because PyPI applies additional checks (e.g. by passing ``--no-raw``
to ``rst2html.py`` in the command above), running the command above without
warnings is not sufficient for PyPI to convert the content successfully.
to ``rst2html.py`` in the command above), being able to run the command above
without warnings does not guarantee that PyPI will convert the content
successfully.

View File

@ -19,7 +19,7 @@ An Introduction to the ipaddress module
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
:mod:`ipaddress` to create objects from strings and integers.
@ -183,10 +183,10 @@ Finding out how many individual addresses are in a network::
>>> net6.numhosts
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')
>>> for x in net4.iterhosts():
>>> for x in net4.hosts():
print(x)
192.0.2.1
192.0.2.2
@ -294,7 +294,7 @@ Getting more detail when instance creation fails
When creating address/network/interface objects using the version-agnostic
factory functions, any errors will be reported as :exc:`ValueError` with
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
or IPv6 in order to provide more detail on why it has been rejected.

View File

@ -23,7 +23,7 @@ tracebacks:
* Only ASCII is supported. The ``backslashreplace`` error handler is used on
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
displayed. (no source code)
* It is limited to 100 frames and 100 threads.

View File

@ -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,
use :func:`importlib.import_module`.
.. versionchanged:: 3.3
Negative values for *level* are no longer supported.
.. rubric:: Footnotes

View File

@ -22,19 +22,18 @@ subnet, as well as checking whether or not a string represents a valid
IP address or network definition.
Defining IP Addresses and Interfaces
------------------------------------
Convenience factory functions
-----------------------------
The :mod:`ipaddress` module provides factory functions to define IP addresses
and networks:
The :mod:`ipaddress` module provides factory functions to conveniently create
IP addresses, networks and interfaces:
.. function:: ip_address(address)
Return an :class:`IPv4Address` or :class:`IPv6Address` object depending on
the IP address passed as argument. *address* is a string or integer
representing the IP address. Either IPv4 or IPv6 addresses may be supplied;
integers less than 2**32 will be considered to be IPv4 by default. A
:exc:`ValueError` is raised if the *address* passed is neither an IPv4 nor
the IP address passed as argument. Either IPv4 or IPv6 addresses may be
supplied; integers less than 2**32 will be considered to be IPv4 by default.
A :exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
IPv6 address.
>>> ipaddress.ip_address('192.168.0.1')
@ -50,8 +49,8 @@ and networks:
representing the IP network. Either IPv4 or IPv6 networks may be supplied;
integers less than 2**32 will be considered to be IPv4 by default. *strict*
is passed to :class:`IPv4Network` or :class:`IPv6Network` constructor. A
:exc:`ValueError` is raised if the string passed isn't either an IPv4 or IPv6
address, or if the network has host bits set.
:exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
IPv6 address, or if the network has host bits set.
>>> ipaddress.ip_network('192.168.0.0/28')
IPv4Network('192.168.0.0/28')
@ -62,45 +61,174 @@ and networks:
Return an :class:`IPv4Interface` or :class:`IPv6Interface` object depending
on the IP address passed as argument. *address* is a string or integer
representing the IP address. Either IPv4 or IPv6 addresses may be supplied;
integers less than 2**32 will be considered to be IPv4 by default.. A
:exc:`ValueError` is raised if the *address* passed isn't either an IPv4 or
integers less than 2**32 will be considered to be IPv4 by default. A
:exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
IPv6 address.
Representing IP Addresses and Networks
--------------------------------------
Address objects
---------------
The module defines the following and classes to represent IP addresses
and networks:
.. todo: list the properties and methods
The :class:`IPv4Address` and :class:`IPv6Address` objects share a lot of common
attributes. Some attributes that are only meaningful for IPv6 addresses are
also implemented by :class:`IPv4Address` objects, in order to make it easier to
write code that handles both IP versions correctly. To avoid duplication, all
common attributes will only be documented for :class:`IPv4Address`.
.. class:: IPv4Address(address)
Construct an IPv4 address. *address* is a string or integer representing the
IP address. An :exc:`AddressValueError` is raised if *address* is not a
valid IPv4 address.
Construct an IPv4 address. An :exc:`AddressValueError` is raised if
*address* is not a valid IPv4 address.
The following constitutes a valid IPv4 address:
1. A string in decimal-dot notation, consisting of four decimal integers in
the inclusive range 0-255, separated by dots (e.g. ``192.168.0.1``). Each
integer represents an octet (byte) in the address, big-endian.
2. An integer that fits into 32 bits.
3. An integer packed into a :class:`bytes` object of length 4, big-endian.
>>> ipaddress.IPv4Address('192.168.0.1')
IPv4Address('192.168.0.1')
>>> ipaddress.IPv4Address('192.0.2.1') == ipaddress.IPv4Address(3221225985)
True
.. attribute:: exploded
.. class:: IPv4Interface(address)
The longhand version of the address as a string. Note: the
exploded/compressed distinction is meaningful only for IPv6 addresses.
For IPv4 addresses it is the same.
Construct an IPv4 interface. *address* is a string or integer representing
the IP interface. An :exc:`AddressValueError` is raised if *address* is not
a valid IPv4 address.
.. attribute:: compressed
The network address for the interface is determined by calling
``IPv4Network(address, strict=False)``.
The shorthand version of the address as a string.
>>> ipaddress.IPv4Interface('192.168.0.0/24')
IPv4Interface('192.168.0.0/24')
>>> ipaddress.IPv4Interface('192.168.0.0/24').network
IPv4Network('192.168.0.0/24')
.. attribute:: packed
The binary representation of this address - a :class:`bytes` object.
.. attribute:: version
A numeric version number.
.. attribute:: max_prefixlen
Maximal length of the prefix (in bits). The prefix defines the number of
leading bits in an address that are compared to determine whether or not an
address is part of a network.
.. attribute:: is_multicast
``True`` if the address is reserved for multicast use. See :RFC:`3171` (for
IPv4) or :RFC:`2373` (for IPv6).
.. attribute:: is_private
``True`` if the address is allocated for private networks. See :RFC:`1918`
(for IPv4) or :RFC:`4193` (for IPv6).
.. attribute:: is_unspecified
``True`` if the address is unspecified. See :RFC:`5375` (for IPv4) or
:RFC:`2373` (for IPv6).
.. attribute:: is_reserved
``True`` if the address is otherwise IETF reserved.
.. attribute:: is_loopback
``True`` if this is a loopback address. See :RFC:`3330` (for IPv4) or
:RFC:`2373` (for IPv6).
.. attribute:: is_link_local
``True`` if the address is reserved for link-local. See :RFC:`3927`.
.. class:: IPv6Address(address)
Construct an IPv6 address. An :exc:`AddressValueError` is raised if
*address* is not a valid IPv6 address.
The following constitutes a valid IPv6 address:
1. A string consisting of eight groups of four hexadecimal digits, each
group representing 16 bits. The groups are separated by colons.
This describes an *exploded* (longhand) notation. The string can
also be *compressed* (shorthand notation) by various means. See
:RFC:`4291` for details. For example,
``"0000:0000:0000:0000:0000:0abc:0007:0def"`` can be compressed to
``"::abc:7:def"``.
2. An integer that fits into 128 bits.
3. An integer packed into a :class:`bytes` object of length 16, big-endian.
>>> ipaddress.IPv6Address('2001:db8::1000')
IPv6Address('2001:db8::1000')
All the attributes exposed by :class:`IPv4Address` are supported. In
addition, the following attributs are exposed only by :class:`IPv6Address`.
.. attribute:: is_site_local
``True`` if the address is reserved for site-local. Note that the site-local
address space has been deprecated by :RFC:`3879`. Use
:attr:`~IPv4Address.is_private` to test if this address is in the space of
unique local addresses as defined by :RFC:`4193`.
.. attribute:: ipv4_mapped
If this address represents a IPv4 mapped address, return the IPv4 mapped
address. Otherwise return ``None``.
.. attribute:: teredo
If this address appears to be a teredo address (starts with ``2001::/32``),
return a tuple of embedded teredo IPs ``(server, client)`` pairs. Otherwise
return ``None``.
.. attribute:: sixtofour
If this address appears to contain a 6to4 embedded address, return the
embedded IPv4 address. Otherwise return ``None``.
Operators
^^^^^^^^^
Address objects support some operators. Unless stated otherwise, operators can
only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with
IPv6).
Logical operators
"""""""""""""""""
Address objects can be compared with the usual set of logical operators. Some
examples::
>>> IPv4Address('127.0.0.2') > IPv4Address('127.0.0.1')
True
>>> IPv4Address('127.0.0.2') == IPv4Address('127.0.0.1')
False
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
True
Arithmetic operators
""""""""""""""""""""
Integers can be added to or subtracted from address objects. Some examples::
>>> IPv4Address('127.0.0.2') + 3
IPv4Address('127.0.0.5')
>>> IPv4Address('127.0.0.2') - 3
IPv4Address('126.255.255.255')
>>> IPv4Address('255.255.255.255') + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address
Network objects
---------------
.. class:: IPv4Network(address, strict=True)
@ -121,31 +249,6 @@ and networks:
IPv4Network('192.0.2.0/27')
.. class:: IPv6Address(address)
Construct an IPv6 address. *address* is a string or integer representing the
IP address. An :exc:`AddressValueError` is raised if *address* is not a
valid IPv6 address.
>>> ipaddress.IPv6Address('2001:db8::1000')
IPv6Address('2001:db8::1000')
.. class:: IPv6Interface(address)
Construct an IPv6 interface. *address* is a string or integer representing
the IP interface. An :exc:`AddressValueError` is raised if *address* is not
a valid IPv6 address.
The network address for the interface is determined by calling
``IPv6Network(address, strict=False)``.
>>> ipaddress.IPv6Interface('2001:db8::1000/96')
IPv6Interface('2001:db8::1000/96')
>>> ipaddress.IPv6Interface('2001:db8::1000/96').network
IPv6Network('2001:db8::/96')
.. class:: IPv6Network(address, strict=True)
Construct an IPv6 network. *address* is a string or integer representing the
@ -165,6 +268,39 @@ and networks:
IPv6Network('2001:db8::/96')
Interface objects
-----------------
.. class:: IPv4Interface(address)
Construct an IPv4 interface. *address* is a string or integer representing
the IP interface. An :exc:`AddressValueError` is raised if *address* is not
a valid IPv4 address.
The network address for the interface is determined by calling
``IPv4Network(address, strict=False)``.
>>> ipaddress.IPv4Interface('192.168.0.0/24')
IPv4Interface('192.168.0.0/24')
>>> ipaddress.IPv4Interface('192.168.0.0/24').network
IPv4Network('192.168.0.0/24')
.. class:: IPv6Interface(address)
Construct an IPv6 interface. *address* is a string or integer representing
the IP interface. An :exc:`AddressValueError` is raised if *address* is not
a valid IPv6 address.
The network address for the interface is determined by calling
``IPv6Network(address, strict=False)``.
>>> ipaddress.IPv6Interface('2001:db8::1000/96')
IPv6Interface('2001:db8::1000/96')
>>> ipaddress.IPv6Interface('2001:db8::1000/96').network
IPv6Network('2001:db8::/96')
Other Module Level Functions
----------------------------

View File

@ -248,8 +248,8 @@ class PyShellEditorWindow(EditorWindow):
def ranges_to_linenumbers(self, ranges):
lines = []
for index in range(0, len(ranges), 2):
lineno = int(float(ranges[index]))
end = int(float(ranges[index+1]))
lineno = int(float(ranges[index].string))
end = int(float(ranges[index+1].string))
while lineno < end:
lines.append(lineno)
lineno += 1

View File

@ -297,8 +297,20 @@ def _lock_unlock_module(name):
else:
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.
It should change for each incompatible change to the bytecode.
@ -629,19 +641,12 @@ class BuiltinImporter:
"""Load a built-in module."""
is_reload = fullname in sys.modules
try:
return cls._exec_module(fullname)
return _call_with_frames_removed(_imp.init_builtin, fullname)
except:
if not is_reload and fullname in sys.modules:
del sys.modules[fullname]
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
@_requires_builtin
def get_code(cls, fullname):
@ -687,7 +692,7 @@ class FrozenImporter:
"""Load a frozen module."""
is_reload = fullname in sys.modules
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.
del m.__file__
return m
@ -714,13 +719,6 @@ class FrozenImporter:
"""Return if the frozen module is a package."""
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:
@ -850,15 +848,9 @@ class _LoaderBasics:
else:
module.__package__ = module.__package__.rpartition('.')[0]
module.__loader__ = self
self._exec_module(code_object, module.__dict__)
_call_with_frames_removed(exec, code_object, module.__dict__)
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):
@ -956,8 +948,9 @@ class SourceLoader(_LoaderBasics):
raise ImportError(msg.format(bytecode_path),
name=fullname, path=bytecode_path)
source_bytes = self.get_data(source_path)
code_object = compile(source_bytes, source_path, 'exec',
dont_inherit=True)
code_object = _call_with_frames_removed(compile,
source_bytes, source_path, 'exec',
dont_inherit=True)
_verbose_message('code object from {}', source_path)
if (not sys.dont_write_bytecode and bytecode_path is not None and
source_mtime is not None):
@ -1093,7 +1086,8 @@ class ExtensionFileLoader:
"""Load an extension module."""
is_reload = fullname in sys.modules
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)
return module
except:
@ -1113,12 +1107,6 @@ class ExtensionFileLoader:
"""Return None as extension modules have no source code."""
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:
"""Represents a namespace package's path. It uses the module name
@ -1472,7 +1460,7 @@ def _find_and_load_unlocked(name, import_):
parent = name.rpartition('.')[0]
if parent:
if parent not in sys.modules:
_recursive_import(import_, parent)
_call_with_frames_removed(import_, parent)
# Crazy side-effects!
if name in sys.modules:
return sys.modules[name]
@ -1550,13 +1538,6 @@ def _gcd_import(name, package=None, level=0):
_lock_unlock_module(name)
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_):
"""Figure out what __import__ should return.
@ -1575,7 +1556,7 @@ def _handle_fromlist(module, fromlist, import_):
fromlist.extend(module.__all__)
for x in fromlist:
if not hasattr(module, x):
_recursive_import(import_,
_call_with_frames_removed(import_,
'{}.{}'.format(module.__name__, x))
return module

View File

@ -7,6 +7,7 @@ import signal
import subprocess
import sys
from test import support, script_helper
from test.script_helper import assert_python_ok
import tempfile
import unittest
@ -256,6 +257,20 @@ faulthandler._read_null()
finally:
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):
"""
Explicitly call dump_traceback() function and check its output.

View File

@ -785,11 +785,13 @@ class ImportTracebackTests(unittest.TestCase):
sys.path[:] = self.old_path
rmtree(TESTFN)
def create_module(self, mod, contents):
with open(os.path.join(TESTFN, mod + ".py"), "w") as f:
def create_module(self, mod, contents, ext=".py"):
fname = os.path.join(TESTFN, mod + ext)
with open(fname, "w") as f:
f.write(contents)
self.addCleanup(unload, mod)
importlib.invalidate_caches()
return fname
def assert_traceback(self, tb, files):
deduped_files = []
@ -857,16 +859,14 @@ class ImportTracebackTests(unittest.TestCase):
def _setup_broken_package(self, parent, child):
pkg_name = "_parent_foo"
def cleanup():
rmtree(pkg_name)
unload(pkg_name)
os.mkdir(pkg_name)
self.addCleanup(cleanup)
self.addCleanup(unload, pkg_name)
pkg_path = os.path.join(TESTFN, pkg_name)
os.mkdir(pkg_path)
# 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:
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:
f.write(child)
importlib.invalidate_caches()

View File

@ -10,6 +10,10 @@ What's New in Python 3.3.0 Beta 2?
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
importlib
@ -342,6 +346,9 @@ Core and Builtins
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
for tkinter SimpleDialog.

View File

@ -195,7 +195,7 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
}
PyDoc_STRVAR(import_doc,
"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\
"__import__(name, globals={}, locals={}, fromlist=[], level=0) -> module\n\
\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\
@ -208,8 +208,7 @@ empty list to emulate ``import name''.\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\
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\
both absolute and relative imports, 0 is absolute, a positive number\n\
absolute or relative imports. 0 is absolute while a positive number\n\
is the number of parent directories to search relative to the current module.");

View File

@ -1153,9 +1153,7 @@ static void
remove_importlib_frames(void)
{
const char *importlib_filename = "<frozen importlib._bootstrap>";
const char *exec_funcname = "_exec_module";
const char *get_code_funcname = "get_code";
const char *recursive_import = "_recursive_import";
const char *remove_frames = "_call_with_frames_removed";
int always_trim = 0;
int trim_get_code = 0;
int in_importlib = 0;
@ -1163,18 +1161,8 @@ remove_importlib_frames(void)
PyObject **prev_link, **outer_link = NULL;
/* Synopsis: if it's an ImportError, we trim all importlib chunks
from the traceback. If it's a SyntaxError, we trim any chunks that
end with a call to "get_code", We always trim chunks
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.
*/
from the traceback. We always trim chunks
which end with a call to "_call_with_frames_removed". */
PyErr_Fetch(&exception, &value, &base_tb);
if (!exception || Py_VerboseFlag)
@ -1207,14 +1195,8 @@ remove_importlib_frames(void)
if (in_importlib &&
(always_trim ||
(PyUnicode_CompareWithASCIIString(code->co_name,
exec_funcname) == 0) ||
(PyUnicode_CompareWithASCIIString(code->co_name,
recursive_import) == 0) ||
(trim_get_code &&
PyUnicode_CompareWithASCIIString(code->co_name,
get_code_funcname) == 0)
)) {
PyUnicode_CompareWithASCIIString(code->co_name,
remove_frames) == 0)) {
PyObject *tmp = *outer_link;
*outer_link = next;
Py_XINCREF(next);

File diff suppressed because it is too large Load Diff

View File

@ -356,10 +356,6 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
_PyImportHooks_Init();
/* initialize the faulthandler module */
if (_PyFaulthandler_Init())
Py_FatalError("Py_Initialize: can't initialize faulthandler");
/* Initialize _warnings. */
_PyWarnings_Init();
@ -368,6 +364,10 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
import_init(interp, sysmod);
/* initialize the faulthandler module */
if (_PyFaulthandler_Init())
Py_FatalError("Py_Initialize: can't initialize faulthandler");
_PyTime_Init();
if (initfsencoding(interp) < 0)