merge 2.7.12 release branch
diff --git a/Doc/Makefile b/Doc/Makefile
index ea30231..2220d92 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -161,7 +161,7 @@
-make suspicious
# for quick rebuilds (HTML only)
-autobuild-html:
+autobuild-dev-html:
make html SPHINXOPTS='-A daily=1 -A versionswitcher=1'
# for stable releases: only build if not in pre-release stage (alpha, beta)
@@ -173,3 +173,9 @@
esac
@make autobuild-dev
+autobuild-stable-html:
+ @case $(DISTVERSION) in *[ab]*) \
+ echo "Not building; $(DISTVERSION) is not a release version."; \
+ exit 1;; \
+ esac
+ @make autobuild-dev-html
diff --git a/Doc/c-api/class.rst b/Doc/c-api/class.rst
index 4dbe508..020309d 100644
--- a/Doc/c-api/class.rst
+++ b/Doc/c-api/class.rst
@@ -61,5 +61,5 @@
Create a new instance of a specific class without calling its constructor.
*class* is the class of new object. The *dict* parameter will be used as the
- object's :attr:`__dict__`; if *NULL*, a new dictionary will be created for the
+ object's :attr:`~object.__dict__`; if *NULL*, a new dictionary will be created for the
instance.
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 56e63cf..80e12e1 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -51,10 +51,10 @@
.. index:: single: __dict__ (module attribute)
Return the dictionary object that implements *module*'s namespace; this object
- is the same as the :attr:`__dict__` attribute of the module object. This
+ is the same as the :attr:`~object.__dict__` attribute of the module object. This
function never fails. It is recommended extensions use other
:c:func:`PyModule_\*` and :c:func:`PyObject_\*` functions rather than directly
- manipulate a module's :attr:`__dict__`.
+ manipulate a module's :attr:`~object.__dict__`.
.. c:function:: char* PyModule_GetName(PyObject *module)
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index c6ec685..8833a36 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -159,9 +159,8 @@
The :attr:`ml_flags` field is a bitfield which can include the following flags.
The individual flags indicate either a calling convention or a binding
convention. Of the calling convention flags, only :const:`METH_VARARGS` and
-:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS`
-alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling
-convention flags can be combined with a binding flag.
+:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags
+can be combined with a binding flag.
.. data:: METH_VARARGS
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index fdd679f..a9981fe 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -117,10 +117,10 @@
For statically allocated type objects, the tp_name field should contain a dot.
Everything before the last dot is made accessible as the :attr:`__module__`
attribute, and everything after the last dot is made accessible as the
- :attr:`__name__` attribute.
+ :attr:`~definition.__name__` attribute.
If no dot is present, the entire :c:member:`~PyTypeObject.tp_name` field is made accessible as the
- :attr:`__name__` attribute, and the :attr:`__module__` attribute is undefined
+ :attr:`~definition.__name__` attribute, and the :attr:`__module__` attribute is undefined
(unless explicitly set in the dictionary, as explained above). This means your
type will be impossible to pickle.
diff --git a/Doc/library/__builtin__.rst b/Doc/library/__builtin__.rst
index 673d74f..cb8b53a 100644
--- a/Doc/library/__builtin__.rst
+++ b/Doc/library/__builtin__.rst
@@ -39,6 +39,6 @@
Most modules have the name ``__builtins__`` (note the ``'s'``) made available
as part of their globals. The value of ``__builtins__`` is normally either
- this module or the value of this modules's :attr:`__dict__` attribute. Since
+ this module or the value of this modules's :attr:`~object.__dict__` attribute. Since
this is an implementation detail, it may not be used by alternate
implementations of Python.
diff --git a/Doc/library/curses.ascii.rst b/Doc/library/curses.ascii.rst
index 0a45c2a..4f4d915 100644
--- a/Doc/library/curses.ascii.rst
+++ b/Doc/library/curses.ascii.rst
@@ -116,12 +116,12 @@
.. function:: isblank(c)
- Checks for an ASCII whitespace character.
+ Checks for an ASCII whitespace character; space or horizontal tab.
.. function:: iscntrl(c)
- Checks for an ASCII control character (in the range 0x00 to 0x1f).
+ Checks for an ASCII control character (in the range 0x00 to 0x1f or 0x7f).
.. function:: isdigit(c)
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 20372b3..350bc71 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -311,7 +311,7 @@
:func:`dir` reports their attributes.
If the object does not provide :meth:`__dir__`, the function tries its best to
- gather information from the object's :attr:`__dict__` attribute, if defined, and
+ gather information from the object's :attr:`~object.__dict__` attribute, if defined, and
from its type object. The resulting list is not necessarily complete, and may
be inaccurate when the object has a custom :func:`__getattr__`.
@@ -1477,7 +1477,7 @@
With three arguments, return a new type object. This is essentially a
dynamic form of the :keyword:`class` statement. The *name* string is the
- class name and becomes the :attr:`~class.__name__` attribute; the *bases* tuple
+ class name and becomes the :attr:`~definition.__name__` attribute; the *bases* tuple
itemizes the base classes and becomes the :attr:`~class.__bases__` attribute;
and the *dict* dictionary is the namespace containing definitions for class
body and becomes the :attr:`~object.__dict__` attribute. For example, the
@@ -1545,11 +1545,11 @@
.. function:: vars([object])
Return the :attr:`~object.__dict__` attribute for a module, class, instance,
- or any other object with a :attr:`__dict__` attribute.
+ or any other object with a :attr:`~object.__dict__` attribute.
- Objects such as modules and instances have an updateable :attr:`__dict__`
+ Objects such as modules and instances have an updateable :attr:`~object.__dict__`
attribute; however, other objects may have write restrictions on their
- :attr:`__dict__` attributes (for example, new-style classes use a
+ :attr:`~object.__dict__` attributes (for example, new-style classes use a
dictproxy to prevent direct dictionary updates).
Without an argument, :func:`vars` acts like :func:`locals`. Note, the
diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst
index 10dbd0f..f3e396b 100644
--- a/Doc/library/functools.rst
+++ b/Doc/library/functools.rst
@@ -185,7 +185,7 @@
:class:`partial` objects are like :class:`function` objects in that they are
callable, weak referencable, and can have attributes. There are some important
-differences. For instance, the :attr:`__name__` and :attr:`__doc__` attributes
+differences. For instance, the :attr:`~definition.__name__` and :attr:`__doc__` attributes
are not created automatically. Also, :class:`partial` objects defined in
classes behave like static methods and do not transform into bound methods
during instance attribute look-up.
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 1964f71..c1b7bec 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -335,9 +335,11 @@
are true.
This is new as of Python 2.2, and, for example, is true of
- ``int.__add__``. An object passing this test has a :attr:`__get__` attribute
- but not a :attr:`__set__` attribute, but beyond that the set of attributes
- varies. :attr:`__name__` is usually sensible, and :attr:`__doc__` often is.
+ ``int.__add__``. An object passing this test
+ has a :meth:`~object.__get__` method but not a :meth:`~object.__set__`
+ method, but beyond that the set of attributes varies. A
+ :attr:`~definition.__name__` attribute is usually
+ sensible, and :attr:`__doc__` often is.
Methods implemented via descriptors that also pass one of the other tests
return false from the :func:`ismethoddescriptor` test, simply because the
@@ -349,11 +351,11 @@
Return true if the object is a data descriptor.
- Data descriptors have both a :attr:`__get__` and a :attr:`__set__` attribute.
+ Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method.
Examples are properties (defined in Python), getsets, and members. The
latter two are defined in C and there are more specific tests available for
those types, which is robust across Python implementations. Typically, data
- descriptors will also have :attr:`__name__` and :attr:`__doc__` attributes
+ descriptors will also have :attr:`~definition.__name__` and :attr:`__doc__` attributes
(properties, getsets, and members have both of these attributes), but this is
not guaranteed.
diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst
index a0ed89e..94e5e10 100644
--- a/Doc/library/readline.rst
+++ b/Doc/library/readline.rst
@@ -186,7 +186,8 @@
be used as the new hook function; if omitted or ``None``, any
function already installed is removed. The hook is called
with no arguments after the first prompt has been printed and just before
- readline starts reading input characters.
+ readline starts reading input characters. This function only exists
+ if Python was compiled for a version of the library that supports it.
Completion
diff --git a/Doc/library/restricted.rst b/Doc/library/restricted.rst
index 80f6344..fd07ab3 100644
--- a/Doc/library/restricted.rst
+++ b/Doc/library/restricted.rst
@@ -48,7 +48,7 @@
Python code executing in restricted mode faces a number of limitations that are
designed to prevent it from escaping from the padded cell. For instance, the
function object attribute :attr:`func_globals` and the class and instance object
-attribute :attr:`__dict__` are unavailable.
+attribute :attr:`~object.__dict__` are unavailable.
Two modules provide the framework for setting up restricted execution
environments:
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 5d8ebbc..7cecfef 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1217,13 +1217,68 @@
Line breaks are not included in the resulting list unless *keepends* is
given and true.
- For example, ``'ab c\n\nde fg\rkl\r\n'.splitlines()`` returns
- ``['ab c', '', 'de fg', 'kl']``, while the same call with ``splitlines(True)``
- returns ``['ab c\n', '\n', 'de fg\r', 'kl\r\n']``.
+ Python recognizes ``"\r"``, ``"\n"``, and ``"\r\n"`` as line boundaries for
+ 8-bit strings.
+
+ For example::
+
+ >>> 'ab c\n\nde fg\rkl\r\n'.splitlines()
+ ['ab c', '', 'de fg', 'kl']
+ >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(True)
+ ['ab c\n', '\n', 'de fg\r', 'kl\r\n']
Unlike :meth:`~str.split` when a delimiter string *sep* is given, this
method returns an empty list for the empty string, and a terminal line
- break does not result in an extra line.
+ break does not result in an extra line::
+
+ >>> "".splitlines()
+ []
+ >>> "One line\n".splitlines()
+ ['One line']
+
+ For comparison, ``split('\n')`` gives::
+
+ >>> ''.split('\n')
+ ['']
+ >>> 'Two lines\n'.split('\n')
+ ['Two lines', '']
+
+.. method:: unicode.splitlines([keepends])
+
+ Return a list of the lines in the string, like :meth:`str.splitlines`.
+ However, the Unicode method splits on the following line boundaries,
+ which are a superset of the :term:`universal newlines` recognized for
+ 8-bit strings.
+
+ +-----------------------+-----------------------------+
+ | Representation | Description |
+ +=======================+=============================+
+ | ``\n`` | Line Feed |
+ +-----------------------+-----------------------------+
+ | ``\r`` | Carriage Return |
+ +-----------------------+-----------------------------+
+ | ``\r\n`` | Carriage Return + Line Feed |
+ +-----------------------+-----------------------------+
+ | ``\v`` or ``\x0b`` | Line Tabulation |
+ +-----------------------+-----------------------------+
+ | ``\f`` or ``\x0c`` | Form Feed |
+ +-----------------------+-----------------------------+
+ | ``\x1c`` | File Separator |
+ +-----------------------+-----------------------------+
+ | ``\x1d`` | Group Separator |
+ +-----------------------+-----------------------------+
+ | ``\x1e`` | Record Separator |
+ +-----------------------+-----------------------------+
+ | ``\x85`` | Next Line (C1 Control Code) |
+ +-----------------------+-----------------------------+
+ | ``\u2028`` | Line Separator |
+ +-----------------------+-----------------------------+
+ | ``\u2029`` | Paragraph Separator |
+ +-----------------------+-----------------------------+
+
+ .. versionchanged:: 2.7
+
+ ``\v`` and ``\f`` added to list of line boundaries.
.. method:: str.startswith(prefix[, start[, end]])
@@ -2872,9 +2927,10 @@
A special attribute of every module is :attr:`~object.__dict__`. This is the
dictionary containing the module's symbol table. Modifying this dictionary will
actually change the module's symbol table, but direct assignment to the
-:attr:`__dict__` attribute is not possible (you can write
+:attr:`~object.__dict__` attribute is not possible (you can write
``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but you can't write
-``m.__dict__ = {}``). Modifying :attr:`__dict__` directly is not recommended.
+``m.__dict__ = {}``). Modifying :attr:`~object.__dict__` directly is
+not recommended.
Modules built into the interpreter are written like this: ``<module 'sys'
(built-in)>``. If loaded from a file, they are written as ``<module 'os' from
@@ -3101,9 +3157,10 @@
The tuple of base classes of a class object.
-.. attribute:: class.__name__
+.. attribute:: definition.__name__
- The name of the class or type.
+ The name of the class, type, function, method, descriptor, or
+ generator instance.
The following attributes are only supported by :term:`new-style class`\ es.
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index fe0cea8..9e62dfc 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -481,6 +481,24 @@
.. tabularcolumns:: |l|L|l|
+ .. index::
+ single: __doc__ (function attribute)
+ single: __name__ (function attribute)
+ single: __module__ (function attribute)
+ single: __dict__ (function attribute)
+ single: __defaults__ (function attribute)
+ single: __code__ (function attribute)
+ single: __globals__ (function attribute)
+ single: __closure__ (function attribute)
+ single: func_doc (function attribute)
+ single: func_name (function attribute)
+ single: func_dict (function attribute)
+ single: func_defaults (function attribute)
+ single: func_code (function attribute)
+ single: func_globals (function attribute)
+ single: func_closure (function attribute)
+ pair: global; namespace
+
+-----------------------+-------------------------------+-----------+
| Attribute | Meaning | |
+=======================+===============================+===========+
@@ -488,7 +506,8 @@
| :attr:`func_doc` | string, or ``None`` if | |
| | unavailable. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`__name__` | The function's name. | Writable |
+ | :attr:`~definition.\ | The function's name | Writable |
+ | __name__` | | |
| :attr:`func_name` | | |
+-----------------------+-------------------------------+-----------+
| :attr:`__module__` | The name of the module the | Writable |
@@ -511,9 +530,9 @@
| | module in which the function | |
| | was defined. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`__dict__` | The namespace supporting | Writable |
- | :attr:`func_dict` | arbitrary function | |
- | | attributes. | |
+ | :attr:`~object.\ | The namespace supporting | Writable |
+ | __dict__` | arbitrary function | |
+ | :attr:`func_dict` | attributes. | |
+-----------------------+-------------------------------+-----------+
| :attr:`__closure__` | ``None`` or a tuple of cells | Read-only |
| :attr:`func_closure` | that contain bindings for the | |
@@ -540,24 +559,6 @@
Additional information about a function's definition can be retrieved from its
code object; see the description of internal types below.
- .. index::
- single: __doc__ (function attribute)
- single: __name__ (function attribute)
- single: __module__ (function attribute)
- single: __dict__ (function attribute)
- single: __defaults__ (function attribute)
- single: __code__ (function attribute)
- single: __globals__ (function attribute)
- single: __closure__ (function attribute)
- single: func_doc (function attribute)
- single: func_name (function attribute)
- single: func_dict (function attribute)
- single: func_defaults (function attribute)
- single: func_code (function attribute)
- single: func_globals (function attribute)
- single: func_closure (function attribute)
- pair: global; namespace
-
User-defined methods
.. index::
object: method
@@ -571,7 +572,7 @@
:attr:`im_func` is the function object; :attr:`im_class` is the class of
:attr:`im_self` for bound methods or the class that asked for the method for
unbound methods; :attr:`__doc__` is the method's documentation (same as
- ``im_func.__doc__``); :attr:`__name__` is the method name (same as
+ ``im_func.__doc__``); :attr:`~definition.__name__` is the method name (same as
``im_func.__name__``); :attr:`__module__` is the name of the module the method
was defined in, or ``None`` if unavailable.
@@ -683,7 +684,7 @@
standard built-in module). The number and type of the arguments are
determined by the C function. Special read-only attributes:
:attr:`__doc__` is the function's documentation string, or ``None`` if
- unavailable; :attr:`__name__` is the function's name; :attr:`__self__` is
+ unavailable; :attr:`~definition.__name__` is the function's name; :attr:`__self__` is
set to ``None`` (but see the next item); :attr:`__module__` is the name of
the module the function was defined in or ``None`` if unavailable.
@@ -744,7 +745,7 @@
.. index:: single: __dict__ (module attribute)
- Special read-only attribute: :attr:`__dict__` is the module's namespace as a
+ Special read-only attribute: :attr:`~object.__dict__` is the module's namespace as a
dictionary object.
.. impl-detail::
@@ -806,7 +807,7 @@
static method object, it is transformed into the object wrapped by the static
method object. See section :ref:`descriptors` for another way in which
attributes retrieved from a class may differ from those actually contained in
- its :attr:`__dict__` (note that only new-style classes support descriptors).
+ its :attr:`~object.__dict__` (note that only new-style classes support descriptors).
.. index:: triple: class; attribute; assignment
@@ -824,8 +825,8 @@
single: __bases__ (class attribute)
single: __doc__ (class attribute)
- Special attributes: :attr:`__name__` is the class name; :attr:`__module__` is
- the module name in which the class was defined; :attr:`__dict__` is the
+ Special attributes: :attr:`~definition.__name__` is the class name; :attr:`__module__` is
+ the module name in which the class was defined; :attr:`~object.__dict__` is the
dictionary containing the class's namespace; :attr:`~class.__bases__` is a
tuple (possibly empty or a singleton) containing the base classes, in the
order of their occurrence in the base class list; :attr:`__doc__` is the
@@ -851,7 +852,7 @@
objects are also transformed, as if they had been retrieved from class
:class:`C`; see above under "Classes". See section :ref:`descriptors` for
another way in which attributes of a class retrieved via its instances may
- differ from the objects actually stored in the class's :attr:`__dict__`. If no
+ differ from the objects actually stored in the class's :attr:`~object.__dict__`. If no
class attribute is found, and the object's class has a :meth:`__getattr__`
method, that is called to satisfy the lookup.
@@ -1554,7 +1555,7 @@
descriptor must be in either the owner's class dictionary or in the class
dictionary for one of its parents). In the examples below, "the attribute"
refers to the attribute whose name is the key of the property in the owner
-class' :attr:`__dict__`.
+class' :attr:`~object.__dict__`.
.. method:: object.__get__(self, instance, owner)
diff --git a/Doc/tools/extensions/suspicious.py b/Doc/tools/extensions/suspicious.py
index d3ed849..0a70e57 100644
--- a/Doc/tools/extensions/suspicious.py
+++ b/Doc/tools/extensions/suspicious.py
@@ -270,5 +270,5 @@
# ignore comments -- too much false positives.
# (although doing this could miss some errors;
# there were two sections "commented-out" by mistake
- # in the Python docs that would not be catched)
+ # in the Python docs that would not be caught)
raise nodes.SkipNode
diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst
index b1f3f00..963581b 100644
--- a/Doc/tutorial/classes.rst
+++ b/Doc/tutorial/classes.rst
@@ -905,8 +905,8 @@
.. rubric:: Footnotes
.. [#] Except for one thing. Module objects have a secret read-only attribute called
- :attr:`__dict__` which returns the dictionary used to implement the module's
- namespace; the name :attr:`__dict__` is an attribute but not a global name.
+ :attr:`~object.__dict__` which returns the dictionary used to implement the module's
+ namespace; the name :attr:`~object.__dict__` is an attribute but not a global name.
Obviously, using this violates the abstraction of namespace implementation, and
should be restricted to things like post-mortem debuggers.
diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst
index 2cdd3a2..b859d76 100644
--- a/Doc/whatsnew/2.0.rst
+++ b/Doc/whatsnew/2.0.rst
@@ -506,7 +506,7 @@
you'd use the :func:`apply` built-in function: ``apply(f, args, kw)`` calls the
function :func:`f` with the argument tuple *args* and the keyword arguments in
the dictionary *kw*. :func:`apply` is the same in 2.0, but thanks to a patch
-from Greg Ewing, ``f(*args, **kw)`` as a shorter and clearer way to achieve the
+from Greg Ewing, ``f(*args, **kw)`` is a shorter and clearer way to achieve the
same effect. This syntax is symmetrical with the syntax for defining
functions::
diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst
index c34ba8a..d25e48d 100644
--- a/Doc/whatsnew/2.1.rst
+++ b/Doc/whatsnew/2.1.rst
@@ -442,8 +442,8 @@
f.grammar = "A ::= B (C D)*"
The dictionary containing attributes can be accessed as the function's
-:attr:`__dict__`. Unlike the :attr:`__dict__` attribute of class instances, in
-functions you can actually assign a new dictionary to :attr:`__dict__`, though
+:attr:`~object.__dict__`. Unlike the :attr:`~object.__dict__` attribute of class instances, in
+functions you can actually assign a new dictionary to :attr:`~object.__dict__`, though
the new value is restricted to a regular Python dictionary; you *can't* be
tricky and set it to a :class:`UserDict` instance, or any other random object
that behaves like a mapping.
diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst
index 43bc2ab..83227e1 100644
--- a/Doc/whatsnew/2.2.rst
+++ b/Doc/whatsnew/2.2.rst
@@ -157,7 +157,7 @@
conventions, such as defining :attr:`__members__` and :attr:`__methods__`
attributes that were lists of names, but often the author of an extension type
or a class wouldn't bother to define them. You could fall back on inspecting
-the :attr:`__dict__` of an object, but when class inheritance or an arbitrary
+the :attr:`~object.__dict__` of an object, but when class inheritance or an arbitrary
:meth:`__getattr__` hook were in use this could still be inaccurate.
The one big idea underlying the new class model is that an API for describing
@@ -169,7 +169,7 @@
Attribute descriptors are objects that live inside class objects, and have a few
attributes of their own:
-* :attr:`__name__` is the attribute's name.
+* :attr:`~definition.__name__` is the attribute's name.
* :attr:`__doc__` is the attribute's docstring.
@@ -329,7 +329,7 @@
to trap attribute references. Writing a :meth:`__getattr__` method is
complicated because to avoid recursion you can't use regular attribute accesses
inside them, and instead have to mess around with the contents of
-:attr:`__dict__`. :meth:`__getattr__` methods also end up being called by Python
+:attr:`~object.__dict__`. :meth:`__getattr__` methods also end up being called by Python
when it checks for other methods such as :meth:`__repr__` or :meth:`__coerce__`,
and so have to be written with this in mind. Finally, calling a function on
every attribute access results in a sizable performance loss.
@@ -357,15 +357,15 @@
That is certainly clearer and easier to write than a pair of
:meth:`__getattr__`/:meth:`__setattr__` methods that check for the :attr:`size`
attribute and handle it specially while retrieving all other attributes from the
-instance's :attr:`__dict__`. Accesses to :attr:`size` are also the only ones
+instance's :attr:`~object.__dict__`. Accesses to :attr:`size` are also the only ones
which have to perform the work of calling a function, so references to other
attributes run at their usual speed.
Finally, it's possible to constrain the list of attributes that can be
-referenced on an object using the new :attr:`__slots__` class attribute. Python
+referenced on an object using the new :attr:`~object.__slots__` class attribute. Python
objects are usually very dynamic; at any time it's possible to define a new
attribute on an instance by just doing ``obj.new_attr=1``. A new-style class
-can define a class attribute named :attr:`__slots__` to limit the legal
+can define a class attribute named :attr:`~object.__slots__` to limit the legal
attributes to a particular set of names. An example will make this clear::
>>> class C(object):
@@ -383,7 +383,7 @@
AttributeError: 'C' object has no attribute 'newattr'
Note how you get an :exc:`AttributeError` on the attempt to assign to an
-attribute not listed in :attr:`__slots__`.
+attribute not listed in :attr:`~object.__slots__`.
.. _sect-rellinks:
diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst
index bcf1b61..1d63663 100644
--- a/Doc/whatsnew/2.3.rst
+++ b/Doc/whatsnew/2.3.rst
@@ -1111,10 +1111,10 @@
<type '_socket.socket'>
* One of the noted incompatibilities between old- and new-style classes has been
- removed: you can now assign to the :attr:`__name__` and :attr:`__bases__`
+ removed: you can now assign to the :attr:`~definition.__name__` and :attr:`~class.__bases__`
attributes of new-style classes. There are some restrictions on what can be
- assigned to :attr:`__bases__` along the lines of those relating to assigning to
- an instance's :attr:`__class__` attribute.
+ assigned to :attr:`~class.__bases__` along the lines of those relating to assigning to
+ an instance's :attr:`~instance.__class__` attribute.
.. ======================================================================
@@ -1920,7 +1920,7 @@
* If you dynamically allocate type objects in your extension, you should be
aware of a change in the rules relating to the :attr:`__module__` and
- :attr:`__name__` attributes. In summary, you will want to ensure the type's
+ :attr:`~definition.__name__` attributes. In summary, you will want to ensure the type's
dictionary contains a ``'__module__'`` key; making the module name the part of
the type name leading up to the final period will no longer have the desired
effect. For more detail, read the API reference documentation or the source.
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index 4c57860..fbb9e33 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -27,7 +27,7 @@
#define PY_RELEASE_SERIAL 1
/* Version as a string */
-#define PY_VERSION "2.7.12rc1"
+#define PY_VERSION "2.7.12rc1+"
/*--end constants--*/
/* Subversion Revision number of this file (not of the repository). Empty
diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py
index e7a0a93..2668899 100644
--- a/Lib/ctypes/test/test_find.py
+++ b/Lib/ctypes/test/test_find.py
@@ -1,6 +1,7 @@
import unittest
-import os
+import os, os.path
import sys
+from test import test_support
from ctypes import *
from ctypes.util import find_library
from ctypes.test import is_resource_enabled
@@ -65,6 +66,11 @@
if self.gle:
self.gle.gleGetJoinStyle
+ def test_shell_injection(self):
+ result = find_library('; echo Hello shell > ' + test_support.TESTFN)
+ self.assertFalse(os.path.lexists(test_support.TESTFN))
+ self.assertIsNone(result)
+
# On platforms where the default shared library suffix is '.so',
# at least some libraries can be loaded as attributes of the cdll
# object, since ctypes now tries loading the lib again
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index b2c514d..ab10ec5 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -1,4 +1,6 @@
-import sys, os
+import os
+import subprocess
+import sys
# find_library(name) returns the pathname of a library, or None.
if os.name == "nt":
@@ -86,25 +88,28 @@
import re, tempfile, errno
def _findLib_gcc(name):
+ # Run GCC's linker with the -t (aka --trace) option and examine the
+ # library name it prints out. The GCC command will fail because we
+ # haven't supplied a proper program with main(), but that does not
+ # matter.
expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
- fdout, ccout = tempfile.mkstemp()
- os.close(fdout)
- cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \
- 'LANG=C LC_ALL=C $CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
+ cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit; fi;' \
+ 'LANG=C LC_ALL=C $CC -Wl,-t -o "$2" 2>&1 -l"$1"'
+
+ temp = tempfile.NamedTemporaryFile()
try:
- f = os.popen(cmd)
- try:
- trace = f.read()
- finally:
- rv = f.close()
+ proc = subprocess.Popen((cmd, '_findLib_gcc', name, temp.name),
+ shell=True,
+ stdout=subprocess.PIPE)
+ [trace, _] = proc.communicate()
finally:
try:
- os.unlink(ccout)
+ temp.close()
except OSError, e:
+ # ENOENT is raised if the file was already removed, which is
+ # the normal behaviour of GCC if linking fails
if e.errno != errno.ENOENT:
raise
- if rv == 10:
- raise OSError, 'gcc or cc command not found'
res = re.search(expr, trace)
if not res:
return None
@@ -116,13 +121,17 @@
def _get_soname(f):
if not f:
return None
- cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f
- f = os.popen(cmd)
+
+ null = open(os.devnull, "wb")
try:
- data = f.read()
- finally:
- f.close()
- res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data)
+ with null:
+ proc = subprocess.Popen(("/usr/ccs/bin/dump", "-Lpv", f),
+ stdout=subprocess.PIPE,
+ stderr=null)
+ except OSError: # E.g. command not found
+ return None
+ [data, _] = proc.communicate()
+ res = re.search(br'\[.*\]\sSONAME\s+([^\s]+)', data)
if not res:
return None
return res.group(1)
@@ -131,16 +140,12 @@
# assuming GNU binutils / ELF
if not f:
return None
- cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \
- "objdump -p -j .dynamic 2>/dev/null " + f
- f = os.popen(cmd)
- try:
- dump = f.read()
- finally:
- rv = f.close()
- if rv == 10:
- raise OSError, 'objdump command not found'
- res = re.search(r'\sSONAME\s+([^\s]+)', dump)
+ cmd = 'if ! type objdump >/dev/null 2>&1; then exit; fi;' \
+ 'objdump -p -j .dynamic 2>/dev/null "$1"'
+ proc = subprocess.Popen((cmd, '_get_soname', f), shell=True,
+ stdout=subprocess.PIPE)
+ [dump, _] = proc.communicate()
+ res = re.search(br'\sSONAME\s+([^\s]+)', dump)
if not res:
return None
return res.group(1)
@@ -151,23 +156,30 @@
def _num_version(libname):
# "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
- parts = libname.split(".")
+ parts = libname.split(b".")
nums = []
try:
while parts:
nums.insert(0, int(parts.pop()))
except ValueError:
pass
- return nums or [ sys.maxint ]
+ return nums or [sys.maxint]
def find_library(name):
ename = re.escape(name)
expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
- f = os.popen('/sbin/ldconfig -r 2>/dev/null')
+
+ null = open(os.devnull, 'wb')
try:
- data = f.read()
- finally:
- f.close()
+ with null:
+ proc = subprocess.Popen(('/sbin/ldconfig', '-r'),
+ stdout=subprocess.PIPE,
+ stderr=null)
+ except OSError: # E.g. command not found
+ data = b''
+ else:
+ [data, _] = proc.communicate()
+
res = re.findall(expr, data)
if not res:
return _get_soname(_findLib_gcc(name))
@@ -180,16 +192,32 @@
if not os.path.exists('/usr/bin/crle'):
return None
+ env = dict(os.environ)
+ env['LC_ALL'] = 'C'
+
if is64:
- cmd = 'env LC_ALL=C /usr/bin/crle -64 2>/dev/null'
+ args = ('/usr/bin/crle', '-64')
else:
- cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null'
+ args = ('/usr/bin/crle',)
paths = None
- for line in os.popen(cmd).readlines():
- line = line.strip()
- if line.startswith('Default Library Path (ELF):'):
- paths = line.split()[4]
+ null = open(os.devnull, 'wb')
+ try:
+ with null:
+ proc = subprocess.Popen(args,
+ stdout=subprocess.PIPE,
+ stderr=null,
+ env=env)
+ except OSError: # E.g. bad executable
+ return None
+ try:
+ for line in proc.stdout:
+ line = line.strip()
+ if line.startswith(b'Default Library Path (ELF):'):
+ paths = line.split()[4]
+ finally:
+ proc.stdout.close()
+ proc.wait()
if not paths:
return None
@@ -223,11 +251,20 @@
# XXX assuming GLIBC's ldconfig (with option -p)
expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type)
- f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null')
+
+ env = dict(os.environ)
+ env['LC_ALL'] = 'C'
+ env['LANG'] = 'C'
+ null = open(os.devnull, 'wb')
try:
- data = f.read()
- finally:
- f.close()
+ with null:
+ p = subprocess.Popen(['/sbin/ldconfig', '-p'],
+ stderr=null,
+ stdout=subprocess.PIPE,
+ env=env)
+ except OSError: # E.g. command not found
+ return None
+ [data, _] = p.communicate()
res = re.search(expr, data)
if not res:
return None
diff --git a/Lib/curses/ascii.py b/Lib/curses/ascii.py
index 800fd8b..6a466e0 100644
--- a/Lib/curses/ascii.py
+++ b/Lib/curses/ascii.py
@@ -54,13 +54,13 @@
def isalnum(c): return isalpha(c) or isdigit(c)
def isalpha(c): return isupper(c) or islower(c)
def isascii(c): return _ctoi(c) <= 127 # ?
-def isblank(c): return _ctoi(c) in (8,32)
-def iscntrl(c): return _ctoi(c) <= 31
+def isblank(c): return _ctoi(c) in (9, 32)
+def iscntrl(c): return _ctoi(c) <= 31 or _ctoi(c) == 127
def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57
def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126
def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122
def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126
-def ispunct(c): return _ctoi(c) != 32 and not isalnum(c)
+def ispunct(c): return isgraph(c) and not isalnum(c)
def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32)
def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90
def isxdigit(c): return isdigit(c) or \
diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py
index e0f6907..b4866dd 100644
--- a/Lib/idlelib/configDialog.py
+++ b/Lib/idlelib/configDialog.py
@@ -767,6 +767,7 @@
if not tkMessageBox.askyesno(
'Delete Key Set', delmsg % keySetName, parent=self):
return
+ self.DeactivateCurrentConfig()
#remove key set from config
idleConf.userCfg['keys'].remove_section(keySetName)
if keySetName in self.changedItems['keys']:
@@ -785,7 +786,8 @@
self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
#user can't back out of these changes, they must be applied now
- self.Apply()
+ self.SaveAllChangedConfigs()
+ self.ActivateConfigChanges()
self.SetKeysType()
def DeleteCustomTheme(self):
@@ -794,6 +796,7 @@
if not tkMessageBox.askyesno(
'Delete Theme', delmsg % themeName, parent=self):
return
+ self.DeactivateCurrentConfig()
#remove theme from config
idleConf.userCfg['highlight'].remove_section(themeName)
if themeName in self.changedItems['highlight']:
@@ -812,7 +815,8 @@
self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
#user can't back out of these changes, they must be applied now
- self.Apply()
+ self.SaveAllChangedConfigs()
+ self.ActivateConfigChanges()
self.SetThemeType()
def GetColour(self):
diff --git a/Lib/lib-tk/test/test_ttk/test_widgets.py b/Lib/lib-tk/test/test_ttk/test_widgets.py
index f874a9c..a84960d 100644
--- a/Lib/lib-tk/test/test_ttk/test_widgets.py
+++ b/Lib/lib-tk/test/test_ttk/test_widgets.py
@@ -2,7 +2,7 @@
import Tkinter as tkinter
from Tkinter import TclError
import ttk
-from test.test_support import requires, run_unittest
+from test.test_support import requires, run_unittest, have_unicode, u
import sys
from test_functions import MockTclObj
@@ -1486,6 +1486,60 @@
value)
+ def test_selection(self):
+ # item 'none' doesn't exist
+ self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none')
+ self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none')
+ self.assertRaises(tkinter.TclError, self.tv.selection_remove, 'none')
+ self.assertRaises(tkinter.TclError, self.tv.selection_toggle, 'none')
+
+ item1 = self.tv.insert('', 'end')
+ item2 = self.tv.insert('', 'end')
+ c1 = self.tv.insert(item1, 'end')
+ c2 = self.tv.insert(item1, 'end')
+ c3 = self.tv.insert(item1, 'end')
+ self.assertEqual(self.tv.selection(), ())
+
+ self.tv.selection_set((c1, item2))
+ self.assertEqual(self.tv.selection(), (c1, item2))
+ self.tv.selection_set(c2)
+ self.assertEqual(self.tv.selection(), (c2,))
+
+ self.tv.selection_add((c1, item2))
+ self.assertEqual(self.tv.selection(), (c1, c2, item2))
+ self.tv.selection_add(item1)
+ self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
+
+ self.tv.selection_remove((item1, c3))
+ self.assertEqual(self.tv.selection(), (c1, c2, item2))
+ self.tv.selection_remove(c2)
+ self.assertEqual(self.tv.selection(), (c1, item2))
+
+ self.tv.selection_toggle((c1, c3))
+ self.assertEqual(self.tv.selection(), (c3, item2))
+ self.tv.selection_toggle(item2)
+ self.assertEqual(self.tv.selection(), (c3,))
+
+ self.tv.insert('', 'end', id='with spaces')
+ self.tv.selection_set('with spaces')
+ self.assertEqual(self.tv.selection(), ('with spaces',))
+
+ self.tv.insert('', 'end', id='{brace')
+ self.tv.selection_set('{brace')
+ self.assertEqual(self.tv.selection(), ('{brace',))
+
+ if have_unicode:
+ self.tv.insert('', 'end', id=u(r'unicode\u20ac'))
+ self.tv.selection_set(u(r'unicode\u20ac'))
+ self.assertEqual(self.tv.selection(), (u(r'unicode\u20ac'),))
+
+ self.tv.insert('', 'end', id='bytes\xe2\x82\xac')
+ self.tv.selection_set('bytes\xe2\x82\xac')
+ self.assertEqual(self.tv.selection(),
+ (u(r'bytes\u20ac') if have_unicode else
+ 'bytes\xe2\x82\xac',))
+
+
def test_set(self):
self.tv['columns'] = ['A', 'B']
item = self.tv.insert('', 'end', values=['a', 'b'])
@@ -1612,5 +1666,9 @@
SizegripTest, TreeviewTest, WidgetTest,
)
+tests_gui = (
+ TreeviewTest,
+ )
+
if __name__ == "__main__":
run_unittest(*tests_gui)
diff --git a/Lib/lib-tk/ttk.py b/Lib/lib-tk/ttk.py
index f7d0433..3f6f79b 100644
--- a/Lib/lib-tk/ttk.py
+++ b/Lib/lib-tk/ttk.py
@@ -1394,7 +1394,9 @@
def selection(self, selop=None, items=None):
"""If selop is not specified, returns selected items."""
- return self.tk.call(self._w, "selection", selop, items)
+ if isinstance(items, basestring):
+ items = (items,)
+ return self.tk.splitlist(self.tk.call(self._w, "selection", selop, items))
def selection_set(self, items):
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index 73a7590..635f48d 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -192,7 +192,7 @@
continue
try:
key, value = line.split("=")
- except:
+ except ValueError:
print "Bad line in config-file %s:\n%s" % (filename,line)
continue
key = key.strip()
@@ -205,7 +205,7 @@
value = float(value)
else:
value = int(value)
- except:
+ except ValueError:
pass # value need not be converted
cfgdict[key] = value
return cfgdict
@@ -234,7 +234,7 @@
try:
head, tail = split(__file__)
cfg_file2 = join(head, default_cfg)
- except:
+ except BaseException:
cfg_file2 = ""
if isfile(cfg_file2):
#print "2. Loading config-file %s:" % cfg_file2
@@ -249,7 +249,7 @@
try:
readconfig(_CFG)
-except:
+except BaseException:
print "No configfile read, reason unknown"
@@ -677,7 +677,7 @@
x, y = (self.cv.canvasx(event.x)/self.xscale,
-self.cv.canvasy(event.y)/self.yscale)
fun(x, y)
- except:
+ except BaseException:
pass
self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
@@ -1105,7 +1105,7 @@
raise TurtleGraphicsError("bad color string: %s" % str(color))
try:
r, g, b = color
- except:
+ except (TypeError, ValueError):
raise TurtleGraphicsError("bad color arguments: %s" % str(color))
if self._colormode == 1.0:
r, g, b = [round(255.0*x) for x in (r, g, b)]
@@ -2606,7 +2606,7 @@
return args
try:
r, g, b = args
- except:
+ except (TypeError, ValueError):
raise TurtleGraphicsError("bad color arguments: %s" % str(args))
if self.screen._colormode == 1.0:
r, g, b = [round(255.0*x) for x in (r, g, b)]
@@ -3755,7 +3755,7 @@
#print key
try:
eval(key).im_func.__doc__ = docsdict[key]
- except:
+ except BaseException:
print "Bad docstring-entry: %s" % key
_LANGUAGE = _CFG["language"]
@@ -3765,7 +3765,7 @@
read_docstrings(_LANGUAGE)
except ImportError:
print "Cannot find docsdict for", _LANGUAGE
-except:
+except BaseException:
print ("Unknown Error when trying to import %s-docstring-dictionary" %
_LANGUAGE)
diff --git a/Lib/lib2to3/tests/test_refactor.py b/Lib/lib2to3/tests/test_refactor.py
index 7fc84e2..c737aa5 100644
--- a/Lib/lib2to3/tests/test_refactor.py
+++ b/Lib/lib2to3/tests/test_refactor.py
@@ -8,6 +8,7 @@
import os
import codecs
import operator
+import re
import StringIO
import tempfile
import shutil
@@ -226,8 +227,8 @@
actually_write=False)
# Testing that it logged this message when write=False was passed is
# sufficient to see that it did not bail early after "No changes".
- message_regex = r"Not writing changes to .*%s%s" % (
- os.sep, os.path.basename(test_file))
+ message_regex = r"Not writing changes to .*%s" % \
+ re.escape(os.sep + os.path.basename(test_file))
for message in debug_messages:
if "Not writing changes" in message:
self.assertRegexpMatches(message, message_regex)
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 9316fff..b4b190f 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -28,7 +28,7 @@
Module docs for core modules are assumed to be in
- http://docs.python.org/library/
+ https://docs.python.org/library/
This can be overridden by setting the PYTHONDOCS environment variable
to a different URL or to a local directory containing the Library
@@ -374,7 +374,9 @@
docmodule = docclass = docroutine = docother = docproperty = docdata = fail
- def getdocloc(self, object):
+ def getdocloc(self, object,
+ basedir=os.path.join(sys.exec_prefix, "lib",
+ "python"+sys.version[0:3])):
"""Return the location of module docs or None"""
try:
@@ -383,9 +385,8 @@
file = '(built-in)'
docloc = os.environ.get("PYTHONDOCS",
- "http://docs.python.org/library")
- basedir = os.path.join(sys.exec_prefix, "lib",
- "python"+sys.version[0:3])
+ "https://docs.python.org/library")
+ basedir = os.path.normcase(basedir)
if (isinstance(object, type(os)) and
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
'marshal', 'posix', 'signal', 'sys',
@@ -393,10 +394,10 @@
(file.startswith(basedir) and
not file.startswith(os.path.join(basedir, 'site-packages')))) and
object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
- if docloc.startswith("http://"):
- docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__)
+ if docloc.startswith(("http://", "https://")):
+ docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
else:
- docloc = os.path.join(docloc, object.__name__ + ".html")
+ docloc = os.path.join(docloc, object.__name__.lower() + ".html")
else:
docloc = None
return docloc
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index c9abfe3..e08fe12 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -10,6 +10,7 @@
#
import os
+import string
import sys
import tempfile
import unittest
@@ -324,6 +325,53 @@
class TestAscii(unittest.TestCase):
+ def test_controlnames(self):
+ for name in curses.ascii.controlnames:
+ self.assertTrue(hasattr(curses.ascii, name), name)
+
+ def test_ctypes(self):
+ def check(func, expected):
+ self.assertEqual(func(i), expected)
+ self.assertEqual(func(c), expected)
+
+ for i in range(256):
+ c = b = chr(i)
+ check(curses.ascii.isalnum, b.isalnum())
+ check(curses.ascii.isalpha, b.isalpha())
+ check(curses.ascii.isdigit, b.isdigit())
+ check(curses.ascii.islower, b.islower())
+ check(curses.ascii.isspace, b.isspace())
+ check(curses.ascii.isupper, b.isupper())
+
+ check(curses.ascii.isascii, i < 128)
+ check(curses.ascii.ismeta, i >= 128)
+ check(curses.ascii.isctrl, i < 32)
+ check(curses.ascii.iscntrl, i < 32 or i == 127)
+ check(curses.ascii.isblank, c in ' \t')
+ check(curses.ascii.isgraph, 32 < i <= 126)
+ check(curses.ascii.isprint, 32 <= i <= 126)
+ check(curses.ascii.ispunct, c in string.punctuation)
+ check(curses.ascii.isxdigit, c in string.hexdigits)
+
+ def test_ascii(self):
+ ascii = curses.ascii.ascii
+ self.assertEqual(ascii('\xc1'), 'A')
+ self.assertEqual(ascii('A'), 'A')
+ self.assertEqual(ascii(ord('\xc1')), ord('A'))
+
+ def test_ctrl(self):
+ ctrl = curses.ascii.ctrl
+ self.assertEqual(ctrl('J'), '\n')
+ self.assertEqual(ctrl('\n'), '\n')
+ self.assertEqual(ctrl('@'), '\0')
+ self.assertEqual(ctrl(ord('J')), ord('\n'))
+
+ def test_alt(self):
+ alt = curses.ascii.alt
+ self.assertEqual(alt('\n'), '\x8a')
+ self.assertEqual(alt('A'), '\xc1')
+ self.assertEqual(alt(ord('A')), 0xc1)
+
def test_unctrl(self):
unctrl = curses.ascii.unctrl
self.assertEqual(unctrl('a'), 'a')
@@ -333,9 +381,13 @@
self.assertEqual(unctrl('\x7f'), '^?')
self.assertEqual(unctrl('\n'), '^J')
self.assertEqual(unctrl('\0'), '^@')
+ self.assertEqual(unctrl(ord('A')), 'A')
+ self.assertEqual(unctrl(ord('\n')), '^J')
# Meta-bit characters
self.assertEqual(unctrl('\x8a'), '!^J')
self.assertEqual(unctrl('\xc1'), '!A')
+ self.assertEqual(unctrl(ord('\x8a')), '!^J')
+ self.assertEqual(unctrl(ord('\xc1')), '!A')
def test_main():
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 69176f4..62d6029 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -38,17 +38,17 @@
class TestPartial(unittest.TestCase):
- thetype = functools.partial
+ partial = functools.partial
def test_basic_examples(self):
- p = self.thetype(capture, 1, 2, a=10, b=20)
+ p = self.partial(capture, 1, 2, a=10, b=20)
self.assertEqual(p(3, 4, b=30, c=40),
((1, 2, 3, 4), dict(a=10, b=30, c=40)))
- p = self.thetype(map, lambda x: x*10)
+ p = self.partial(map, lambda x: x*10)
self.assertEqual(p([1,2,3,4]), [10, 20, 30, 40])
def test_attributes(self):
- p = self.thetype(capture, 1, 2, a=10, b=20)
+ p = self.partial(capture, 1, 2, a=10, b=20)
# attributes should be readable
self.assertEqual(p.func, capture)
self.assertEqual(p.args, (1, 2))
@@ -58,7 +58,7 @@
self.assertRaises(TypeError, setattr, p, 'args', (1, 2))
self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2))
- p = self.thetype(hex)
+ p = self.partial(hex)
try:
del p.__dict__
except TypeError:
@@ -67,9 +67,9 @@
self.fail('partial object allowed __dict__ to be deleted')
def test_argument_checking(self):
- self.assertRaises(TypeError, self.thetype) # need at least a func arg
+ self.assertRaises(TypeError, self.partial) # need at least a func arg
try:
- self.thetype(2)()
+ self.partial(2)()
except TypeError:
pass
else:
@@ -80,7 +80,7 @@
def func(a=10, b=20):
return a
d = {'a':3}
- p = self.thetype(func, a=5)
+ p = self.partial(func, a=5)
self.assertEqual(p(**d), 3)
self.assertEqual(d, {'a':3})
p(b=7)
@@ -89,21 +89,21 @@
def test_arg_combinations(self):
# exercise special code paths for zero args in either partial
# object or the caller
- p = self.thetype(capture)
+ p = self.partial(capture)
self.assertEqual(p(), ((), {}))
self.assertEqual(p(1,2), ((1,2), {}))
- p = self.thetype(capture, 1, 2)
+ p = self.partial(capture, 1, 2)
self.assertEqual(p(), ((1,2), {}))
self.assertEqual(p(3,4), ((1,2,3,4), {}))
def test_kw_combinations(self):
# exercise special code paths for no keyword args in
# either the partial object or the caller
- p = self.thetype(capture)
+ p = self.partial(capture)
self.assertEqual(p.keywords, {})
self.assertEqual(p(), ((), {}))
self.assertEqual(p(a=1), ((), {'a':1}))
- p = self.thetype(capture, a=1)
+ p = self.partial(capture, a=1)
self.assertEqual(p.keywords, {'a':1})
self.assertEqual(p(), ((), {'a':1}))
self.assertEqual(p(b=2), ((), {'a':1, 'b':2}))
@@ -113,7 +113,7 @@
def test_positional(self):
# make sure positional arguments are captured correctly
for args in [(), (0,), (0,1), (0,1,2), (0,1,2,3)]:
- p = self.thetype(capture, *args)
+ p = self.partial(capture, *args)
expected = args + ('x',)
got, empty = p('x')
self.assertTrue(expected == got and empty == {})
@@ -121,14 +121,14 @@
def test_keyword(self):
# make sure keyword arguments are captured correctly
for a in ['a', 0, None, 3.5]:
- p = self.thetype(capture, a=a)
+ p = self.partial(capture, a=a)
expected = {'a':a,'x':None}
empty, got = p(x=None)
self.assertTrue(expected == got and empty == ())
def test_no_side_effects(self):
# make sure there are no side effects that affect subsequent calls
- p = self.thetype(capture, 0, a=1)
+ p = self.partial(capture, 0, a=1)
args1, kw1 = p(1, b=2)
self.assertTrue(args1 == (0,1) and kw1 == {'a':1,'b':2})
args2, kw2 = p()
@@ -137,13 +137,13 @@
def test_error_propagation(self):
def f(x, y):
x // y
- self.assertRaises(ZeroDivisionError, self.thetype(f, 1, 0))
- self.assertRaises(ZeroDivisionError, self.thetype(f, 1), 0)
- self.assertRaises(ZeroDivisionError, self.thetype(f), 1, 0)
- self.assertRaises(ZeroDivisionError, self.thetype(f, y=0), 1)
+ self.assertRaises(ZeroDivisionError, self.partial(f, 1, 0))
+ self.assertRaises(ZeroDivisionError, self.partial(f, 1), 0)
+ self.assertRaises(ZeroDivisionError, self.partial(f), 1, 0)
+ self.assertRaises(ZeroDivisionError, self.partial(f, y=0), 1)
def test_weakref(self):
- f = self.thetype(int, base=16)
+ f = self.partial(int, base=16)
p = proxy(f)
self.assertEqual(f.func, p.func)
f = None
@@ -151,20 +151,20 @@
def test_with_bound_and_unbound_methods(self):
data = map(str, range(10))
- join = self.thetype(str.join, '')
+ join = self.partial(str.join, '')
self.assertEqual(join(data), '0123456789')
- join = self.thetype(''.join)
+ join = self.partial(''.join)
self.assertEqual(join(data), '0123456789')
def test_pickle(self):
- f = self.thetype(signature, ['asdf'], bar=[True])
+ f = self.partial(signature, ['asdf'], bar=[True])
f.attr = []
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
f_copy = pickle.loads(pickle.dumps(f, proto))
self.assertEqual(signature(f_copy), signature(f))
def test_copy(self):
- f = self.thetype(signature, ['asdf'], bar=[True])
+ f = self.partial(signature, ['asdf'], bar=[True])
f.attr = []
f_copy = copy.copy(f)
self.assertEqual(signature(f_copy), signature(f))
@@ -173,7 +173,7 @@
self.assertIs(f_copy.keywords, f.keywords)
def test_deepcopy(self):
- f = self.thetype(signature, ['asdf'], bar=[True])
+ f = self.partial(signature, ['asdf'], bar=[True])
f.attr = []
f_copy = copy.deepcopy(f)
self.assertEqual(signature(f_copy), signature(f))
@@ -184,7 +184,7 @@
self.assertIsNot(f_copy.keywords['bar'], f.keywords['bar'])
def test_setstate(self):
- f = self.thetype(signature)
+ f = self.partial(signature)
f.__setstate__((capture, (1,), dict(a=10), dict(attr=[])))
self.assertEqual(signature(f),
(capture, (1,), dict(a=10), dict(attr=[])))
@@ -207,7 +207,7 @@
self.assertEqual(f(), ((), {}))
def test_setstate_errors(self):
- f = self.thetype(signature)
+ f = self.partial(signature)
self.assertRaises(TypeError, f.__setstate__, (capture, (), {}))
self.assertRaises(TypeError, f.__setstate__, (capture, (), {}, {}, None))
self.assertRaises(TypeError, f.__setstate__, [capture, (), {}, None])
@@ -217,7 +217,7 @@
self.assertRaises(TypeError, f.__setstate__, (capture, (), [], None))
def test_setstate_subclasses(self):
- f = self.thetype(signature)
+ f = self.partial(signature)
f.__setstate__((capture, MyTuple((1,)), MyDict(a=10), None))
s = signature(f)
self.assertEqual(s, (capture, (1,), dict(a=10), {}))
@@ -236,6 +236,40 @@
self.assertEqual(r, ((1, 2), {}))
self.assertIs(type(r[0]), tuple)
+ def test_recursive_pickle(self):
+ f = self.partial(capture)
+ f.__setstate__((f, (), {}, {}))
+ try:
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.assertRaises(RuntimeError):
+ pickle.dumps(f, proto)
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
+ f = self.partial(capture)
+ f.__setstate__((capture, (f,), {}, {}))
+ try:
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ f_copy = pickle.loads(pickle.dumps(f, proto))
+ try:
+ self.assertIs(f_copy.args[0], f_copy)
+ finally:
+ f_copy.__setstate__((capture, (), {}, {}))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
+ f = self.partial(capture)
+ f.__setstate__((capture, (), {'a': f}, {}))
+ try:
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ f_copy = pickle.loads(pickle.dumps(f, proto))
+ try:
+ self.assertIs(f_copy.keywords['a'], f_copy)
+ finally:
+ f_copy.__setstate__((capture, (), {}, {}))
+ finally:
+ f.__setstate__((capture, (), {}, {}))
+
# Issue 6083: Reference counting bug
def test_setstate_refcount(self):
class BadSequence:
@@ -250,7 +284,7 @@
return {}
raise IndexError
- f = self.thetype(object)
+ f = self.partial(object)
self.assertRaises(TypeError, f.__setstate__, BadSequence())
class PartialSubclass(functools.partial):
@@ -258,11 +292,11 @@
class TestPartialSubclass(TestPartial):
- thetype = PartialSubclass
+ partial = PartialSubclass
class TestPythonPartial(TestPartial):
- thetype = PythonPartial
+ partial = PythonPartial
# the python version isn't picklable
test_pickle = None
@@ -270,6 +304,7 @@
test_setstate_errors = None
test_setstate_subclasses = None
test_setstate_refcount = None
+ test_recursive_pickle = None
# the python version isn't deepcopyable
test_deepcopy = None
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 6cfe7e7..7188d0a 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -13,6 +13,7 @@
import xml.etree
import types
import test.test_support
+import xml.etree.ElementTree
from collections import namedtuple
from test.script_helper import assert_python_ok
from test.test_support import (TESTFN, rmtree, reap_children, captured_stdout,
@@ -253,6 +254,14 @@
loc = "<br><a href=\"" + loc + "\">Module Docs</a>"
return output.strip(), loc
+def get_pydoc_link(module):
+ "Returns a documentation web link of a module"
+ dirname = os.path.dirname
+ basedir = dirname(dirname(__file__))
+ doc = pydoc.TextDoc()
+ loc = doc.getdocloc(module, basedir=basedir)
+ return loc
+
def get_pydoc_text(module):
"Returns pydoc generated output as text"
doc = pydoc.TextDoc()
@@ -331,6 +340,11 @@
print_diffs(expected_text, result)
self.fail("outputs are not equal, see diff above")
+ def test_mixed_case_module_names_are_lower_cased(self):
+ # issue16484
+ doc_link = get_pydoc_link(xml.etree.ElementTree)
+ self.assertIn('xml.etree.elementtree', doc_link)
+
def test_issue8225(self):
# Test issue8225 to ensure no doc link appears for xml.etree
result, doc_loc = get_pydoc_text(xml.etree)
diff --git a/Mac/IDLE/idlemain.py b/Mac/IDLE/idlemain.py
index 8b8beb9..986760d 100644
--- a/Mac/IDLE/idlemain.py
+++ b/Mac/IDLE/idlemain.py
@@ -68,8 +68,6 @@
break
# Now it is safe to import idlelib.
-from idlelib import macosxSupport
-macosxSupport._appbundle = True
from idlelib.PyShell import main
if __name__ == '__main__':
main()
diff --git a/Misc/ACKS b/Misc/ACKS
index ee3a465..5566f1f 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -965,6 +965,7 @@
R. David Murray
Matti Mäki
Jörg Müller
+Kaushik N
Dale Nagata
John Nagle
Takahiro Nakayama
@@ -1553,5 +1554,6 @@
Cheng Zhang
Kai Zhu
Tarek Ziadé
+Jelle Zijlstra
Gennadiy Zlobin
Peter Åstrand
diff --git a/Misc/NEWS b/Misc/NEWS
index 3cf805d..aa2563e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,39 @@
Python News
+++++++++++
+What's New in Python 2.7.13?
+============================
+
+*Release date: XXXX-XX-XX*
+
+Core and Builtins
+-----------------
+
+Library
+-------
+
+- Issue #27079: Fixed curses.ascii functions isblank(), iscntrl() and ispunct().
+
+- Issue #22636: Avoid shell injection problems with
+ ctypes.util.find_library().
+
+- Issue #27330: Fixed possible leaks in the ctypes module.
+
+- Issue #27238: Got rid of bare excepts in the turtle module. Original patch
+ by Jelle Zijlstra.
+
+- Issue #26386: Fixed ttk.TreeView selection operations with item id's
+ containing spaces.
+
+- Issue #25455: Fixed a crash in repr of cElementTree.Element with recursive tag.
+
+Documentation
+-------------
+
+- Issue #16484: Change the default PYTHONDOCS URL to "https:", and fix the
+ resulting links to use lowercase. Patch by Sean Rodman, test by Kaushik
+ Nadikuditi.
+
What's New in Python 2.7.12?
============================
@@ -4541,7 +4574,7 @@
- Issue #11450: Don't truncate hg version info in Py_GetBuildInfo() when
there are many tags (e.g. when using mq). Patch by Nadeem Vawda.
-- Issue #10451: memoryview objects could allow to mutate a readable buffer.
+- Issue #10451: memoryview objects could allow mutating a readable buffer.
Initial patch by Ross Lagerwall.
- Issue #10892: Don't segfault when trying to delete __abstractmethods__ from a
@@ -4610,7 +4643,7 @@
seeking a bit forward, writing, then seeking before the previous write but
still within buffered data, and writing again).
-- Issue #8498: In socket.accept(), allow to specify 0 as a backlog value in
+- Issue #8498: In socket.accept(), allow specifying 0 as a backlog value in
order to accept exactly one connection. Patch by Daniel Evers.
- Issue #12012: ssl.PROTOCOL_SSLv2 becomes optional.
@@ -6071,8 +6104,8 @@
- Build the ossaudio extension on GNU/kFreeBSD.
-- On Windows, ctypes does no longer check the stack before and after calling a
- foreign function. This allows to use the unmodified libffi library.
+- On Windows, ctypes no longer checks the stack before and after calling a
+ foreign function. This allows using the unmodified libffi library.
Tests
-----
@@ -9407,8 +9440,7 @@
- The mimetools module has been deprecated for removal in 3.0.
- The ctypes.byref function now takes an optional second parameter
- which allows to specify an offset in bytes for the constructed
- pointer-like object.
+ which specifies an offset in bytes for the constructed pointer-like object.
- Added the ast module.
@@ -11033,7 +11065,7 @@
-- the failure just occurred later, with a more cumbersome
exception.
-- Patch #787789: allow to pass custom TestRunner instances to
+- Patch #787789: allow passing custom TestRunner instances to
unittest's main() function.
- Patches #1550273, #1550272: fix a few bugs in unittest and add a
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 86208e2..b7e47fa 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1174,7 +1174,7 @@
static PyObject *
CharArray_get_value(CDataObject *self)
{
- int i;
+ Py_ssize_t i;
char *ptr = self->b_ptr;
for (i = 0; i < self->b_size; ++i)
if (*ptr++ == '\0')
@@ -1236,9 +1236,9 @@
static PyObject *
WCharArray_get_value(CDataObject *self)
{
- unsigned int i;
+ Py_ssize_t i;
wchar_t *ptr = (wchar_t *)self->b_ptr;
- for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
+ for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i)
if (*ptr++ == (wchar_t)0)
break;
return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
@@ -1267,7 +1267,7 @@
return -1;
} else
Py_INCREF(value);
- if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
+ if ((size_t)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
PyErr_SetString(PyExc_ValueError,
"string too long");
result = -1;
@@ -1308,8 +1308,10 @@
descr = PyDescr_NewMethod(type, meth);
if (descr == NULL)
return -1;
- if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
+ if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) {
+ Py_DECREF(descr);
return -1;
+ }
Py_DECREF(descr);
}
return 0;
@@ -1324,8 +1326,10 @@
descr = PyDescr_NewMember(type, memb);
if (descr == NULL)
return -1;
- if (PyDict_SetItemString(dict, memb->name, descr) < 0)
+ if (PyDict_SetItemString(dict, memb->name, descr) < 0) {
+ Py_DECREF(descr);
return -1;
+ }
Py_DECREF(descr);
}
return 0;
@@ -1341,8 +1345,10 @@
descr = PyDescr_NewGetSet(type, gsp);
if (descr == NULL)
return -1;
- if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
+ if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
+ Py_DECREF(descr);
return -1;
+ }
Py_DECREF(descr);
}
return 0;
@@ -1843,8 +1849,10 @@
Py_INCREF(name);
PyString_Concat(&name, suffix);
- if (name == NULL)
+ if (name == NULL) {
+ Py_DECREF(swapped_args);
return NULL;
+ }
PyTuple_SET_ITEM(swapped_args, 0, name);
for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
@@ -1862,8 +1870,10 @@
stgdict = (StgDictObject *)PyObject_CallObject(
(PyObject *)&PyCStgDict_Type, NULL);
- if (!stgdict) /* XXX leaks result! */
+ if (!stgdict) {
+ Py_DECREF(result);
return NULL;
+ }
stgdict->ffi_type_pointer = *fmt->pffi_type;
stgdict->align = fmt->pffi_type->alignment;
@@ -2045,20 +2055,25 @@
PyObject *meth;
int x;
meth = PyDescr_NewClassMethod(result, ml);
- if (!meth)
+ if (!meth) {
+ Py_DECREF(result);
return NULL;
+ }
#else
#error
PyObject *meth, *func;
int x;
func = PyCFunction_New(ml, NULL);
- if (!func)
+ if (!func) {
+ Py_DECREF(result);
return NULL;
+ }
meth = PyObject_CallFunctionObjArgs(
(PyObject *)&PyClassMethod_Type,
func, NULL);
Py_DECREF(func);
if (!meth) {
+ Py_DECREF(result);
return NULL;
}
#endif
@@ -2241,8 +2256,10 @@
nArgs = PyTuple_GET_SIZE(ob);
converters = PyTuple_New(nArgs);
- if (!converters)
+ if (!converters) {
+ Py_DECREF(ob);
return NULL;
+ }
/* I have to check if this is correct. Using c_char, which has a size
of 1, will be assumed to be pushed as only one byte!
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 280a315..419beb1 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -92,8 +92,10 @@
#define CTYPES_CAPSULE_ERROROBJ "_ctypes/callproc.c error object"
CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(CTYPES_CAPSULE_ERROROBJ)
-#define CTYPES_CAPSULE_WCHAR_T "_ctypes/callproc.c wchar_t buffer from unicode"
+#if defined(CTYPES_UNICODE) && !defined(HAVE_USABLE_WCHAR_T)
+# define CTYPES_CAPSULE_WCHAR_T "_ctypes/callproc.c wchar_t buffer from unicode"
CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(CTYPES_CAPSULE_WCHAR_T)
+#endif
/*
ctypes maintains thread-local storage that has space for two error numbers:
@@ -162,8 +164,10 @@
return NULL;
memset(space, 0, sizeof(int) * 2);
errobj = CAPSULE_NEW(space, CTYPES_CAPSULE_ERROROBJ);
- if (errobj == NULL)
+ if (errobj == NULL) {
+ PyMem_Free(space);
return NULL;
+ }
if (-1 == PyDict_SetItem(dict, error_object_name,
errobj)) {
Py_DECREF(errobj);
@@ -1277,7 +1281,7 @@
PyObject *nameobj;
PyObject *ignored;
HMODULE hMod;
- if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored))
+ if (!PyArg_ParseTuple(args, "S|O:LoadLibrary", &nameobj, &ignored))
return NULL;
#ifdef _UNICODE
name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR));
@@ -1815,6 +1819,10 @@
if (result == NULL)
return result;
key = PyLong_FromVoidPtr(result);
+ if (key == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
} else if (PyType_Check(cls)) {
typ = (PyTypeObject *)cls;
buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1);
diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
index 0585ed2..e033cd5 100644
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -12,8 +12,10 @@
#include "ctypes.h"
-#define CTYPES_CAPSULE_WCHAR_T "_ctypes/cfield.c wchar_t buffer from unicode"
+#if defined(CTYPES_UNICODE) && !defined(HAVE_USABLE_WCHAR_T)
+# define CTYPES_CAPSULE_WCHAR_T "_ctypes/cfield.c wchar_t buffer from unicode"
CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(CTYPES_CAPSULE_WCHAR_T)
+#endif
/******************************************************************/
@@ -48,7 +50,7 @@
{
CFieldObject *self;
PyObject *proto;
- Py_ssize_t size, align, length;
+ Py_ssize_t size, align;
SETFUNC setfunc = NULL;
GETFUNC getfunc = NULL;
StgDictObject *dict;
@@ -102,7 +104,6 @@
}
size = dict->size;
- length = dict->length;
proto = desc;
/* Field descriptors for 'c_char * n' are be scpecial cased to
@@ -1313,7 +1314,7 @@
return NULL;
size = strlen(data);
if (size < length) {
- /* This will copy the leading NUL character
+ /* This will copy the trailing NUL character
* if there is space for it.
*/
++size;
@@ -1508,6 +1509,7 @@
if (value) {
Py_ssize_t size = PyUnicode_GET_SIZE(value);
if ((unsigned) size != size) {
+ Py_DECREF(value);
PyErr_SetString(PyExc_ValueError, "String too long for BSTR");
return NULL;
}
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 6f628a5..df97b5e 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -1222,18 +1222,28 @@
static PyObject*
element_repr(ElementObject* self)
{
- PyObject *repr, *tag;
+ int status;
- tag = PyObject_Repr(self->tag);
- if (!tag)
- return NULL;
+ if (self->tag == NULL)
+ return PyUnicode_FromFormat("<Element at %p>", self);
- repr = PyString_FromFormat("<Element %s at %p>",
- PyString_AS_STRING(tag), self);
+ status = Py_ReprEnter((PyObject *)self);
+ if (status == 0) {
+ PyObject *repr, *tag;
+ tag = PyObject_Repr(self->tag);
+ if (!tag)
+ return NULL;
- Py_DECREF(tag);
-
- return repr;
+ repr = PyString_FromFormat("<Element %s at %p>",
+ PyString_AS_STRING(tag), self);
+ Py_DECREF(tag);
+ return repr;
+ }
+ if (status > 0)
+ PyErr_Format(PyExc_RuntimeError,
+ "reentrant call inside %s.__repr__",
+ Py_TYPE(self)->tp_name);
+ return NULL;
}
static PyObject*
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index 58456a4..2a652b0 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -52,8 +52,8 @@
(size_t)(size) <= UINT_MAX / (size_t)(elemsize))
/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
- making _tkinter correct for this API means to break earlier
- versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
+ making _tkinter correct for this API means breaking earlier
+ versions. USE_COMPAT_CONST allows making _tkinter work with both 8.4 and
earlier versions. Once Tcl releases before 8.4 don't need to be supported
anymore, this should go. */
#define USE_COMPAT_CONST
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index e7fd349..4573637 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -613,7 +613,7 @@
sizeof(_PyDateTime_BaseTime));
if (self == NULL)
return (PyObject *)PyErr_NoMemory();
- PyObject_INIT(self, type);
+ (void)PyObject_INIT(self, type);
return self;
}
@@ -628,7 +628,7 @@
sizeof(_PyDateTime_BaseDateTime));
if (self == NULL)
return (PyObject *)PyErr_NoMemory();
- PyObject_INIT(self, type);
+ (void)PyObject_INIT(self, type);
return self;
}
diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c
index 6a61508..4128387 100644
--- a/Modules/expat/xmlparse.c
+++ b/Modules/expat/xmlparse.c
@@ -2,12 +2,6 @@
See the file COPYING for copying permission.
*/
-#include <stddef.h>
-#include <string.h> /* memset(), memcpy() */
-#include <assert.h>
-#include <limits.h> /* UINT_MAX */
-#include <time.h> /* time() */
-
#define XML_BUILDING_EXPAT 1
#ifdef COMPILED_FROM_DSP
@@ -22,6 +16,12 @@
#include <expat_config.h>
#endif /* ndef COMPILED_FROM_DSP */
+#include <stddef.h>
+#include <string.h> /* memset(), memcpy() */
+#include <assert.h>
+#include <limits.h> /* UINT_MAX */
+#include <time.h> /* time() */
+
#include "ascii.h"
#include "expat.h"
diff --git a/Modules/readline.c b/Modules/readline.c
index 1600cd3..3bb0ac8 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -66,10 +66,11 @@
static int libedit_history_start = 0;
#endif /* __APPLE__ */
+#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
static void
on_completion_display_matches_hook(char **matches,
int num_matches, int max_length);
-
+#endif
/* Memory allocated for rl_completer_word_break_characters
(see issue #17289 for the motivation). */
@@ -774,6 +775,7 @@
/* C function to call the Python completion_display_matches */
+#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
static void
on_completion_display_matches_hook(char **matches,
int num_matches, int max_length)
@@ -816,6 +818,7 @@
#endif
}
+#endif
#ifdef HAVE_RL_RESIZE_TERMINAL
static volatile sig_atomic_t sigwinch_received;
diff --git a/Modules/tkappinit.c b/Modules/tkappinit.c
index c1f97b0..2ed8594 100644
--- a/Modules/tkappinit.c
+++ b/Modules/tkappinit.c
@@ -26,7 +26,9 @@
int
Tcl_AppInit(Tcl_Interp *interp)
{
+#ifdef WITH_MOREBUTTONS
Tk_Window main_window;
+#endif
const char *_tkinter_skip_tk_init;
#ifdef TKINTER_PROTECT_LOADTK
const char *_tkinter_tk_failed;
@@ -111,7 +113,11 @@
return TCL_ERROR;
}
+#ifdef WITH_MOREBUTTONS
main_window = Tk_MainWindow(interp);
+#else
+ Tk_MainWindow(interp);
+#endif
#ifdef TK_AQUA
TkMacOSXInitAppleEvents(interp);
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 636d178..738e613 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -2256,7 +2256,7 @@
im = free_list;
if (im != NULL) {
free_list = (PyMethodObject *)(im->im_self);
- PyObject_INIT(im, &PyMethod_Type);
+ (void)PyObject_INIT(im, &PyMethod_Type);
numfree--;
}
else {
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 9e97d1b..c4e3895 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -239,7 +239,7 @@
op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT(op, &PyComplex_Type);
+ (void)PyObject_INIT(op, &PyComplex_Type);
op->cval = cval;
return (PyObject *) op;
}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 82cb28d..801f286 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -149,7 +149,7 @@
/* Inline PyObject_New */
op = free_list;
free_list = (PyFloatObject *)Py_TYPE(op);
- PyObject_INIT(op, &PyFloat_Type);
+ (void)PyObject_INIT(op, &PyFloat_Type);
op->ob_fval = fval;
return (PyObject *) op;
}
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 654d2fe..41bb074 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -107,7 +107,7 @@
/* Inline PyObject_New */
v = free_list;
free_list = (PyIntObject *)Py_TYPE(v);
- PyObject_INIT(v, &PyInt_Type);
+ (void)PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
return (PyObject *) v;
}
@@ -1466,7 +1466,7 @@
/* PyObject_New is inlined */
v = free_list;
free_list = (PyIntObject *)Py_TYPE(v);
- PyObject_INIT(v, &PyInt_Type);
+ (void)PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
small_ints[ival + NSMALLNEGINTS] = v;
}
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 0b60ca3..c1a99ab 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -20,7 +20,7 @@
op = free_list;
if (op != NULL) {
free_list = (PyCFunctionObject *)(op->m_self);
- PyObject_INIT(op, &PyCFunction_Type);
+ (void)PyObject_INIT(op, &PyCFunction_Type);
numfree--;
}
else {
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index f2db6da..1a04b78 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -88,7 +88,7 @@
op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyString_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyString_Type, size);
op->ob_shash = -1;
op->ob_sstate = SSTATE_NOT_INTERNED;
if (str != NULL)
@@ -143,7 +143,7 @@
op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyString_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyString_Type, size);
op->ob_shash = -1;
op->ob_sstate = SSTATE_NOT_INTERNED;
Py_MEMCPY(op->ob_sval, str, size+1);
@@ -1061,7 +1061,7 @@
op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyString_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyString_Type, size);
op->ob_shash = -1;
op->ob_sstate = SSTATE_NOT_INTERNED;
Py_MEMCPY(op->ob_sval, a->ob_sval, Py_SIZE(a));
@@ -1103,7 +1103,7 @@
op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + nbytes);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyString_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyString_Type, size);
op->ob_shash = -1;
op->ob_sstate = SSTATE_NOT_INTERNED;
op->ob_sval[size] = '\0';
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index cae5118..272a283 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -791,7 +791,7 @@
Py_INCREF(type);
if (type->tp_itemsize == 0)
- PyObject_INIT(obj, type);
+ (void)PyObject_INIT(obj, type);
else
(void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 0b81a3c..ca6628e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -347,7 +347,7 @@
size_t new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
unicode->str = (Py_UNICODE*) PyObject_MALLOC(new_size);
}
- PyObject_INIT(unicode, &PyUnicode_Type);
+ (void)PyObject_INIT(unicode, &PyUnicode_Type);
}
else {
size_t new_size;
diff --git a/Parser/pgen.c b/Parser/pgen.c
index beaf53b..b2f8470 100644
--- a/Parser/pgen.c
+++ b/Parser/pgen.c
@@ -283,6 +283,7 @@
REQ(n, ATOM);
i = n->n_nchildren;
+ (void)i; /* Don't warn about set but unused */
REQN(i, 1);
n = n->n_child;
if (n->n_type == LPAR) {
diff --git a/Python/compile.c b/Python/compile.c
index 51f2874..ba93fb4 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1889,7 +1889,7 @@
attr = PyString_FromStringAndSize(src,
dot ? dot - src : strlen(src));
if (!attr)
- return -1;
+ return 0;
ADDOP_O(c, LOAD_ATTR, attr, names);
Py_DECREF(attr);
src = dot + 1;