Merge.
This commit is contained in:
commit
1b329e791a
1
.hgtags
1
.hgtags
|
@ -146,6 +146,7 @@ ab2c023a9432f16652e89c404bbc84aa91bf55af v3.4.2
|
||||||
b4cbecbc0781e89a309d03b60a1f75f8499250e6 v3.4.3
|
b4cbecbc0781e89a309d03b60a1f75f8499250e6 v3.4.3
|
||||||
04f3f725896c6961212c3a12e8ac25be6958f4fa v3.4.4rc1
|
04f3f725896c6961212c3a12e8ac25be6958f4fa v3.4.4rc1
|
||||||
737efcadf5a678b184e0fa431aae11276bf06648 v3.4.4
|
737efcadf5a678b184e0fa431aae11276bf06648 v3.4.4
|
||||||
|
3631bb4a2490292ebf81d3e947ae36da145da564 v3.4.5rc1
|
||||||
5d4b6a57d5fd7564bf73f3db0e46fe5eeb00bcd8 v3.5.0a1
|
5d4b6a57d5fd7564bf73f3db0e46fe5eeb00bcd8 v3.5.0a1
|
||||||
0337bd7ebcb6559d69679bc7025059ad1ce4f432 v3.5.0a2
|
0337bd7ebcb6559d69679bc7025059ad1ce4f432 v3.5.0a2
|
||||||
82656e28b5e5c4ae48d8dd8b5f0d7968908a82b6 v3.5.0a3
|
82656e28b5e5c4ae48d8dd8b5f0d7968908a82b6 v3.5.0a3
|
||||||
|
|
|
@ -166,7 +166,7 @@ autobuild-dev:
|
||||||
-make suspicious
|
-make suspicious
|
||||||
|
|
||||||
# for quick rebuilds (HTML only)
|
# for quick rebuilds (HTML only)
|
||||||
autobuild-html:
|
autobuild-dev-html:
|
||||||
make html SPHINXOPTS='-A daily=1 -A versionswitcher=1'
|
make html SPHINXOPTS='-A daily=1 -A versionswitcher=1'
|
||||||
|
|
||||||
# for stable releases: only build if not in pre-release stage (alpha, beta)
|
# for stable releases: only build if not in pre-release stage (alpha, beta)
|
||||||
|
@ -177,3 +177,10 @@ autobuild-stable:
|
||||||
exit 1;; \
|
exit 1;; \
|
||||||
esac
|
esac
|
||||||
@make autobuild-dev
|
@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
|
||||||
|
|
|
@ -59,10 +59,10 @@ Module Objects
|
||||||
.. index:: single: __dict__ (module attribute)
|
.. index:: single: __dict__ (module attribute)
|
||||||
|
|
||||||
Return the dictionary object that implements *module*'s namespace; this object
|
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
|
function never fails. It is recommended extensions use other
|
||||||
:c:func:`PyModule_\*` and :c:func:`PyObject_\*` functions rather than directly
|
: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:: PyObject* PyModule_GetNameObject(PyObject *module)
|
.. c:function:: PyObject* PyModule_GetNameObject(PyObject *module)
|
||||||
|
|
|
@ -150,9 +150,8 @@ specific C type of the *self* object.
|
||||||
The :attr:`ml_flags` field is a bitfield which can include the following flags.
|
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
|
The individual flags indicate either a calling convention or a binding
|
||||||
convention. Of the calling convention flags, only :const:`METH_VARARGS` and
|
convention. Of the calling convention flags, only :const:`METH_VARARGS` and
|
||||||
:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS`
|
:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags
|
||||||
alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling
|
can be combined with a binding flag.
|
||||||
convention flags can be combined with a binding flag.
|
|
||||||
|
|
||||||
|
|
||||||
.. data:: METH_VARARGS
|
.. data:: METH_VARARGS
|
||||||
|
|
|
@ -111,10 +111,10 @@ type objects) *must* have the :attr:`ob_size` field.
|
||||||
For statically allocated type objects, the tp_name field should contain a dot.
|
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__`
|
Everything before the last dot is made accessible as the :attr:`__module__`
|
||||||
attribute, and everything after the last dot is made accessible as the
|
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
|
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
|
(unless explicitly set in the dictionary, as explained above). This means your
|
||||||
type will be impossible to pickle.
|
type will be impossible to pickle.
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,7 @@ remember the methods for a list, they can do something like this::
|
||||||
>>> L
|
>>> L
|
||||||
[1]
|
[1]
|
||||||
|
|
||||||
With the interpreter, documentation is never far from the student as he's
|
With the interpreter, documentation is never far from the student as they are
|
||||||
programming.
|
programming.
|
||||||
|
|
||||||
There are also good IDEs for Python. IDLE is a cross-platform IDE for Python
|
There are also good IDEs for Python. IDLE is a cross-platform IDE for Python
|
||||||
|
|
|
@ -374,9 +374,7 @@ module. If you have :mod:`tkinter` available, you may also want to look at
|
||||||
:source:`Tools/demo/redemo.py`, a demonstration program included with the
|
:source:`Tools/demo/redemo.py`, a demonstration program included with the
|
||||||
Python distribution. It allows you to enter REs and strings, and displays
|
Python distribution. It allows you to enter REs and strings, and displays
|
||||||
whether the RE matches or fails. :file:`redemo.py` can be quite useful when
|
whether the RE matches or fails. :file:`redemo.py` can be quite useful when
|
||||||
trying to debug a complicated RE. Phil Schwartz's `Kodos
|
trying to debug a complicated RE.
|
||||||
<http://kodos.sourceforge.net/>`_ is also an interactive tool for developing and
|
|
||||||
testing RE patterns.
|
|
||||||
|
|
||||||
This HOWTO uses the standard Python interpreter for its examples. First, run the
|
This HOWTO uses the standard Python interpreter for its examples. First, run the
|
||||||
Python interpreter, import the :mod:`re` module, and compile a RE::
|
Python interpreter, import the :mod:`re` module, and compile a RE::
|
||||||
|
|
|
@ -37,6 +37,6 @@ that wants to implement an :func:`open` function that wraps the built-in
|
||||||
|
|
||||||
As an implementation detail, most modules have the name ``__builtins__`` made
|
As an implementation detail, most modules have the name ``__builtins__`` made
|
||||||
available as part of their globals. The value of ``__builtins__`` is normally
|
available as part of their globals. The value of ``__builtins__`` is normally
|
||||||
either this module or the value of this module's :attr:`__dict__` attribute.
|
either this module or the value of this module's :attr:`~object.__dict__` attribute.
|
||||||
Since this is an implementation detail, it may not be used by alternate
|
Since this is an implementation detail, it may not be used by alternate
|
||||||
implementations of Python.
|
implementations of Python.
|
||||||
|
|
|
@ -115,12 +115,12 @@ C library:
|
||||||
|
|
||||||
.. function:: isblank(c)
|
.. function:: isblank(c)
|
||||||
|
|
||||||
Checks for an ASCII whitespace character.
|
Checks for an ASCII whitespace character; space or horizontal tab.
|
||||||
|
|
||||||
|
|
||||||
.. function:: iscntrl(c)
|
.. 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)
|
.. function:: isdigit(c)
|
||||||
|
|
|
@ -128,6 +128,9 @@ The individual submodules are described in the following sections.
|
||||||
:platform: Unix
|
:platform: Unix
|
||||||
:synopsis: GNU's reinterpretation of dbm.
|
:synopsis: GNU's reinterpretation of dbm.
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/dbm/gnu.py`
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
This module is quite similar to the :mod:`dbm` module, but uses the GNU library
|
This module is quite similar to the :mod:`dbm` module, but uses the GNU library
|
||||||
``gdbm`` instead to provide some additional functionality. Please note that the
|
``gdbm`` instead to provide some additional functionality. Please note that the
|
||||||
|
@ -237,6 +240,9 @@ supported.
|
||||||
:platform: Unix
|
:platform: Unix
|
||||||
:synopsis: The standard "database" interface, based on ndbm.
|
:synopsis: The standard "database" interface, based on ndbm.
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/dbm/ndbm.py`
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
The :mod:`dbm.ndbm` module provides an interface to the Unix "(n)dbm" library.
|
The :mod:`dbm.ndbm` module provides an interface to the Unix "(n)dbm" library.
|
||||||
Dbm objects behave like mappings (dictionaries), except that keys and values are
|
Dbm objects behave like mappings (dictionaries), except that keys and values are
|
||||||
|
@ -299,6 +305,8 @@ to locate the appropriate header file to simplify building this module.
|
||||||
.. module:: dbm.dumb
|
.. module:: dbm.dumb
|
||||||
:synopsis: Portable implementation of the simple DBM interface.
|
:synopsis: Portable implementation of the simple DBM interface.
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/dbm/dumb.py`
|
||||||
|
|
||||||
.. index:: single: databases
|
.. index:: single: databases
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -308,6 +316,8 @@ to locate the appropriate header file to simplify building this module.
|
||||||
module is not written for speed and is not nearly as heavily used as the other
|
module is not written for speed and is not nearly as heavily used as the other
|
||||||
database modules.
|
database modules.
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
The :mod:`dbm.dumb` module provides a persistent dictionary-like interface which
|
The :mod:`dbm.dumb` module provides a persistent dictionary-like interface which
|
||||||
is written entirely in Python. Unlike other modules such as :mod:`dbm.gnu` no
|
is written entirely in Python. Unlike other modules such as :mod:`dbm.gnu` no
|
||||||
external library is required. As with other persistent mappings, the keys and
|
external library is required. As with other persistent mappings, the keys and
|
||||||
|
|
|
@ -431,7 +431,7 @@ The solution is to specify the module name explicitly as follows::
|
||||||
the source, pickling will be disabled.
|
the source, pickling will be disabled.
|
||||||
|
|
||||||
The new pickle protocol 4 also, in some circumstances, relies on
|
The new pickle protocol 4 also, in some circumstances, relies on
|
||||||
:attr:`__qualname__` being set to the location where pickle will be able
|
:attr:`~definition.__qualname__` being set to the location where pickle will be able
|
||||||
to find the class. For example, if the class was made available in class
|
to find the class. For example, if the class was made available in class
|
||||||
SomeData in the global scope::
|
SomeData in the global scope::
|
||||||
|
|
||||||
|
|
|
@ -304,7 +304,7 @@ are always available. They are listed here in alphabetical order.
|
||||||
:func:`dir` reports their attributes.
|
:func:`dir` reports their attributes.
|
||||||
|
|
||||||
If the object does not provide :meth:`__dir__`, the function tries its best to
|
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
|
from its type object. The resulting list is not necessarily complete, and may
|
||||||
be inaccurate when the object has a custom :func:`__getattr__`.
|
be inaccurate when the object has a custom :func:`__getattr__`.
|
||||||
|
|
||||||
|
@ -1446,7 +1446,7 @@ are always available. They are listed here in alphabetical order.
|
||||||
|
|
||||||
With three arguments, return a new type object. This is essentially a
|
With three arguments, return a new type object. This is essentially a
|
||||||
dynamic form of the :keyword:`class` statement. The *name* string is the
|
dynamic form of the :keyword:`class` statement. The *name* string is the
|
||||||
class name and becomes the :attr:`~class.__name__` attribute; the *bases*
|
class name and becomes the :attr:`~definition.__name__` attribute; the *bases*
|
||||||
tuple itemizes the base classes and becomes the :attr:`~class.__bases__`
|
tuple itemizes the base classes and becomes the :attr:`~class.__bases__`
|
||||||
attribute; and the *dict* dictionary is the namespace containing definitions
|
attribute; and the *dict* dictionary is the namespace containing definitions
|
||||||
for class body and is copied to a standard dictionary to become the
|
for class body and is copied to a standard dictionary to become the
|
||||||
|
@ -1464,12 +1464,12 @@ are always available. They are listed here in alphabetical order.
|
||||||
.. function:: vars([object])
|
.. function:: vars([object])
|
||||||
|
|
||||||
Return the :attr:`~object.__dict__` attribute for a module, class, instance,
|
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
|
attribute; however, other objects may have write restrictions on their
|
||||||
:attr:`__dict__` attributes (for example, classes use a
|
:attr:`~object.__dict__` attributes (for example, classes use a
|
||||||
dictproxy to prevent direct dictionary updates).
|
:class:`types.MappingProxyType` to prevent direct dictionary updates).
|
||||||
|
|
||||||
Without an argument, :func:`vars` acts like :func:`locals`. Note, the
|
Without an argument, :func:`vars` acts like :func:`locals`. Note, the
|
||||||
locals dictionary is only useful for reads since updates to the locals
|
locals dictionary is only useful for reads since updates to the locals
|
||||||
|
|
|
@ -474,7 +474,7 @@ have three read-only attributes:
|
||||||
|
|
||||||
:class:`partial` objects are like :class:`function` objects in that they are
|
:class:`partial` objects are like :class:`function` objects in that they are
|
||||||
callable, weak referencable, and can have attributes. There are some important
|
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
|
are not created automatically. Also, :class:`partial` objects defined in
|
||||||
classes behave like static methods and do not transform into bound methods
|
classes behave like static methods and do not transform into bound methods
|
||||||
during instance attribute look-up.
|
during instance attribute look-up.
|
||||||
|
|
|
@ -211,6 +211,11 @@ Functions
|
||||||
.. module:: importlib.abc
|
.. module:: importlib.abc
|
||||||
:synopsis: Abstract base classes related to import
|
:synopsis: Abstract base classes related to import
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/importlib/abc.py`
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
|
||||||
The :mod:`importlib.abc` module contains all of the core abstract base classes
|
The :mod:`importlib.abc` module contains all of the core abstract base classes
|
||||||
used by :keyword:`import`. Some subclasses of the core abstract base classes
|
used by :keyword:`import`. Some subclasses of the core abstract base classes
|
||||||
are also provided to help in implementing the core ABCs.
|
are also provided to help in implementing the core ABCs.
|
||||||
|
@ -700,6 +705,10 @@ ABC hierarchy::
|
||||||
.. module:: importlib.machinery
|
.. module:: importlib.machinery
|
||||||
:synopsis: Importers and path hooks
|
:synopsis: Importers and path hooks
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/importlib/machinery.py`
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
This module contains the various objects that help :keyword:`import`
|
This module contains the various objects that help :keyword:`import`
|
||||||
find and load modules.
|
find and load modules.
|
||||||
|
|
||||||
|
@ -1082,6 +1091,11 @@ find and load modules.
|
||||||
.. module:: importlib.util
|
.. module:: importlib.util
|
||||||
:synopsis: Utility code for importers
|
:synopsis: Utility code for importers
|
||||||
|
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/importlib/util.py`
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
This module contains the various objects that help in the construction of
|
This module contains the various objects that help in the construction of
|
||||||
an :term:`importer`.
|
an :term:`importer`.
|
||||||
|
|
||||||
|
|
|
@ -374,8 +374,9 @@ attributes:
|
||||||
are true.
|
are true.
|
||||||
|
|
||||||
This, for example, is true of ``int.__add__``. An object passing this test
|
This, for example, is true of ``int.__add__``. An object passing this test
|
||||||
has a :attr:`__get__` attribute but not a :attr:`__set__` attribute, but
|
has a :meth:`~object.__get__` method but not a :meth:`~object.__set__`
|
||||||
beyond that the set of attributes varies. :attr:`__name__` is usually
|
method, but beyond that the set of attributes varies. A
|
||||||
|
:attr:`~definition.__name__` attribute is usually
|
||||||
sensible, and :attr:`__doc__` often is.
|
sensible, and :attr:`__doc__` often is.
|
||||||
|
|
||||||
Methods implemented via descriptors that also pass one of the other tests
|
Methods implemented via descriptors that also pass one of the other tests
|
||||||
|
@ -388,11 +389,11 @@ attributes:
|
||||||
|
|
||||||
Return true if the object is a data descriptor.
|
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
|
Examples are properties (defined in Python), getsets, and members. The
|
||||||
latter two are defined in C and there are more specific tests available for
|
latter two are defined in C and there are more specific tests available for
|
||||||
those types, which is robust across Python implementations. Typically, data
|
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
|
(properties, getsets, and members have both of these attributes), but this is
|
||||||
not guaranteed.
|
not guaranteed.
|
||||||
|
|
||||||
|
|
|
@ -629,13 +629,19 @@ when serializing instances of "exotic" numerical types such as
|
||||||
:class:`decimal.Decimal`.
|
:class:`decimal.Decimal`.
|
||||||
|
|
||||||
.. highlight:: bash
|
.. highlight:: bash
|
||||||
.. module:: json.tool
|
|
||||||
|
|
||||||
.. _json-commandline:
|
.. _json-commandline:
|
||||||
|
|
||||||
Command Line Interface
|
Command Line Interface
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
.. module:: json.tool
|
||||||
|
:synopsis: A command line to validate and pretty-print JSON.
|
||||||
|
|
||||||
|
**Source code:** :source:`Lib/json/tool.py`
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
The :mod:`json.tool` module provides a simple command line interface to validate
|
The :mod:`json.tool` module provides a simple command line interface to validate
|
||||||
and pretty-print JSON objects.
|
and pretty-print JSON objects.
|
||||||
|
|
||||||
|
|
|
@ -1010,7 +1010,7 @@ Connection objects are usually created using :func:`Pipe` -- see also
|
||||||
using :meth:`recv`.
|
using :meth:`recv`.
|
||||||
|
|
||||||
The object must be picklable. Very large pickles (approximately 32 MB+,
|
The object must be picklable. Very large pickles (approximately 32 MB+,
|
||||||
though it depends on the OS) may raise a ValueError exception.
|
though it depends on the OS) may raise a :exc:`ValueError` exception.
|
||||||
|
|
||||||
.. method:: recv()
|
.. method:: recv()
|
||||||
|
|
||||||
|
@ -2723,12 +2723,7 @@ start method.
|
||||||
|
|
||||||
More picklability
|
More picklability
|
||||||
|
|
||||||
Ensure that all arguments to :meth:`Process.__init__` are
|
Ensure that all arguments to :meth:`Process.__init__` are picklable.
|
||||||
picklable. This means, in particular, that bound or unbound
|
|
||||||
methods cannot be used directly as the ``target`` (unless you use
|
|
||||||
the *fork* start method) --- just define a function and use that
|
|
||||||
instead.
|
|
||||||
|
|
||||||
Also, if you subclass :class:`~multiprocessing.Process` then make sure that
|
Also, if you subclass :class:`~multiprocessing.Process` then make sure that
|
||||||
instances will be picklable when the :meth:`Process.start
|
instances will be picklable when the :meth:`Process.start
|
||||||
<multiprocessing.Process.start>` method is called.
|
<multiprocessing.Process.start>` method is called.
|
||||||
|
|
|
@ -1195,7 +1195,11 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
|
||||||
.. function:: writev(fd, buffers)
|
.. function:: writev(fd, buffers)
|
||||||
|
|
||||||
Write the contents of *buffers* to file descriptor *fd*. *buffers* must be a
|
Write the contents of *buffers* to file descriptor *fd*. *buffers* must be a
|
||||||
sequence of :term:`bytes-like objects <bytes-like object>`.
|
sequence of :term:`bytes-like objects <bytes-like object>`. Buffers are
|
||||||
|
processed in array order. Entire contents of first buffer is written before
|
||||||
|
proceeding to second, and so on. The operating system may set a limit
|
||||||
|
(sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
|
||||||
|
|
||||||
:func:`~os.writev` writes the contents of each object to the file descriptor
|
:func:`~os.writev` writes the contents of each object to the file descriptor
|
||||||
and returns the total number of bytes written.
|
and returns the total number of bytes written.
|
||||||
|
|
||||||
|
@ -2049,9 +2053,8 @@ features:
|
||||||
|
|
||||||
Note that there is a nice correspondence between several attributes
|
Note that there is a nice correspondence between several attributes
|
||||||
and methods of ``DirEntry`` and of :class:`pathlib.Path`. In
|
and methods of ``DirEntry`` and of :class:`pathlib.Path`. In
|
||||||
particular, the ``name`` and ``path`` attributes have the same
|
particular, the ``name`` attribute has the same meaning, as do the
|
||||||
meaning, as do the ``is_dir()``, ``is_file()``, ``is_symlink()``
|
``is_dir()``, ``is_file()``, ``is_symlink()`` and ``stat()`` methods.
|
||||||
and ``stat()`` methods.
|
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
|
|
@ -443,7 +443,7 @@ three digits in length.
|
||||||
The ``'\u'`` and ``'\U'`` escape sequences have been added.
|
The ``'\u'`` and ``'\U'`` escape sequences have been added.
|
||||||
|
|
||||||
.. deprecated-removed:: 3.5 3.6
|
.. deprecated-removed:: 3.5 3.6
|
||||||
Unknown escapes consist of ``'\'`` and ASCII letter now raise a
|
Unknown escapes consisting of ``'\'`` and ASCII letter now raise a
|
||||||
deprecation warning and will be forbidden in Python 3.6.
|
deprecation warning and will be forbidden in Python 3.6.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,9 @@ The following functions operate on a history file:
|
||||||
|
|
||||||
Append the last *nelements* items of history to a file. The default filename is
|
Append the last *nelements* items of history to a file. The default filename is
|
||||||
:file:`~/.history`. The file must already exist. This calls
|
:file:`~/.history`. The file must already exist. This calls
|
||||||
:c:func:`append_history` in the underlying library.
|
:c:func:`append_history` in the underlying library. This function
|
||||||
|
only exists if Python was compiled for a version of the library
|
||||||
|
that supports it.
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
@ -185,7 +187,8 @@ Startup hooks
|
||||||
be used as the new hook function; if omitted or ``None``, any
|
be used as the new hook function; if omitted or ``None``, any
|
||||||
function already installed is removed. The hook is called
|
function already installed is removed. The hook is called
|
||||||
with no arguments after the first prompt has been printed and just before
|
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
|
Completion
|
||||||
|
|
|
@ -309,25 +309,26 @@ Connection Objects
|
||||||
call :meth:`commit`. If you just close your database connection without
|
call :meth:`commit`. If you just close your database connection without
|
||||||
calling :meth:`commit` first, your changes will be lost!
|
calling :meth:`commit` first, your changes will be lost!
|
||||||
|
|
||||||
.. method:: execute(sql, [parameters])
|
.. method:: execute(sql[, parameters])
|
||||||
|
|
||||||
This is a nonstandard shortcut that creates an intermediate cursor object by
|
This is a nonstandard shortcut that creates a cursor object by calling
|
||||||
calling the cursor method, then calls the cursor's :meth:`execute
|
the :meth:`~Connection.cursor` method, calls the cursor's
|
||||||
<Cursor.execute>` method with the parameters given.
|
:meth:`~Cursor.execute` method with the *parameters* given, and returns
|
||||||
|
the cursor.
|
||||||
|
|
||||||
|
.. method:: executemany(sql[, parameters])
|
||||||
|
|
||||||
.. method:: executemany(sql, [parameters])
|
This is a nonstandard shortcut that creates a cursor object by
|
||||||
|
calling the :meth:`~Connection.cursor` method, calls the cursor's
|
||||||
This is a nonstandard shortcut that creates an intermediate cursor object by
|
:meth:`~Cursor.executemany` method with the *parameters* given, and
|
||||||
calling the cursor method, then calls the cursor's :meth:`executemany
|
returns the cursor.
|
||||||
<Cursor.executemany>` method with the parameters given.
|
|
||||||
|
|
||||||
.. method:: executescript(sql_script)
|
.. method:: executescript(sql_script)
|
||||||
|
|
||||||
This is a nonstandard shortcut that creates an intermediate cursor object by
|
This is a nonstandard shortcut that creates a cursor object by
|
||||||
calling the cursor method, then calls the cursor's :meth:`executescript
|
calling the :meth:`~Connection.cursor` method, calls the cursor's
|
||||||
<Cursor.executescript>` method with the parameters given.
|
:meth:`~Cursor.executescript` method with the given *sql_script*, and
|
||||||
|
returns the cursor.
|
||||||
|
|
||||||
.. method:: create_function(name, num_params, func)
|
.. method:: create_function(name, num_params, func)
|
||||||
|
|
||||||
|
@ -488,10 +489,6 @@ Connection Objects
|
||||||
:mod:`sqlite3` module will return Unicode objects for ``TEXT``. If you want to
|
:mod:`sqlite3` module will return Unicode objects for ``TEXT``. If you want to
|
||||||
return bytestrings instead, you can set it to :class:`bytes`.
|
return bytestrings instead, you can set it to :class:`bytes`.
|
||||||
|
|
||||||
For efficiency reasons, there's also a way to return :class:`str` objects
|
|
||||||
only for non-ASCII data, and :class:`bytes` otherwise. To activate it, set
|
|
||||||
this attribute to :const:`sqlite3.OptimizedUnicode`.
|
|
||||||
|
|
||||||
You can also set it to any other callable that accepts a single bytestring
|
You can also set it to any other callable that accepts a single bytestring
|
||||||
parameter and returns the resulting object.
|
parameter and returns the resulting object.
|
||||||
|
|
||||||
|
@ -533,7 +530,7 @@ Cursor Objects
|
||||||
|
|
||||||
A :class:`Cursor` instance has the following attributes and methods.
|
A :class:`Cursor` instance has the following attributes and methods.
|
||||||
|
|
||||||
.. method:: execute(sql, [parameters])
|
.. method:: execute(sql[, parameters])
|
||||||
|
|
||||||
Executes an SQL statement. The SQL statement may be parameterized (i. e.
|
Executes an SQL statement. The SQL statement may be parameterized (i. e.
|
||||||
placeholders instead of SQL literals). The :mod:`sqlite3` module supports two
|
placeholders instead of SQL literals). The :mod:`sqlite3` module supports two
|
||||||
|
@ -545,7 +542,7 @@ Cursor Objects
|
||||||
.. literalinclude:: ../includes/sqlite3/execute_1.py
|
.. literalinclude:: ../includes/sqlite3/execute_1.py
|
||||||
|
|
||||||
:meth:`execute` will only execute a single SQL statement. If you try to execute
|
:meth:`execute` will only execute a single SQL statement. If you try to execute
|
||||||
more than one statement with it, it will raise a Warning. Use
|
more than one statement with it, it will raise an ``sqlite3.Warning``. Use
|
||||||
:meth:`executescript` if you want to execute multiple SQL statements with one
|
:meth:`executescript` if you want to execute multiple SQL statements with one
|
||||||
call.
|
call.
|
||||||
|
|
||||||
|
@ -553,8 +550,8 @@ Cursor Objects
|
||||||
.. method:: executemany(sql, seq_of_parameters)
|
.. method:: executemany(sql, seq_of_parameters)
|
||||||
|
|
||||||
Executes an SQL command against all parameter sequences or mappings found in
|
Executes an SQL command against all parameter sequences or mappings found in
|
||||||
the sequence *sql*. The :mod:`sqlite3` module also allows using an
|
the sequence *seq_of_parameters*. The :mod:`sqlite3` module also allows
|
||||||
:term:`iterator` yielding parameters instead of a sequence.
|
using an :term:`iterator` yielding parameters instead of a sequence.
|
||||||
|
|
||||||
.. literalinclude:: ../includes/sqlite3/executemany_1.py
|
.. literalinclude:: ../includes/sqlite3/executemany_1.py
|
||||||
|
|
||||||
|
@ -569,7 +566,7 @@ Cursor Objects
|
||||||
at once. It issues a ``COMMIT`` statement first, then executes the SQL script it
|
at once. It issues a ``COMMIT`` statement first, then executes the SQL script it
|
||||||
gets as a parameter.
|
gets as a parameter.
|
||||||
|
|
||||||
*sql_script* can be an instance of :class:`str` or :class:`bytes`.
|
*sql_script* can be an instance of :class:`str`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
|
@ -4360,9 +4360,10 @@ an (external) *definition* for a module named *foo* somewhere.)
|
||||||
A special attribute of every module is :attr:`~object.__dict__`. This is the
|
A special attribute of every module is :attr:`~object.__dict__`. This is the
|
||||||
dictionary containing the module's symbol table. Modifying this dictionary will
|
dictionary containing the module's symbol table. Modifying this dictionary will
|
||||||
actually change the module's symbol table, but direct assignment to the
|
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__['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'
|
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
|
(built-in)>``. If loaded from a file, they are written as ``<module 'os' from
|
||||||
|
@ -4575,14 +4576,16 @@ types, where they are relevant. Some of these are not reported by the
|
||||||
The tuple of base classes of a class object.
|
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, function, method, descriptor, or
|
||||||
|
generator instance.
|
||||||
|
|
||||||
|
|
||||||
.. attribute:: class.__qualname__
|
.. attribute:: definition.__qualname__
|
||||||
|
|
||||||
The :term:`qualified name` of the class or type.
|
The :term:`qualified name` of the class, function, method, descriptor,
|
||||||
|
or generator instance.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
|
@ -64,19 +64,19 @@ Some facts and figures:
|
||||||
| ``'x'`` or | Create a tarfile exclusively without |
|
| ``'x'`` or | Create a tarfile exclusively without |
|
||||||
| ``'x:'`` | compression. |
|
| ``'x:'`` | compression. |
|
||||||
| | Raise an :exc:`FileExistsError` exception |
|
| | Raise an :exc:`FileExistsError` exception |
|
||||||
| | if it is already exists. |
|
| | if it already exists. |
|
||||||
+------------------+---------------------------------------------+
|
+------------------+---------------------------------------------+
|
||||||
| ``'x:gz'`` | Create a tarfile with gzip compression. |
|
| ``'x:gz'`` | Create a tarfile with gzip compression. |
|
||||||
| | Raise an :exc:`FileExistsError` exception |
|
| | Raise an :exc:`FileExistsError` exception |
|
||||||
| | if it is already exists. |
|
| | if it already exists. |
|
||||||
+------------------+---------------------------------------------+
|
+------------------+---------------------------------------------+
|
||||||
| ``'x:bz2'`` | Create a tarfile with bzip2 compression. |
|
| ``'x:bz2'`` | Create a tarfile with bzip2 compression. |
|
||||||
| | Raise an :exc:`FileExistsError` exception |
|
| | Raise an :exc:`FileExistsError` exception |
|
||||||
| | if it is already exists. |
|
| | if it already exists. |
|
||||||
+------------------+---------------------------------------------+
|
+------------------+---------------------------------------------+
|
||||||
| ``'x:xz'`` | Create a tarfile with lzma compression. |
|
| ``'x:xz'`` | Create a tarfile with lzma compression. |
|
||||||
| | Raise an :exc:`FileExistsError` exception |
|
| | Raise an :exc:`FileExistsError` exception |
|
||||||
| | if it is already exists. |
|
| | if it already exists. |
|
||||||
+------------------+---------------------------------------------+
|
+------------------+---------------------------------------------+
|
||||||
| ``'a' or 'a:'`` | Open for appending with no compression. The |
|
| ``'a' or 'a:'`` | Open for appending with no compression. The |
|
||||||
| | file is created if it does not exist. |
|
| | file is created if it does not exist. |
|
||||||
|
@ -148,8 +148,8 @@ Some facts and figures:
|
||||||
|
|
||||||
.. class:: TarFile
|
.. class:: TarFile
|
||||||
|
|
||||||
Class for reading and writing tar archives. Do not use this class directly,
|
Class for reading and writing tar archives. Do not use this class directly:
|
||||||
better use :func:`tarfile.open` instead. See :ref:`tarfile-objects`.
|
use :func:`tarfile.open` instead. See :ref:`tarfile-objects`.
|
||||||
|
|
||||||
|
|
||||||
.. function:: is_tarfile(name)
|
.. function:: is_tarfile(name)
|
||||||
|
@ -271,7 +271,7 @@ be finalized; only the internally used file object will be closed. See the
|
||||||
|
|
||||||
*mode* is either ``'r'`` to read from an existing archive, ``'a'`` to append
|
*mode* is either ``'r'`` to read from an existing archive, ``'a'`` to append
|
||||||
data to an existing file, ``'w'`` to create a new file overwriting an existing
|
data to an existing file, ``'w'`` to create a new file overwriting an existing
|
||||||
one or ``'x'`` to create a new file only if it's not exists.
|
one, or ``'x'`` to create a new file only if it does not already exist.
|
||||||
|
|
||||||
If *fileobj* is given, it is used for reading or writing data. If it can be
|
If *fileobj* is given, it is used for reading or writing data. If it can be
|
||||||
determined, *mode* is overridden by *fileobj*'s mode. *fileobj* will be used
|
determined, *mode* is overridden by *fileobj*'s mode. *fileobj* will be used
|
||||||
|
|
|
@ -250,7 +250,7 @@ ZipFile Objects
|
||||||
.. method:: ZipFile.extract(member, path=None, pwd=None)
|
.. method:: ZipFile.extract(member, path=None, pwd=None)
|
||||||
|
|
||||||
Extract a member from the archive to the current working directory; *member*
|
Extract a member from the archive to the current working directory; *member*
|
||||||
must be its full name or a :class:`ZipInfo` object). Its file information is
|
must be its full name or a :class:`ZipInfo` object. Its file information is
|
||||||
extracted as accurately as possible. *path* specifies a different directory
|
extracted as accurately as possible. *path* specifies a different directory
|
||||||
to extract to. *member* can be a filename or a :class:`ZipInfo` object.
|
to extract to. *member* can be a filename or a :class:`ZipInfo` object.
|
||||||
*pwd* is the password used for encrypted files.
|
*pwd* is the password used for encrypted files.
|
||||||
|
@ -343,9 +343,9 @@ ZipFile Objects
|
||||||
If ``arcname`` (or ``filename``, if ``arcname`` is not given) contains a null
|
If ``arcname`` (or ``filename``, if ``arcname`` is not given) contains a null
|
||||||
byte, the name of the file in the archive will be truncated at the null byte.
|
byte, the name of the file in the archive will be truncated at the null byte.
|
||||||
|
|
||||||
.. method:: ZipFile.writestr(zinfo_or_arcname, bytes[, compress_type])
|
.. method:: ZipFile.writestr(zinfo_or_arcname, data[, compress_type])
|
||||||
|
|
||||||
Write the string *bytes* to the archive; *zinfo_or_arcname* is either the file
|
Write the string *data* to the archive; *zinfo_or_arcname* is either the file
|
||||||
name it will be given in the archive, or a :class:`ZipInfo` instance. If it's
|
name it will be given in the archive, or a :class:`ZipInfo` instance. If it's
|
||||||
an instance, at least the filename, date, and time must be given. If it's a
|
an instance, at least the filename, date, and time must be given. If it's a
|
||||||
name, the date and time is set to the current date and time.
|
name, the date and time is set to the current date and time.
|
||||||
|
|
|
@ -454,6 +454,19 @@ Callable types
|
||||||
|
|
||||||
.. tabularcolumns:: |l|L|l|
|
.. 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: __closure__ (function attribute)
|
||||||
|
single: __code__ (function attribute)
|
||||||
|
single: __globals__ (function attribute)
|
||||||
|
single: __annotations__ (function attribute)
|
||||||
|
single: __kwdefaults__ (function attribute)
|
||||||
|
pair: global; namespace
|
||||||
|
|
||||||
+-------------------------+-------------------------------+-----------+
|
+-------------------------+-------------------------------+-----------+
|
||||||
| Attribute | Meaning | |
|
| Attribute | Meaning | |
|
||||||
+=========================+===============================+===========+
|
+=========================+===============================+===========+
|
||||||
|
@ -462,10 +475,11 @@ Callable types
|
||||||
| | unavailable; not inherited by | |
|
| | unavailable; not inherited by | |
|
||||||
| | subclasses | |
|
| | subclasses | |
|
||||||
+-------------------------+-------------------------------+-----------+
|
+-------------------------+-------------------------------+-----------+
|
||||||
| :attr:`__name__` | The function's name | Writable |
|
| :attr:`~definition.\ | The function's name | Writable |
|
||||||
|
| __name__` | | |
|
||||||
+-------------------------+-------------------------------+-----------+
|
+-------------------------+-------------------------------+-----------+
|
||||||
| :attr:`__qualname__` | The function's | Writable |
|
| :attr:`~definition.\ | The function's | Writable |
|
||||||
| | :term:`qualified name` | |
|
| __qualname__` | :term:`qualified name` | |
|
||||||
| | | |
|
| | | |
|
||||||
| | .. versionadded:: 3.3 | |
|
| | .. versionadded:: 3.3 | |
|
||||||
+-------------------------+-------------------------------+-----------+
|
+-------------------------+-------------------------------+-----------+
|
||||||
|
@ -489,7 +503,7 @@ Callable types
|
||||||
| | module in which the function | |
|
| | module in which the function | |
|
||||||
| | was defined. | |
|
| | was defined. | |
|
||||||
+-------------------------+-------------------------------+-----------+
|
+-------------------------+-------------------------------+-----------+
|
||||||
| :attr:`__dict__` | The namespace supporting | Writable |
|
| :attr:`~object.__dict__`| The namespace supporting | Writable |
|
||||||
| | arbitrary function | |
|
| | arbitrary function | |
|
||||||
| | attributes. | |
|
| | attributes. | |
|
||||||
+-------------------------+-------------------------------+-----------+
|
+-------------------------+-------------------------------+-----------+
|
||||||
|
@ -519,19 +533,6 @@ Callable types
|
||||||
Additional information about a function's definition can be retrieved from its
|
Additional information about a function's definition can be retrieved from its
|
||||||
code object; see the description of internal types below.
|
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: __closure__ (function attribute)
|
|
||||||
single: __code__ (function attribute)
|
|
||||||
single: __globals__ (function attribute)
|
|
||||||
single: __annotations__ (function attribute)
|
|
||||||
single: __kwdefaults__ (function attribute)
|
|
||||||
pair: global; namespace
|
|
||||||
|
|
||||||
Instance methods
|
Instance methods
|
||||||
.. index::
|
.. index::
|
||||||
object: method
|
object: method
|
||||||
|
@ -550,7 +551,7 @@ Callable types
|
||||||
|
|
||||||
Special read-only attributes: :attr:`__self__` is the class instance object,
|
Special read-only attributes: :attr:`__self__` is the class instance object,
|
||||||
:attr:`__func__` is the function object; :attr:`__doc__` is the method's
|
:attr:`__func__` is the function object; :attr:`__doc__` is the method's
|
||||||
documentation (same as ``__func__.__doc__``); :attr:`__name__` is the
|
documentation (same as ``__func__.__doc__``); :attr:`~definition.__name__` is the
|
||||||
method name (same as ``__func__.__name__``); :attr:`__module__` is the
|
method name (same as ``__func__.__name__``); :attr:`__module__` is the
|
||||||
name of the module the method was defined in, or ``None`` if unavailable.
|
name of the module the method was defined in, or ``None`` if unavailable.
|
||||||
|
|
||||||
|
@ -637,7 +638,7 @@ Callable types
|
||||||
standard built-in module). The number and type of the arguments are
|
standard built-in module). The number and type of the arguments are
|
||||||
determined by the C function. Special read-only attributes:
|
determined by the C function. Special read-only attributes:
|
||||||
:attr:`__doc__` is the function's documentation string, or ``None`` if
|
: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
|
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.
|
the module the function was defined in or ``None`` if unavailable.
|
||||||
|
|
||||||
|
@ -687,7 +688,7 @@ Modules
|
||||||
|
|
||||||
.. index:: single: __dict__ (module attribute)
|
.. 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.
|
dictionary object.
|
||||||
|
|
||||||
.. impl-detail::
|
.. impl-detail::
|
||||||
|
@ -743,7 +744,7 @@ Custom classes
|
||||||
method object, it is transformed into the object wrapped by the static method
|
method object, it is transformed into the object wrapped by the static method
|
||||||
object. See section :ref:`descriptors` for another way in which attributes
|
object. See section :ref:`descriptors` for another way in which attributes
|
||||||
retrieved from a class may differ from those actually contained in its
|
retrieved from a class may differ from those actually contained in its
|
||||||
:attr:`__dict__`.
|
:attr:`~object.__dict__`.
|
||||||
|
|
||||||
.. index:: triple: class; attribute; assignment
|
.. index:: triple: class; attribute; assignment
|
||||||
|
|
||||||
|
@ -761,8 +762,8 @@ Custom classes
|
||||||
single: __bases__ (class attribute)
|
single: __bases__ (class attribute)
|
||||||
single: __doc__ (class attribute)
|
single: __doc__ (class attribute)
|
||||||
|
|
||||||
Special attributes: :attr:`__name__` is the class name; :attr:`__module__` is
|
Special attributes: :attr:`~definition.__name__` is the class name; :attr:`__module__` is
|
||||||
the module name in which the class was defined; :attr:`__dict__` is the
|
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
|
dictionary containing the class's namespace; :attr:`~class.__bases__` is a
|
||||||
tuple (possibly empty or a singleton) containing the base classes, in the
|
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
|
order of their occurrence in the base class list; :attr:`__doc__` is the
|
||||||
|
@ -785,7 +786,7 @@ Class instances
|
||||||
class method objects are also transformed; see above under "Classes". See
|
class method objects are also transformed; see above under "Classes". See
|
||||||
section :ref:`descriptors` for another way in which attributes of a class
|
section :ref:`descriptors` for another way in which attributes of a class
|
||||||
retrieved via its instances may differ from the objects actually stored in
|
retrieved via its instances may differ from the objects actually stored in
|
||||||
the class's :attr:`__dict__`. If no class attribute is found, and the
|
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
|
object's class has a :meth:`__getattr__` method, that is called to satisfy
|
||||||
the lookup.
|
the lookup.
|
||||||
|
|
||||||
|
@ -1466,7 +1467,7 @@ method (a so-called *descriptor* class) appears in an *owner* class (the
|
||||||
descriptor must be in either the owner's class dictionary or in the class
|
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"
|
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
|
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)
|
.. method:: object.__get__(self, instance, owner)
|
||||||
|
|
|
@ -270,5 +270,5 @@ class SuspiciousVisitor(nodes.GenericNodeVisitor):
|
||||||
# ignore comments -- too much false positives.
|
# ignore comments -- too much false positives.
|
||||||
# (although doing this could miss some errors;
|
# (although doing this could miss some errors;
|
||||||
# there were two sections "commented-out" by mistake
|
# 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
|
raise nodes.SkipNode
|
||||||
|
|
|
@ -951,8 +951,8 @@ Examples::
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
.. [#] Except for one thing. Module objects have a secret read-only attribute called
|
.. [#] 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
|
:attr:`~object.__dict__` which returns the dictionary used to implement the module's
|
||||||
namespace; the name :attr:`__dict__` is an attribute but not a global name.
|
namespace; the name :attr:`~object.__dict__` is an attribute but not a global name.
|
||||||
Obviously, using this violates the abstraction of namespace implementation, and
|
Obviously, using this violates the abstraction of namespace implementation, and
|
||||||
should be restricted to things like post-mortem debuggers.
|
should be restricted to things like post-mortem debuggers.
|
||||||
|
|
||||||
|
|
|
@ -506,7 +506,7 @@ arguments and/or a dictionary of keyword arguments. In Python 1.5 and earlier,
|
||||||
you'd use the :func:`apply` built-in function: ``apply(f, args, kw)`` calls the
|
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
|
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
|
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
|
same effect. This syntax is symmetrical with the syntax for defining
|
||||||
functions::
|
functions::
|
||||||
|
|
||||||
|
|
|
@ -442,8 +442,8 @@ Python syntax::
|
||||||
f.grammar = "A ::= B (C D)*"
|
f.grammar = "A ::= B (C D)*"
|
||||||
|
|
||||||
The dictionary containing attributes can be accessed as the function's
|
The dictionary containing attributes can be accessed as the function's
|
||||||
:attr:`__dict__`. Unlike the :attr:`__dict__` attribute of class instances, in
|
:attr:`~object.__dict__`. Unlike the :attr:`~object.__dict__` attribute of class instances, in
|
||||||
functions you can actually assign a new dictionary to :attr:`__dict__`, though
|
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
|
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
|
tricky and set it to a :class:`UserDict` instance, or any other random object
|
||||||
that behaves like a mapping.
|
that behaves like a mapping.
|
||||||
|
|
|
@ -157,7 +157,7 @@ attributes and methods were supported by an object. There were some informal
|
||||||
conventions, such as defining :attr:`__members__` and :attr:`__methods__`
|
conventions, such as defining :attr:`__members__` and :attr:`__methods__`
|
||||||
attributes that were lists of names, but often the author of an extension type
|
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
|
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.
|
: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
|
The one big idea underlying the new class model is that an API for describing
|
||||||
|
@ -169,7 +169,7 @@ possible, as well as more exotic constructs.
|
||||||
Attribute descriptors are objects that live inside class objects, and have a few
|
Attribute descriptors are objects that live inside class objects, and have a few
|
||||||
attributes of their own:
|
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.
|
* :attr:`__doc__` is the attribute's docstring.
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ However, Python 2.2's support for :dfn:`properties` will often be a simpler way
|
||||||
to trap attribute references. Writing a :meth:`__getattr__` method is
|
to trap attribute references. Writing a :meth:`__getattr__` method is
|
||||||
complicated because to avoid recursion you can't use regular attribute accesses
|
complicated because to avoid recursion you can't use regular attribute accesses
|
||||||
inside them, and instead have to mess around with the contents of
|
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__`,
|
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
|
and so have to be written with this in mind. Finally, calling a function on
|
||||||
every attribute access results in a sizable performance loss.
|
every attribute access results in a sizable performance loss.
|
||||||
|
@ -357,15 +357,15 @@ write::
|
||||||
That is certainly clearer and easier to write than a pair of
|
That is certainly clearer and easier to write than a pair of
|
||||||
:meth:`__getattr__`/:meth:`__setattr__` methods that check for the :attr:`size`
|
:meth:`__getattr__`/:meth:`__setattr__` methods that check for the :attr:`size`
|
||||||
attribute and handle it specially while retrieving all other attributes from the
|
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
|
which have to perform the work of calling a function, so references to other
|
||||||
attributes run at their usual speed.
|
attributes run at their usual speed.
|
||||||
|
|
||||||
Finally, it's possible to constrain the list of attributes that can be
|
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
|
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
|
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::
|
attributes to a particular set of names. An example will make this clear::
|
||||||
|
|
||||||
>>> class C(object):
|
>>> class C(object):
|
||||||
|
@ -383,7 +383,7 @@ attributes to a particular set of names. An example will make this clear::
|
||||||
AttributeError: 'C' object has no attribute 'newattr'
|
AttributeError: 'C' object has no attribute 'newattr'
|
||||||
|
|
||||||
Note how you get an :exc:`AttributeError` on the attempt to assign to an
|
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:
|
.. _sect-rellinks:
|
||||||
|
|
|
@ -1111,10 +1111,10 @@ Here are all of the changes that Python 2.3 makes to the core Python language.
|
||||||
<type '_socket.socket'>
|
<type '_socket.socket'>
|
||||||
|
|
||||||
* One of the noted incompatibilities between old- and new-style classes has been
|
* 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
|
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
|
assigned to :attr:`~class.__bases__` along the lines of those relating to assigning to
|
||||||
an instance's :attr:`__class__` attribute.
|
an instance's :attr:`~instance.__class__` attribute.
|
||||||
|
|
||||||
.. ======================================================================
|
.. ======================================================================
|
||||||
|
|
||||||
|
@ -1920,7 +1920,7 @@ Changes to Python's build process and to the C API include:
|
||||||
|
|
||||||
* If you dynamically allocate type objects in your extension, you should be
|
* 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
|
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
|
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
|
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.
|
effect. For more detail, read the API reference documentation or the source.
|
||||||
|
|
|
@ -783,8 +783,8 @@ Operators And Special Methods
|
||||||
:attr:`func_closure`, :attr:`func_code`, :attr:`func_defaults`,
|
:attr:`func_closure`, :attr:`func_code`, :attr:`func_defaults`,
|
||||||
:attr:`func_dict`, :attr:`func_doc`, :attr:`func_globals`,
|
:attr:`func_dict`, :attr:`func_doc`, :attr:`func_globals`,
|
||||||
:attr:`func_name` were renamed to :attr:`__closure__`,
|
:attr:`func_name` were renamed to :attr:`__closure__`,
|
||||||
:attr:`__code__`, :attr:`__defaults__`, :attr:`__dict__`,
|
:attr:`__code__`, :attr:`__defaults__`, :attr:`~object.__dict__`,
|
||||||
:attr:`__doc__`, :attr:`__globals__`, :attr:`__name__`,
|
:attr:`__doc__`, :attr:`__globals__`, :attr:`~definition.__name__`,
|
||||||
respectively.
|
respectively.
|
||||||
|
|
||||||
* :meth:`__nonzero__` is now :meth:`__bool__`.
|
* :meth:`__nonzero__` is now :meth:`__bool__`.
|
||||||
|
|
|
@ -82,6 +82,9 @@ class _GeneratorContextManager(ContextDecorator):
|
||||||
# raised inside the "with" statement from being suppressed.
|
# raised inside the "with" statement from being suppressed.
|
||||||
return exc is not value
|
return exc is not value
|
||||||
except RuntimeError as exc:
|
except RuntimeError as exc:
|
||||||
|
# Don't re-raise the passed in exception. (issue27112)
|
||||||
|
if exc is value:
|
||||||
|
return False
|
||||||
# Likewise, avoid suppressing if a StopIteration exception
|
# Likewise, avoid suppressing if a StopIteration exception
|
||||||
# was passed to throw() and later wrapped into a RuntimeError
|
# was passed to throw() and later wrapped into a RuntimeError
|
||||||
# (see PEP 479).
|
# (see PEP 479).
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import unittest
|
import unittest
|
||||||
import os
|
import os, os.path
|
||||||
import sys
|
import sys
|
||||||
import test.support
|
import test.support
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
@ -64,6 +64,11 @@ class Test_OpenGL_libs(unittest.TestCase):
|
||||||
self.skipTest('lib_gle not available')
|
self.skipTest('lib_gle not available')
|
||||||
self.gle.gleGetJoinStyle
|
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',
|
# On platforms where the default shared library suffix is '.so',
|
||||||
# at least some libraries can be loaded as attributes of the cdll
|
# at least some libraries can be loaded as attributes of the cdll
|
||||||
# object, since ctypes now tries loading the lib again
|
# object, since ctypes now tries loading the lib again
|
||||||
|
|
|
@ -227,10 +227,10 @@ class StructureTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_conflicting_initializers(self):
|
def test_conflicting_initializers(self):
|
||||||
class POINT(Structure):
|
class POINT(Structure):
|
||||||
_fields_ = [("x", c_int), ("y", c_int)]
|
_fields_ = [("phi", c_float), ("rho", c_float)]
|
||||||
# conflicting positional and keyword args
|
# conflicting positional and keyword args
|
||||||
self.assertRaises(TypeError, POINT, 2, 3, x=4)
|
self.assertRaisesRegex(TypeError, "phi", POINT, 2, 3, phi=4)
|
||||||
self.assertRaises(TypeError, POINT, 2, 3, y=4)
|
self.assertRaisesRegex(TypeError, "rho", POINT, 2, 3, rho=4)
|
||||||
|
|
||||||
# too many initializers
|
# too many initializers
|
||||||
self.assertRaises(TypeError, POINT, 2, 3, 4)
|
self.assertRaises(TypeError, POINT, 2, 3, 4)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import sys, os
|
import os
|
||||||
import contextlib
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
# find_library(name) returns the pathname of a library, or None.
|
# find_library(name) returns the pathname of a library, or None.
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
|
@ -94,28 +95,46 @@ elif os.name == "posix":
|
||||||
import re, tempfile
|
import re, tempfile
|
||||||
|
|
||||||
def _findLib_gcc(name):
|
def _findLib_gcc(name):
|
||||||
expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
|
# Run GCC's linker with the -t (aka --trace) option and examine the
|
||||||
fdout, ccout = tempfile.mkstemp()
|
# library name it prints out. The GCC command will fail because we
|
||||||
os.close(fdout)
|
# haven't supplied a proper program with main(), but that does not
|
||||||
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;' \
|
# matter.
|
||||||
'LANG=C LC_ALL=C $CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
|
expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name))
|
||||||
|
|
||||||
|
c_compiler = shutil.which('gcc')
|
||||||
|
if not c_compiler:
|
||||||
|
c_compiler = shutil.which('cc')
|
||||||
|
if not c_compiler:
|
||||||
|
# No C compiler available, give up
|
||||||
|
return None
|
||||||
|
|
||||||
|
temp = tempfile.NamedTemporaryFile()
|
||||||
try:
|
try:
|
||||||
f = os.popen(cmd)
|
args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name]
|
||||||
|
|
||||||
|
env = dict(os.environ)
|
||||||
|
env['LC_ALL'] = 'C'
|
||||||
|
env['LANG'] = 'C'
|
||||||
try:
|
try:
|
||||||
trace = f.read()
|
proc = subprocess.Popen(args,
|
||||||
finally:
|
stdout=subprocess.PIPE,
|
||||||
rv = f.close()
|
stderr=subprocess.STDOUT,
|
||||||
|
env=env)
|
||||||
|
except OSError: # E.g. bad executable
|
||||||
|
return None
|
||||||
|
with proc:
|
||||||
|
trace = proc.stdout.read()
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
os.unlink(ccout)
|
temp.close()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
# Raised if the file was already removed, which is the normal
|
||||||
|
# behaviour of GCC if linking fails
|
||||||
pass
|
pass
|
||||||
if rv == 10:
|
|
||||||
raise OSError('gcc or cc command not found')
|
|
||||||
res = re.search(expr, trace)
|
res = re.search(expr, trace)
|
||||||
if not res:
|
if not res:
|
||||||
return None
|
return None
|
||||||
return res.group(0)
|
return os.fsdecode(res.group(0))
|
||||||
|
|
||||||
|
|
||||||
if sys.platform == "sunos5":
|
if sys.platform == "sunos5":
|
||||||
|
@ -123,55 +142,75 @@ elif os.name == "posix":
|
||||||
def _get_soname(f):
|
def _get_soname(f):
|
||||||
if not f:
|
if not f:
|
||||||
return None
|
return None
|
||||||
cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f
|
|
||||||
with contextlib.closing(os.popen(cmd)) as f:
|
try:
|
||||||
data = f.read()
|
proc = subprocess.Popen(("/usr/ccs/bin/dump", "-Lpv", f),
|
||||||
res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data)
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL)
|
||||||
|
except OSError: # E.g. command not found
|
||||||
|
return None
|
||||||
|
with proc:
|
||||||
|
data = proc.stdout.read()
|
||||||
|
res = re.search(br'\[.*\]\sSONAME\s+([^\s]+)', data)
|
||||||
if not res:
|
if not res:
|
||||||
return None
|
return None
|
||||||
return res.group(1)
|
return os.fsdecode(res.group(1))
|
||||||
else:
|
else:
|
||||||
def _get_soname(f):
|
def _get_soname(f):
|
||||||
# assuming GNU binutils / ELF
|
# assuming GNU binutils / ELF
|
||||||
if not f:
|
if not f:
|
||||||
return None
|
return None
|
||||||
cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \
|
objdump = shutil.which('objdump')
|
||||||
"objdump -p -j .dynamic 2>/dev/null " + f
|
if not objdump:
|
||||||
f = os.popen(cmd)
|
# objdump is not available, give up
|
||||||
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dump = f.read()
|
proc = subprocess.Popen((objdump, '-p', '-j', '.dynamic', f),
|
||||||
finally:
|
stdout=subprocess.PIPE,
|
||||||
rv = f.close()
|
stderr=subprocess.DEVNULL)
|
||||||
if rv == 10:
|
except OSError: # E.g. bad executable
|
||||||
raise OSError('objdump command not found')
|
return None
|
||||||
res = re.search(r'\sSONAME\s+([^\s]+)', dump)
|
with proc:
|
||||||
|
dump = proc.stdout.read()
|
||||||
|
res = re.search(br'\sSONAME\s+([^\s]+)', dump)
|
||||||
if not res:
|
if not res:
|
||||||
return None
|
return None
|
||||||
return res.group(1)
|
return os.fsdecode(res.group(1))
|
||||||
|
|
||||||
if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")):
|
if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")):
|
||||||
|
|
||||||
def _num_version(libname):
|
def _num_version(libname):
|
||||||
# "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
|
# "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
|
||||||
parts = libname.split(".")
|
parts = libname.split(b".")
|
||||||
nums = []
|
nums = []
|
||||||
try:
|
try:
|
||||||
while parts:
|
while parts:
|
||||||
nums.insert(0, int(parts.pop()))
|
nums.insert(0, int(parts.pop()))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
return nums or [ sys.maxsize ]
|
return nums or [sys.maxsize]
|
||||||
|
|
||||||
def find_library(name):
|
def find_library(name):
|
||||||
ename = re.escape(name)
|
ename = re.escape(name)
|
||||||
expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
|
expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
|
||||||
with contextlib.closing(os.popen('/sbin/ldconfig -r 2>/dev/null')) as f:
|
expr = os.fsencode(expr)
|
||||||
data = f.read()
|
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(('/sbin/ldconfig', '-r'),
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL)
|
||||||
|
except OSError: # E.g. command not found
|
||||||
|
data = b''
|
||||||
|
else:
|
||||||
|
with proc:
|
||||||
|
data = proc.stdout.read()
|
||||||
|
|
||||||
res = re.findall(expr, data)
|
res = re.findall(expr, data)
|
||||||
if not res:
|
if not res:
|
||||||
return _get_soname(_findLib_gcc(name))
|
return _get_soname(_findLib_gcc(name))
|
||||||
res.sort(key=_num_version)
|
res.sort(key=_num_version)
|
||||||
return res[-1]
|
return os.fsdecode(res[-1])
|
||||||
|
|
||||||
elif sys.platform == "sunos5":
|
elif sys.platform == "sunos5":
|
||||||
|
|
||||||
|
@ -179,17 +218,27 @@ elif os.name == "posix":
|
||||||
if not os.path.exists('/usr/bin/crle'):
|
if not os.path.exists('/usr/bin/crle'):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
env = dict(os.environ)
|
||||||
|
env['LC_ALL'] = 'C'
|
||||||
|
|
||||||
if is64:
|
if is64:
|
||||||
cmd = 'env LC_ALL=C /usr/bin/crle -64 2>/dev/null'
|
args = ('/usr/bin/crle', '-64')
|
||||||
else:
|
else:
|
||||||
cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null'
|
args = ('/usr/bin/crle',)
|
||||||
|
|
||||||
paths = None
|
paths = None
|
||||||
with contextlib.closing(os.popen(cmd)) as f:
|
try:
|
||||||
for line in f.readlines():
|
proc = subprocess.Popen(args,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
env=env)
|
||||||
|
except OSError: # E.g. bad executable
|
||||||
|
return None
|
||||||
|
with proc:
|
||||||
|
for line in proc.stdout:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if line.startswith('Default Library Path (ELF):'):
|
if line.startswith(b'Default Library Path (ELF):'):
|
||||||
paths = line.split()[4]
|
paths = os.fsdecode(line).split()[4]
|
||||||
|
|
||||||
if not paths:
|
if not paths:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -54,13 +54,13 @@ def _ctoi(c):
|
||||||
def isalnum(c): return isalpha(c) or isdigit(c)
|
def isalnum(c): return isalpha(c) or isdigit(c)
|
||||||
def isalpha(c): return isupper(c) or islower(c)
|
def isalpha(c): return isupper(c) or islower(c)
|
||||||
def isascii(c): return _ctoi(c) <= 127 # ?
|
def isascii(c): return _ctoi(c) <= 127 # ?
|
||||||
def isblank(c): return _ctoi(c) in (8,32)
|
def isblank(c): return _ctoi(c) in (9, 32)
|
||||||
def iscntrl(c): return _ctoi(c) <= 31
|
def iscntrl(c): return _ctoi(c) <= 31 or _ctoi(c) == 127
|
||||||
def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57
|
def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57
|
||||||
def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126
|
def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126
|
||||||
def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122
|
def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122
|
||||||
def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126
|
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 isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32)
|
||||||
def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90
|
def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90
|
||||||
def isxdigit(c): return isdigit(c) or \
|
def isxdigit(c): return isdigit(c) or \
|
||||||
|
|
|
@ -86,11 +86,9 @@ def _get_vc_env(plat_spec):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
out = subprocess.check_output(
|
out = subprocess.check_output(
|
||||||
'"{}" {} && set'.format(vcvarsall, plat_spec),
|
'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec),
|
||||||
shell=True,
|
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
universal_newlines=True,
|
).decode('utf-16le', errors='replace')
|
||||||
)
|
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError as exc:
|
||||||
log.error(exc.output)
|
log.error(exc.output)
|
||||||
raise DistutilsPlatformError("Error executing {}"
|
raise DistutilsPlatformError("Error executing {}"
|
||||||
|
|
|
@ -91,7 +91,7 @@ class upload(PyPIRCCommand):
|
||||||
data = {
|
data = {
|
||||||
# action
|
# action
|
||||||
':action': 'file_upload',
|
':action': 'file_upload',
|
||||||
'protcol_version': '1',
|
'protocol_version': '1',
|
||||||
|
|
||||||
# identify release
|
# identify release
|
||||||
'name': meta.get_name(),
|
'name': meta.get_name(),
|
||||||
|
|
|
@ -18,6 +18,7 @@ PYPIRC = """\
|
||||||
index-servers =
|
index-servers =
|
||||||
server1
|
server1
|
||||||
server2
|
server2
|
||||||
|
server3
|
||||||
|
|
||||||
[server1]
|
[server1]
|
||||||
username:me
|
username:me
|
||||||
|
@ -28,6 +29,10 @@ username:meagain
|
||||||
password: secret
|
password: secret
|
||||||
realm:acme
|
realm:acme
|
||||||
repository:http://another.pypi/
|
repository:http://another.pypi/
|
||||||
|
|
||||||
|
[server3]
|
||||||
|
username:cbiggles
|
||||||
|
password:yh^%#rest-of-my-password
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PYPIRC_OLD = """\
|
PYPIRC_OLD = """\
|
||||||
|
@ -47,14 +52,14 @@ password:xxx
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PyPIRCCommandTestCase(support.TempdirManager,
|
class BasePyPIRCCommandTestCase(support.TempdirManager,
|
||||||
support.LoggingSilencer,
|
support.LoggingSilencer,
|
||||||
support.EnvironGuard,
|
support.EnvironGuard,
|
||||||
unittest.TestCase):
|
unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Patches the environment."""
|
"""Patches the environment."""
|
||||||
super(PyPIRCCommandTestCase, self).setUp()
|
super(BasePyPIRCCommandTestCase, self).setUp()
|
||||||
self.tmp_dir = self.mkdtemp()
|
self.tmp_dir = self.mkdtemp()
|
||||||
os.environ['HOME'] = self.tmp_dir
|
os.environ['HOME'] = self.tmp_dir
|
||||||
self.rc = os.path.join(self.tmp_dir, '.pypirc')
|
self.rc = os.path.join(self.tmp_dir, '.pypirc')
|
||||||
|
@ -73,7 +78,10 @@ class PyPIRCCommandTestCase(support.TempdirManager,
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""Removes the patch."""
|
"""Removes the patch."""
|
||||||
set_threshold(self.old_threshold)
|
set_threshold(self.old_threshold)
|
||||||
super(PyPIRCCommandTestCase, self).tearDown()
|
super(BasePyPIRCCommandTestCase, self).tearDown()
|
||||||
|
|
||||||
|
|
||||||
|
class PyPIRCCommandTestCase(BasePyPIRCCommandTestCase):
|
||||||
|
|
||||||
def test_server_registration(self):
|
def test_server_registration(self):
|
||||||
# This test makes sure PyPIRCCommand knows how to:
|
# This test makes sure PyPIRCCommand knows how to:
|
||||||
|
@ -113,6 +121,20 @@ class PyPIRCCommandTestCase(support.TempdirManager,
|
||||||
finally:
|
finally:
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
def test_config_interpolation(self):
|
||||||
|
# using the % character in .pypirc should not raise an error (#20120)
|
||||||
|
self.write_file(self.rc, PYPIRC)
|
||||||
|
cmd = self._cmd(self.dist)
|
||||||
|
cmd.repository = 'server3'
|
||||||
|
config = cmd._read_pypirc()
|
||||||
|
|
||||||
|
config = list(sorted(config.items()))
|
||||||
|
waited = [('password', 'yh^%#rest-of-my-password'), ('realm', 'pypi'),
|
||||||
|
('repository', 'https://pypi.python.org/pypi'),
|
||||||
|
('server', 'server3'), ('username', 'cbiggles')]
|
||||||
|
self.assertEqual(config, waited)
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.makeSuite(PyPIRCCommandTestCase)
|
return unittest.makeSuite(PyPIRCCommandTestCase)
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,24 @@ class msvccompilerTestCase(support.TempdirManager,
|
||||||
self.assertFalse(os.path.isfile(os.path.join(
|
self.assertFalse(os.path.isfile(os.path.join(
|
||||||
tempdir, os.path.basename(dll))))
|
tempdir, os.path.basename(dll))))
|
||||||
|
|
||||||
|
def test_get_vc_env_unicode(self):
|
||||||
|
import distutils._msvccompiler as _msvccompiler
|
||||||
|
|
||||||
|
test_var = 'ṰḖṤṪ┅ṼẨṜ'
|
||||||
|
test_value = '₃⁴₅'
|
||||||
|
|
||||||
|
# Ensure we don't early exit from _get_vc_env
|
||||||
|
old_distutils_use_sdk = os.environ.pop('DISTUTILS_USE_SDK', None)
|
||||||
|
os.environ[test_var] = test_value
|
||||||
|
try:
|
||||||
|
env = _msvccompiler._get_vc_env('x86')
|
||||||
|
self.assertIn(test_var.lower(), env)
|
||||||
|
self.assertEqual(test_value, env[test_var.lower()])
|
||||||
|
finally:
|
||||||
|
os.environ.pop(test_var)
|
||||||
|
if old_distutils_use_sdk:
|
||||||
|
os.environ['DISTUTILS_USE_SDK'] = old_distutils_use_sdk
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.makeSuite(msvccompilerTestCase)
|
return unittest.makeSuite(msvccompilerTestCase)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from distutils.command.register import register
|
||||||
from distutils.errors import DistutilsSetupError
|
from distutils.errors import DistutilsSetupError
|
||||||
from distutils.log import INFO
|
from distutils.log import INFO
|
||||||
|
|
||||||
from distutils.tests.test_config import PyPIRCCommandTestCase
|
from distutils.tests.test_config import BasePyPIRCCommandTestCase
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import docutils
|
import docutils
|
||||||
|
@ -72,7 +72,7 @@ class FakeOpener(object):
|
||||||
}.get(name.lower(), default)
|
}.get(name.lower(), default)
|
||||||
|
|
||||||
|
|
||||||
class RegisterTestCase(PyPIRCCommandTestCase):
|
class RegisterTestCase(BasePyPIRCCommandTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(RegisterTestCase, self).setUp()
|
super(RegisterTestCase, self).setUp()
|
||||||
|
|
|
@ -23,7 +23,7 @@ except ImportError:
|
||||||
|
|
||||||
from distutils.command.sdist import sdist, show_formats
|
from distutils.command.sdist import sdist, show_formats
|
||||||
from distutils.core import Distribution
|
from distutils.core import Distribution
|
||||||
from distutils.tests.test_config import PyPIRCCommandTestCase
|
from distutils.tests.test_config import BasePyPIRCCommandTestCase
|
||||||
from distutils.errors import DistutilsOptionError
|
from distutils.errors import DistutilsOptionError
|
||||||
from distutils.spawn import find_executable
|
from distutils.spawn import find_executable
|
||||||
from distutils.log import WARN
|
from distutils.log import WARN
|
||||||
|
@ -52,7 +52,7 @@ somecode%(sep)sdoc.dat
|
||||||
somecode%(sep)sdoc.txt
|
somecode%(sep)sdoc.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class SDistTestCase(PyPIRCCommandTestCase):
|
class SDistTestCase(BasePyPIRCCommandTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# PyPIRCCommandTestCase creates a temp dir already
|
# PyPIRCCommandTestCase creates a temp dir already
|
||||||
|
|
|
@ -12,7 +12,7 @@ from distutils.core import Distribution
|
||||||
from distutils.errors import DistutilsError
|
from distutils.errors import DistutilsError
|
||||||
from distutils.log import ERROR, INFO
|
from distutils.log import ERROR, INFO
|
||||||
|
|
||||||
from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
|
from distutils.tests.test_config import PYPIRC, BasePyPIRCCommandTestCase
|
||||||
|
|
||||||
PYPIRC_LONG_PASSWORD = """\
|
PYPIRC_LONG_PASSWORD = """\
|
||||||
[distutils]
|
[distutils]
|
||||||
|
@ -66,7 +66,7 @@ class FakeOpen(object):
|
||||||
return self.code
|
return self.code
|
||||||
|
|
||||||
|
|
||||||
class uploadTestCase(PyPIRCCommandTestCase):
|
class uploadTestCase(BasePyPIRCCommandTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(uploadTestCase, self).setUp()
|
super(uploadTestCase, self).setUp()
|
||||||
|
@ -130,13 +130,14 @@ class uploadTestCase(PyPIRCCommandTestCase):
|
||||||
|
|
||||||
# what did we send ?
|
# what did we send ?
|
||||||
headers = dict(self.last_open.req.headers)
|
headers = dict(self.last_open.req.headers)
|
||||||
self.assertEqual(headers['Content-length'], '2161')
|
self.assertEqual(headers['Content-length'], '2162')
|
||||||
content_type = headers['Content-type']
|
content_type = headers['Content-type']
|
||||||
self.assertTrue(content_type.startswith('multipart/form-data'))
|
self.assertTrue(content_type.startswith('multipart/form-data'))
|
||||||
self.assertEqual(self.last_open.req.get_method(), 'POST')
|
self.assertEqual(self.last_open.req.get_method(), 'POST')
|
||||||
expected_url = 'https://pypi.python.org/pypi'
|
expected_url = 'https://pypi.python.org/pypi'
|
||||||
self.assertEqual(self.last_open.req.get_full_url(), expected_url)
|
self.assertEqual(self.last_open.req.get_full_url(), expected_url)
|
||||||
self.assertTrue(b'xxx' in self.last_open.req.data)
|
self.assertTrue(b'xxx' in self.last_open.req.data)
|
||||||
|
self.assertIn(b'protocol_version', self.last_open.req.data)
|
||||||
|
|
||||||
# The PyPI response body was echoed
|
# The PyPI response body was echoed
|
||||||
results = self.get_logs(INFO)
|
results = self.get_logs(INFO)
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
|
What's New in IDLE 3.5.3?
|
||||||
|
=========================
|
||||||
|
*Release date: 2017-01-01?*
|
||||||
|
|
||||||
|
- Issue #27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names.
|
||||||
|
|
||||||
|
- Issue #27245: IDLE: Cleanly delete custom themes and key bindings.
|
||||||
|
Previously, when IDLE was started from a console or by import, a cascade
|
||||||
|
of warnings was emitted. Patch by Serhiy Storchaka.
|
||||||
|
|
||||||
|
|
||||||
What's New in IDLE 3.5.2?
|
What's New in IDLE 3.5.2?
|
||||||
=========================
|
=========================
|
||||||
*Release date: 2016-06-30?*
|
*Release date: 2016-06-26*
|
||||||
|
|
||||||
- Issue #5124: Paste with text selected now replaces the selection on X11.
|
- Issue #5124: Paste with text selected now replaces the selection on X11.
|
||||||
This matches how paste works on Windows, Mac, most modern Linux apps,
|
This matches how paste works on Windows, Mac, most modern Linux apps,
|
||||||
|
|
|
@ -145,5 +145,7 @@ class AboutDialog(Toplevel):
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
import unittest
|
||||||
|
unittest.main('idlelib.idle_test.test_helpabout', verbosity=2, exit=False)
|
||||||
from idlelib.idle_test.htest import run
|
from idlelib.idle_test.htest import run
|
||||||
run(AboutDialog)
|
run(AboutDialog)
|
||||||
|
|
|
@ -751,6 +751,7 @@ class ConfigDialog(Toplevel):
|
||||||
if not tkMessageBox.askyesno(
|
if not tkMessageBox.askyesno(
|
||||||
'Delete Key Set', delmsg % keySetName, parent=self):
|
'Delete Key Set', delmsg % keySetName, parent=self):
|
||||||
return
|
return
|
||||||
|
self.DeactivateCurrentConfig()
|
||||||
#remove key set from config
|
#remove key set from config
|
||||||
idleConf.userCfg['keys'].remove_section(keySetName)
|
idleConf.userCfg['keys'].remove_section(keySetName)
|
||||||
if keySetName in self.changedItems['keys']:
|
if keySetName in self.changedItems['keys']:
|
||||||
|
@ -769,7 +770,8 @@ class ConfigDialog(Toplevel):
|
||||||
self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
|
self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
|
||||||
self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
|
self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
|
||||||
#user can't back out of these changes, they must be applied now
|
#user can't back out of these changes, they must be applied now
|
||||||
self.Apply()
|
self.SaveAllChangedConfigs()
|
||||||
|
self.ActivateConfigChanges()
|
||||||
self.SetKeysType()
|
self.SetKeysType()
|
||||||
|
|
||||||
def DeleteCustomTheme(self):
|
def DeleteCustomTheme(self):
|
||||||
|
@ -778,6 +780,7 @@ class ConfigDialog(Toplevel):
|
||||||
if not tkMessageBox.askyesno(
|
if not tkMessageBox.askyesno(
|
||||||
'Delete Theme', delmsg % themeName, parent=self):
|
'Delete Theme', delmsg % themeName, parent=self):
|
||||||
return
|
return
|
||||||
|
self.DeactivateCurrentConfig()
|
||||||
#remove theme from config
|
#remove theme from config
|
||||||
idleConf.userCfg['highlight'].remove_section(themeName)
|
idleConf.userCfg['highlight'].remove_section(themeName)
|
||||||
if themeName in self.changedItems['highlight']:
|
if themeName in self.changedItems['highlight']:
|
||||||
|
@ -796,7 +799,8 @@ class ConfigDialog(Toplevel):
|
||||||
self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
|
self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
|
||||||
self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
|
self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
|
||||||
#user can't back out of these changes, they must be applied now
|
#user can't back out of these changes, they must be applied now
|
||||||
self.Apply()
|
self.SaveAllChangedConfigs()
|
||||||
|
self.ActivateConfigChanges()
|
||||||
self.SetThemeType()
|
self.SetThemeType()
|
||||||
|
|
||||||
def GetColour(self):
|
def GetColour(self):
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
'''Test idlelib.help_about.
|
||||||
|
|
||||||
|
Coverage:
|
||||||
|
'''
|
||||||
|
from idlelib import aboutDialog as help_about
|
||||||
|
from idlelib import textView as textview
|
||||||
|
from idlelib.idle_test.mock_idle import Func
|
||||||
|
from idlelib.idle_test.mock_tk import Mbox
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
About = help_about.AboutDialog
|
||||||
|
class Dummy_about_dialog():
|
||||||
|
# Dummy class for testing file display functions.
|
||||||
|
idle_credits = About.ShowIDLECredits
|
||||||
|
idle_readme = About.ShowIDLEAbout
|
||||||
|
idle_news = About.ShowIDLENEWS
|
||||||
|
# Called by the above
|
||||||
|
display_file_text = About.display_file_text
|
||||||
|
|
||||||
|
|
||||||
|
class DisplayFileTest(unittest.TestCase):
|
||||||
|
"Test that .txt files are found and properly decoded."
|
||||||
|
dialog = Dummy_about_dialog()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.orig_mbox = textview.tkMessageBox
|
||||||
|
cls.orig_view = textview.view_text
|
||||||
|
cls.mbox = Mbox()
|
||||||
|
cls.view = Func()
|
||||||
|
textview.tkMessageBox = cls.mbox
|
||||||
|
textview.view_text = cls.view
|
||||||
|
cls.About = Dummy_about_dialog()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
textview.tkMessageBox = cls.orig_mbox
|
||||||
|
textview.view_text = cls.orig_view
|
||||||
|
|
||||||
|
def test_file_isplay(self):
|
||||||
|
for handler in (self.dialog.idle_credits,
|
||||||
|
self.dialog.idle_readme,
|
||||||
|
self.dialog.idle_news):
|
||||||
|
self.mbox.showerror.message = ''
|
||||||
|
self.view.called = False
|
||||||
|
handler()
|
||||||
|
self.assertEqual(self.mbox.showerror.message, '')
|
||||||
|
self.assertEqual(self.view.called, True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main(verbosity=2)
|
|
@ -76,6 +76,10 @@ def view_file(parent, title, filename, encoding=None, modal=True):
|
||||||
tkMessageBox.showerror(title='File Load Error',
|
tkMessageBox.showerror(title='File Load Error',
|
||||||
message='Unable to load file %r .' % filename,
|
message='Unable to load file %r .' % filename,
|
||||||
parent=parent)
|
parent=parent)
|
||||||
|
except UnicodeDecodeError as err:
|
||||||
|
tkMessageBox.showerror(title='Unicode Decode Error',
|
||||||
|
message=str(err),
|
||||||
|
parent=parent)
|
||||||
else:
|
else:
|
||||||
return view_text(parent, title, contents, modal)
|
return view_text(parent, title, contents, modal)
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations)
|
# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations)
|
||||||
# Python 3.5b2 3340 (fix dictionary display evaluation order #11205)
|
# Python 3.5b2 3340 (fix dictionary display evaluation order #11205)
|
||||||
# Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400)
|
# Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400)
|
||||||
|
# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
|
||||||
#
|
#
|
||||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||||
# longer be understood by older implementations of the eval loop (usually
|
# longer be understood by older implementations of the eval loop (usually
|
||||||
|
@ -231,7 +232,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||||
# in PC/launcher.c must also be updated.
|
# in PC/launcher.c must also be updated.
|
||||||
|
|
||||||
MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n'
|
MAGIC_NUMBER = (3351).to_bytes(2, 'little') + b'\r\n'
|
||||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||||
|
|
||||||
_PYCACHE = '__pycache__'
|
_PYCACHE = '__pycache__'
|
||||||
|
|
|
@ -241,7 +241,7 @@ class _LazyModule(types.ModuleType):
|
||||||
if id(self) != id(sys.modules[original_name]):
|
if id(self) != id(sys.modules[original_name]):
|
||||||
msg = ('module object for {!r} substituted in sys.modules '
|
msg = ('module object for {!r} substituted in sys.modules '
|
||||||
'during a lazy load')
|
'during a lazy load')
|
||||||
raise ValueError(msg.format(original_name))
|
raise ValueError(msg.format(original_name))
|
||||||
# Update after loading since that's what would happen in an eager
|
# Update after loading since that's what would happen in an eager
|
||||||
# loading situation.
|
# loading situation.
|
||||||
self.__dict__.update(attrs_updated)
|
self.__dict__.update(attrs_updated)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import os
|
||||||
import codecs
|
import codecs
|
||||||
import operator
|
import operator
|
||||||
import io
|
import io
|
||||||
|
import re
|
||||||
import tempfile
|
import tempfile
|
||||||
import shutil
|
import shutil
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -226,8 +227,8 @@ from __future__ import print_function"""
|
||||||
actually_write=False)
|
actually_write=False)
|
||||||
# Testing that it logged this message when write=False was passed is
|
# Testing that it logged this message when write=False was passed is
|
||||||
# sufficient to see that it did not bail early after "No changes".
|
# sufficient to see that it did not bail early after "No changes".
|
||||||
message_regex = r"Not writing changes to .*%s%s" % (
|
message_regex = r"Not writing changes to .*%s" % \
|
||||||
os.sep, os.path.basename(test_file))
|
re.escape(os.sep + os.path.basename(test_file))
|
||||||
for message in debug_messages:
|
for message in debug_messages:
|
||||||
if "Not writing changes" in message:
|
if "Not writing changes" in message:
|
||||||
self.assertRegex(message, message_regex)
|
self.assertRegex(message, message_regex)
|
||||||
|
|
|
@ -28,7 +28,7 @@ to a file named "<name>.html".
|
||||||
|
|
||||||
Module docs for core modules are assumed to be in
|
Module docs for core modules are assumed to be in
|
||||||
|
|
||||||
http://docs.python.org/X.Y/library/
|
https://docs.python.org/X.Y/library/
|
||||||
|
|
||||||
This can be overridden by setting the PYTHONDOCS environment variable
|
This can be overridden by setting the PYTHONDOCS environment variable
|
||||||
to a different URL or to a local directory containing the Library
|
to a different URL or to a local directory containing the Library
|
||||||
|
@ -395,6 +395,7 @@ class Doc:
|
||||||
|
|
||||||
docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
|
docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
|
||||||
|
|
||||||
|
basedir = os.path.normcase(basedir)
|
||||||
if (isinstance(object, type(os)) and
|
if (isinstance(object, type(os)) and
|
||||||
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
|
(object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
|
||||||
'marshal', 'posix', 'signal', 'sys',
|
'marshal', 'posix', 'signal', 'sys',
|
||||||
|
@ -402,7 +403,7 @@ class Doc:
|
||||||
(file.startswith(basedir) and
|
(file.startswith(basedir) and
|
||||||
not file.startswith(os.path.join(basedir, 'site-packages')))) and
|
not file.startswith(os.path.join(basedir, 'site-packages')))) and
|
||||||
object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
|
object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
|
||||||
if docloc.startswith("http://"):
|
if docloc.startswith(("http://", "https://")):
|
||||||
docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
|
docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
|
||||||
else:
|
else:
|
||||||
docloc = os.path.join(docloc, object.__name__.lower() + ".html")
|
docloc = os.path.join(docloc, object.__name__.lower() + ".html")
|
||||||
|
|
|
@ -122,11 +122,8 @@ class ConnectionTests(unittest.TestCase):
|
||||||
|
|
||||||
def CheckFailedOpen(self):
|
def CheckFailedOpen(self):
|
||||||
YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
|
YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
|
con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
|
||||||
except sqlite.OperationalError:
|
|
||||||
return
|
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
|
|
||||||
def CheckClose(self):
|
def CheckClose(self):
|
||||||
self.cx.close()
|
self.cx.close()
|
||||||
|
@ -180,6 +177,12 @@ class ConnectionTests(unittest.TestCase):
|
||||||
with self.assertRaises(sqlite.OperationalError):
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
cx.execute('insert into test(id) values(1)')
|
cx.execute('insert into test(id) values(1)')
|
||||||
|
|
||||||
|
@unittest.skipIf(sqlite.sqlite_version_info >= (3, 3, 1),
|
||||||
|
'needs sqlite versions older than 3.3.1')
|
||||||
|
def CheckSameThreadErrorOnOldVersion(self):
|
||||||
|
with self.assertRaises(sqlite.NotSupportedError) as cm:
|
||||||
|
sqlite.connect(':memory:', check_same_thread=False)
|
||||||
|
self.assertEqual(str(cm.exception), 'shared connections not available')
|
||||||
|
|
||||||
class CursorTests(unittest.TestCase):
|
class CursorTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -196,22 +199,12 @@ class CursorTests(unittest.TestCase):
|
||||||
self.cu.execute("delete from test")
|
self.cu.execute("delete from test")
|
||||||
|
|
||||||
def CheckExecuteIllegalSql(self):
|
def CheckExecuteIllegalSql(self):
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
self.cu.execute("select asdf")
|
self.cu.execute("select asdf")
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
except sqlite.OperationalError:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
self.fail("raised wrong exception")
|
|
||||||
|
|
||||||
def CheckExecuteTooMuchSql(self):
|
def CheckExecuteTooMuchSql(self):
|
||||||
try:
|
with self.assertRaises(sqlite.Warning):
|
||||||
self.cu.execute("select 5+4; select 4+5")
|
self.cu.execute("select 5+4; select 4+5")
|
||||||
self.fail("should have raised a Warning")
|
|
||||||
except sqlite.Warning:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
self.fail("raised wrong exception")
|
|
||||||
|
|
||||||
def CheckExecuteTooMuchSql2(self):
|
def CheckExecuteTooMuchSql2(self):
|
||||||
self.cu.execute("select 5+4; -- foo bar")
|
self.cu.execute("select 5+4; -- foo bar")
|
||||||
|
@ -226,13 +219,8 @@ class CursorTests(unittest.TestCase):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def CheckExecuteWrongSqlArg(self):
|
def CheckExecuteWrongSqlArg(self):
|
||||||
try:
|
with self.assertRaises(ValueError):
|
||||||
self.cu.execute(42)
|
self.cu.execute(42)
|
||||||
self.fail("should have raised a ValueError")
|
|
||||||
except ValueError:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
self.fail("raised wrong exception.")
|
|
||||||
|
|
||||||
def CheckExecuteArgInt(self):
|
def CheckExecuteArgInt(self):
|
||||||
self.cu.execute("insert into test(id) values (?)", (42,))
|
self.cu.execute("insert into test(id) values (?)", (42,))
|
||||||
|
@ -250,29 +238,25 @@ class CursorTests(unittest.TestCase):
|
||||||
row = self.cu.fetchone()
|
row = self.cu.fetchone()
|
||||||
self.assertEqual(row[0], "Hu\x00go")
|
self.assertEqual(row[0], "Hu\x00go")
|
||||||
|
|
||||||
|
def CheckExecuteNonIterable(self):
|
||||||
|
with self.assertRaises(ValueError) as cm:
|
||||||
|
self.cu.execute("insert into test(id) values (?)", 42)
|
||||||
|
self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
|
||||||
|
|
||||||
def CheckExecuteWrongNoOfArgs1(self):
|
def CheckExecuteWrongNoOfArgs1(self):
|
||||||
# too many parameters
|
# too many parameters
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
|
self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckExecuteWrongNoOfArgs2(self):
|
def CheckExecuteWrongNoOfArgs2(self):
|
||||||
# too little parameters
|
# too little parameters
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.execute("insert into test(id) values (?)")
|
self.cu.execute("insert into test(id) values (?)")
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckExecuteWrongNoOfArgs3(self):
|
def CheckExecuteWrongNoOfArgs3(self):
|
||||||
# no parameters, parameters are needed
|
# no parameters, parameters are needed
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.execute("insert into test(id) values (?)")
|
self.cu.execute("insert into test(id) values (?)")
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckExecuteParamList(self):
|
def CheckExecuteParamList(self):
|
||||||
self.cu.execute("insert into test(name) values ('foo')")
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
|
@ -311,27 +295,18 @@ class CursorTests(unittest.TestCase):
|
||||||
|
|
||||||
def CheckExecuteDictMappingTooLittleArgs(self):
|
def CheckExecuteDictMappingTooLittleArgs(self):
|
||||||
self.cu.execute("insert into test(name) values ('foo')")
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
|
self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckExecuteDictMappingNoArgs(self):
|
def CheckExecuteDictMappingNoArgs(self):
|
||||||
self.cu.execute("insert into test(name) values ('foo')")
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.execute("select name from test where name=:name")
|
self.cu.execute("select name from test where name=:name")
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckExecuteDictMappingUnnamed(self):
|
def CheckExecuteDictMappingUnnamed(self):
|
||||||
self.cu.execute("insert into test(name) values ('foo')")
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.execute("select name from test where name=?", {"name": "foo"})
|
self.cu.execute("select name from test where name=?", {"name": "foo"})
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckClose(self):
|
def CheckClose(self):
|
||||||
self.cu.close()
|
self.cu.close()
|
||||||
|
@ -360,8 +335,7 @@ class CursorTests(unittest.TestCase):
|
||||||
def CheckTotalChanges(self):
|
def CheckTotalChanges(self):
|
||||||
self.cu.execute("insert into test(name) values ('foo')")
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
self.cu.execute("insert into test(name) values ('foo')")
|
self.cu.execute("insert into test(name) values ('foo')")
|
||||||
if self.cx.total_changes < 2:
|
self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
|
||||||
self.fail("total changes reported wrong value")
|
|
||||||
|
|
||||||
# Checks for executemany:
|
# Checks for executemany:
|
||||||
# Sequences are required by the DB-API, iterators
|
# Sequences are required by the DB-API, iterators
|
||||||
|
@ -392,32 +366,16 @@ class CursorTests(unittest.TestCase):
|
||||||
self.cu.executemany("insert into test(income) values (?)", mygen())
|
self.cu.executemany("insert into test(income) values (?)", mygen())
|
||||||
|
|
||||||
def CheckExecuteManyWrongSqlArg(self):
|
def CheckExecuteManyWrongSqlArg(self):
|
||||||
try:
|
with self.assertRaises(ValueError):
|
||||||
self.cu.executemany(42, [(3,)])
|
self.cu.executemany(42, [(3,)])
|
||||||
self.fail("should have raised a ValueError")
|
|
||||||
except ValueError:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
self.fail("raised wrong exception.")
|
|
||||||
|
|
||||||
def CheckExecuteManySelect(self):
|
def CheckExecuteManySelect(self):
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
self.cu.executemany("select ?", [(3,)])
|
self.cu.executemany("select ?", [(3,)])
|
||||||
self.fail("should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
self.fail("raised wrong exception.")
|
|
||||||
|
|
||||||
def CheckExecuteManyNotIterable(self):
|
def CheckExecuteManyNotIterable(self):
|
||||||
try:
|
with self.assertRaises(TypeError):
|
||||||
self.cu.executemany("insert into test(income) values (?)", 42)
|
self.cu.executemany("insert into test(income) values (?)", 42)
|
||||||
self.fail("should have raised a TypeError")
|
|
||||||
except TypeError:
|
|
||||||
return
|
|
||||||
except Exception as e:
|
|
||||||
print("raised", e.__class__)
|
|
||||||
self.fail("raised wrong exception.")
|
|
||||||
|
|
||||||
def CheckFetchIter(self):
|
def CheckFetchIter(self):
|
||||||
# Optional DB-API extension.
|
# Optional DB-API extension.
|
||||||
|
@ -494,22 +452,15 @@ class CursorTests(unittest.TestCase):
|
||||||
self.assertEqual(self.cu.connection, self.cx)
|
self.assertEqual(self.cu.connection, self.cx)
|
||||||
|
|
||||||
def CheckWrongCursorCallable(self):
|
def CheckWrongCursorCallable(self):
|
||||||
try:
|
with self.assertRaises(TypeError):
|
||||||
def f(): pass
|
def f(): pass
|
||||||
cur = self.cx.cursor(f)
|
cur = self.cx.cursor(f)
|
||||||
self.fail("should have raised a TypeError")
|
|
||||||
except TypeError:
|
|
||||||
return
|
|
||||||
self.fail("should have raised a ValueError")
|
|
||||||
|
|
||||||
def CheckCursorWrongClass(self):
|
def CheckCursorWrongClass(self):
|
||||||
class Foo: pass
|
class Foo: pass
|
||||||
foo = Foo()
|
foo = Foo()
|
||||||
try:
|
with self.assertRaises(TypeError):
|
||||||
cur = sqlite.Cursor(foo)
|
cur = sqlite.Cursor(foo)
|
||||||
self.fail("should have raised a ValueError")
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'This test requires threading.')
|
@unittest.skipUnless(threading, 'This test requires threading.')
|
||||||
class ThreadTests(unittest.TestCase):
|
class ThreadTests(unittest.TestCase):
|
||||||
|
@ -708,22 +659,21 @@ class ExtensionTests(unittest.TestCase):
|
||||||
def CheckScriptSyntaxError(self):
|
def CheckScriptSyntaxError(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
raised = False
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
try:
|
|
||||||
cur.executescript("create table test(x); asdf; create table test2(x)")
|
cur.executescript("create table test(x); asdf; create table test2(x)")
|
||||||
except sqlite.OperationalError:
|
|
||||||
raised = True
|
|
||||||
self.assertEqual(raised, True, "should have raised an exception")
|
|
||||||
|
|
||||||
def CheckScriptErrorNormal(self):
|
def CheckScriptErrorNormal(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
raised = False
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
try:
|
|
||||||
cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
|
cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
|
||||||
except sqlite.OperationalError:
|
|
||||||
raised = True
|
def CheckCursorExecutescriptAsBytes(self):
|
||||||
self.assertEqual(raised, True, "should have raised an exception")
|
con = sqlite.connect(":memory:")
|
||||||
|
cur = con.cursor()
|
||||||
|
with self.assertRaises(ValueError) as cm:
|
||||||
|
cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
|
||||||
|
self.assertEqual(str(cm.exception), 'script argument must be unicode.')
|
||||||
|
|
||||||
def CheckConnectionExecute(self):
|
def CheckConnectionExecute(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
|
@ -745,68 +695,37 @@ class ExtensionTests(unittest.TestCase):
|
||||||
self.assertEqual(result, 5, "Basic test of Connection.executescript")
|
self.assertEqual(result, 5, "Basic test of Connection.executescript")
|
||||||
|
|
||||||
class ClosedConTests(unittest.TestCase):
|
class ClosedConTests(unittest.TestCase):
|
||||||
def setUp(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckClosedConCursor(self):
|
def CheckClosedConCursor(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedConCommit(self):
|
def CheckClosedConCommit(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.commit()
|
con.commit()
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedConRollback(self):
|
def CheckClosedConRollback(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.rollback()
|
con.rollback()
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedCurExecute(self):
|
def CheckClosedCurExecute(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
con.close()
|
con.close()
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
cur.execute("select 4")
|
cur.execute("select 4")
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedCreateFunction(self):
|
def CheckClosedCreateFunction(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
def f(x): return 17
|
def f(x): return 17
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.create_function("foo", 1, f)
|
con.create_function("foo", 1, f)
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedCreateAggregate(self):
|
def CheckClosedCreateAggregate(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
|
@ -818,57 +737,31 @@ class ClosedConTests(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
def finalize(self):
|
def finalize(self):
|
||||||
return 17
|
return 17
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.create_aggregate("foo", 1, Agg)
|
con.create_aggregate("foo", 1, Agg)
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedSetAuthorizer(self):
|
def CheckClosedSetAuthorizer(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
def authorizer(*args):
|
def authorizer(*args):
|
||||||
return sqlite.DENY
|
return sqlite.DENY
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.set_authorizer(authorizer)
|
con.set_authorizer(authorizer)
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedSetProgressCallback(self):
|
def CheckClosedSetProgressCallback(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
def progress(): pass
|
def progress(): pass
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.set_progress_handler(progress, 100)
|
con.set_progress_handler(progress, 100)
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
def CheckClosedCall(self):
|
def CheckClosedCall(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.close()
|
con.close()
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con()
|
con()
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError")
|
|
||||||
|
|
||||||
class ClosedCurTests(unittest.TestCase):
|
class ClosedCurTests(unittest.TestCase):
|
||||||
def setUp(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckClosed(self):
|
def CheckClosed(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
|
@ -882,15 +775,9 @@ class ClosedCurTests(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
method = getattr(cur, method_name)
|
method = getattr(cur, method_name)
|
||||||
|
|
||||||
method(*params)
|
method(*params)
|
||||||
self.fail("Should have raised a ProgrammingError: method " + method_name)
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("Should have raised a ProgrammingError: " + method_name)
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
module_suite = unittest.makeSuite(ModuleTests, "Check")
|
module_suite = unittest.makeSuite(ModuleTests, "Check")
|
||||||
|
|
|
@ -25,27 +25,16 @@ import unittest
|
||||||
import sqlite3 as sqlite
|
import sqlite3 as sqlite
|
||||||
|
|
||||||
class CollationTests(unittest.TestCase):
|
class CollationTests(unittest.TestCase):
|
||||||
def setUp(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckCreateCollationNotCallable(self):
|
def CheckCreateCollationNotCallable(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
try:
|
with self.assertRaises(TypeError) as cm:
|
||||||
con.create_collation("X", 42)
|
con.create_collation("X", 42)
|
||||||
self.fail("should have raised a TypeError")
|
self.assertEqual(str(cm.exception), 'parameter must be callable')
|
||||||
except TypeError as e:
|
|
||||||
self.assertEqual(e.args[0], "parameter must be callable")
|
|
||||||
|
|
||||||
def CheckCreateCollationNotAscii(self):
|
def CheckCreateCollationNotAscii(self):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
con.create_collation("collä", lambda x, y: (x > y) - (x < y))
|
con.create_collation("collä", lambda x, y: (x > y) - (x < y))
|
||||||
self.fail("should have raised a ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError as e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 1),
|
@unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 1),
|
||||||
'old SQLite versions crash on this test')
|
'old SQLite versions crash on this test')
|
||||||
|
@ -66,15 +55,13 @@ class CollationTests(unittest.TestCase):
|
||||||
) order by x collate mycoll
|
) order by x collate mycoll
|
||||||
"""
|
"""
|
||||||
result = con.execute(sql).fetchall()
|
result = con.execute(sql).fetchall()
|
||||||
if result[0][0] != "c" or result[1][0] != "b" or result[2][0] != "a":
|
self.assertEqual(result, [('c',), ('b',), ('a',)],
|
||||||
self.fail("the expected order was not returned")
|
msg='the expected order was not returned')
|
||||||
|
|
||||||
con.create_collation("mycoll", None)
|
con.create_collation("mycoll", None)
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
result = con.execute(sql).fetchall()
|
result = con.execute(sql).fetchall()
|
||||||
self.fail("should have raised an OperationalError")
|
self.assertEqual(str(cm.exception), 'no such collation sequence: mycoll')
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
self.assertEqual(e.args[0].lower(), "no such collation sequence: mycoll")
|
|
||||||
|
|
||||||
def CheckCollationReturnsLargeInteger(self):
|
def CheckCollationReturnsLargeInteger(self):
|
||||||
def mycoll(x, y):
|
def mycoll(x, y):
|
||||||
|
@ -106,8 +93,8 @@ class CollationTests(unittest.TestCase):
|
||||||
result = con.execute("""
|
result = con.execute("""
|
||||||
select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
|
select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
|
||||||
""").fetchall()
|
""").fetchall()
|
||||||
if result[0][0] != 'b' or result[1][0] != 'a':
|
self.assertEqual(result[0][0], 'b')
|
||||||
self.fail("wrong collation function is used")
|
self.assertEqual(result[1][0], 'a')
|
||||||
|
|
||||||
def CheckDeregisterCollation(self):
|
def CheckDeregisterCollation(self):
|
||||||
"""
|
"""
|
||||||
|
@ -117,12 +104,9 @@ class CollationTests(unittest.TestCase):
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.create_collation("mycoll", lambda x, y: (x > y) - (x < y))
|
con.create_collation("mycoll", lambda x, y: (x > y) - (x < y))
|
||||||
con.create_collation("mycoll", None)
|
con.create_collation("mycoll", None)
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")
|
con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")
|
||||||
self.fail("should have raised an OperationalError")
|
self.assertEqual(str(cm.exception), 'no such collation sequence: mycoll')
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
if not e.args[0].startswith("no such collation sequence"):
|
|
||||||
self.fail("wrong OperationalError raised")
|
|
||||||
|
|
||||||
class ProgressTests(unittest.TestCase):
|
class ProgressTests(unittest.TestCase):
|
||||||
def CheckProgressHandlerUsed(self):
|
def CheckProgressHandlerUsed(self):
|
||||||
|
|
|
@ -84,9 +84,8 @@ class RegressionTests(unittest.TestCase):
|
||||||
cur.execute("select 1 x union select " + str(i))
|
cur.execute("select 1 x union select " + str(i))
|
||||||
con.close()
|
con.close()
|
||||||
|
|
||||||
|
@unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2), 'needs sqlite 3.2.2 or newer')
|
||||||
def CheckOnConflictRollback(self):
|
def CheckOnConflictRollback(self):
|
||||||
if sqlite.sqlite_version_info < (3, 2, 2):
|
|
||||||
return
|
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
con.execute("create table foo(x, unique(x) on conflict rollback)")
|
con.execute("create table foo(x, unique(x) on conflict rollback)")
|
||||||
con.execute("insert into foo(x) values (1)")
|
con.execute("insert into foo(x) values (1)")
|
||||||
|
@ -134,17 +133,11 @@ class RegressionTests(unittest.TestCase):
|
||||||
def CheckErrorMsgDecodeError(self):
|
def CheckErrorMsgDecodeError(self):
|
||||||
# When porting the module to Python 3.0, the error message about
|
# When porting the module to Python 3.0, the error message about
|
||||||
# decoding errors disappeared. This verifies they're back again.
|
# decoding errors disappeared. This verifies they're back again.
|
||||||
failure = None
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
try:
|
|
||||||
self.con.execute("select 'xxx' || ? || 'yyy' colname",
|
self.con.execute("select 'xxx' || ? || 'yyy' colname",
|
||||||
(bytes(bytearray([250])),)).fetchone()
|
(bytes(bytearray([250])),)).fetchone()
|
||||||
failure = "should have raised an OperationalError with detailed description"
|
msg = "Could not decode to UTF-8 column 'colname' with text 'xxx"
|
||||||
except sqlite.OperationalError as e:
|
self.assertIn(msg, str(cm.exception))
|
||||||
msg = e.args[0]
|
|
||||||
if not msg.startswith("Could not decode to UTF-8 column 'colname' with text 'xxx"):
|
|
||||||
failure = "OperationalError did not have expected description text"
|
|
||||||
if failure:
|
|
||||||
self.fail(failure)
|
|
||||||
|
|
||||||
def CheckRegisterAdapter(self):
|
def CheckRegisterAdapter(self):
|
||||||
"""
|
"""
|
||||||
|
@ -170,14 +163,8 @@ class RegressionTests(unittest.TestCase):
|
||||||
|
|
||||||
con = sqlite.connect(":memory:")
|
con = sqlite.connect(":memory:")
|
||||||
cur = Cursor(con)
|
cur = Cursor(con)
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
cur.execute("select 4+5").fetchall()
|
cur.execute("select 4+5").fetchall()
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
|
|
||||||
|
|
||||||
def CheckStrSubclass(self):
|
def CheckStrSubclass(self):
|
||||||
"""
|
"""
|
||||||
|
@ -196,13 +183,8 @@ class RegressionTests(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
con = Connection(":memory:")
|
con = Connection(":memory:")
|
||||||
try:
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
except sqlite.ProgrammingError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised ProgrammingError")
|
|
||||||
|
|
||||||
def CheckCursorRegistration(self):
|
def CheckCursorRegistration(self):
|
||||||
"""
|
"""
|
||||||
|
@ -223,13 +205,8 @@ class RegressionTests(unittest.TestCase):
|
||||||
cur.executemany("insert into foo(x) values (?)", [(3,), (4,), (5,)])
|
cur.executemany("insert into foo(x) values (?)", [(3,), (4,), (5,)])
|
||||||
cur.execute("select x from foo")
|
cur.execute("select x from foo")
|
||||||
con.rollback()
|
con.rollback()
|
||||||
try:
|
with self.assertRaises(sqlite.InterfaceError):
|
||||||
cur.fetchall()
|
cur.fetchall()
|
||||||
self.fail("should have raised InterfaceError")
|
|
||||||
except sqlite.InterfaceError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised InterfaceError")
|
|
||||||
|
|
||||||
def CheckAutoCommit(self):
|
def CheckAutoCommit(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -111,39 +111,25 @@ class TransactionTests(unittest.TestCase):
|
||||||
res = self.cur2.fetchall()
|
res = self.cur2.fetchall()
|
||||||
self.assertEqual(len(res), 1)
|
self.assertEqual(len(res), 1)
|
||||||
|
|
||||||
|
@unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2),
|
||||||
|
'test hangs on sqlite versions older than 3.2.2')
|
||||||
def CheckRaiseTimeout(self):
|
def CheckRaiseTimeout(self):
|
||||||
if sqlite.sqlite_version_info < (3, 2, 2):
|
|
||||||
# This will fail (hang) on earlier versions of sqlite.
|
|
||||||
# Determine exact version it was fixed. 3.2.1 hangs.
|
|
||||||
return
|
|
||||||
self.cur1.execute("create table test(i)")
|
self.cur1.execute("create table test(i)")
|
||||||
self.cur1.execute("insert into test(i) values (5)")
|
self.cur1.execute("insert into test(i) values (5)")
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
self.cur2.execute("insert into test(i) values (5)")
|
self.cur2.execute("insert into test(i) values (5)")
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
except sqlite.OperationalError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
|
|
||||||
|
@unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2),
|
||||||
|
'test hangs on sqlite versions older than 3.2.2')
|
||||||
def CheckLocking(self):
|
def CheckLocking(self):
|
||||||
"""
|
"""
|
||||||
This tests the improved concurrency with pysqlite 2.3.4. You needed
|
This tests the improved concurrency with pysqlite 2.3.4. You needed
|
||||||
to roll back con2 before you could commit con1.
|
to roll back con2 before you could commit con1.
|
||||||
"""
|
"""
|
||||||
if sqlite.sqlite_version_info < (3, 2, 2):
|
|
||||||
# This will fail (hang) on earlier versions of sqlite.
|
|
||||||
# Determine exact version it was fixed. 3.2.1 hangs.
|
|
||||||
return
|
|
||||||
self.cur1.execute("create table test(i)")
|
self.cur1.execute("create table test(i)")
|
||||||
self.cur1.execute("insert into test(i) values (5)")
|
self.cur1.execute("insert into test(i) values (5)")
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
self.cur2.execute("insert into test(i) values (5)")
|
self.cur2.execute("insert into test(i) values (5)")
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
except sqlite.OperationalError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
# NO self.con2.rollback() HERE!!!
|
# NO self.con2.rollback() HERE!!!
|
||||||
self.con1.commit()
|
self.con1.commit()
|
||||||
|
|
||||||
|
@ -159,13 +145,8 @@ class TransactionTests(unittest.TestCase):
|
||||||
cur.execute("select 1 union select 2 union select 3")
|
cur.execute("select 1 union select 2 union select 3")
|
||||||
|
|
||||||
con.rollback()
|
con.rollback()
|
||||||
try:
|
with self.assertRaises(sqlite.InterfaceError):
|
||||||
cur.fetchall()
|
cur.fetchall()
|
||||||
self.fail("InterfaceError should have been raised")
|
|
||||||
except sqlite.InterfaceError as e:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("InterfaceError should have been raised")
|
|
||||||
|
|
||||||
class SpecialCommandTests(unittest.TestCase):
|
class SpecialCommandTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -185,24 +185,14 @@ class DeclTypesTests(unittest.TestCase):
|
||||||
def CheckUnsupportedSeq(self):
|
def CheckUnsupportedSeq(self):
|
||||||
class Bar: pass
|
class Bar: pass
|
||||||
val = Bar()
|
val = Bar()
|
||||||
try:
|
with self.assertRaises(sqlite.InterfaceError):
|
||||||
self.cur.execute("insert into test(f) values (?)", (val,))
|
self.cur.execute("insert into test(f) values (?)", (val,))
|
||||||
self.fail("should have raised an InterfaceError")
|
|
||||||
except sqlite.InterfaceError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised an InterfaceError")
|
|
||||||
|
|
||||||
def CheckUnsupportedDict(self):
|
def CheckUnsupportedDict(self):
|
||||||
class Bar: pass
|
class Bar: pass
|
||||||
val = Bar()
|
val = Bar()
|
||||||
try:
|
with self.assertRaises(sqlite.InterfaceError):
|
||||||
self.cur.execute("insert into test(f) values (:val)", {"val": val})
|
self.cur.execute("insert into test(f) values (:val)", {"val": val})
|
||||||
self.fail("should have raised an InterfaceError")
|
|
||||||
except sqlite.InterfaceError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
self.fail("should have raised an InterfaceError")
|
|
||||||
|
|
||||||
def CheckBlob(self):
|
def CheckBlob(self):
|
||||||
# default
|
# default
|
||||||
|
@ -350,11 +340,9 @@ class DateTimeTests(unittest.TestCase):
|
||||||
ts2 = self.cur.fetchone()[0]
|
ts2 = self.cur.fetchone()[0]
|
||||||
self.assertEqual(ts, ts2)
|
self.assertEqual(ts, ts2)
|
||||||
|
|
||||||
|
@unittest.skipIf(sqlite.sqlite_version_info < (3, 1),
|
||||||
|
'the date functions are available on 3.1 or later')
|
||||||
def CheckSqlTimestamp(self):
|
def CheckSqlTimestamp(self):
|
||||||
# The date functions are only available in SQLite version 3.1 or later
|
|
||||||
if sqlite.sqlite_version_info < (3, 1):
|
|
||||||
return
|
|
||||||
|
|
||||||
# SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time.
|
# SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time.
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
self.cur.execute("insert into test(ts) values (current_timestamp)")
|
self.cur.execute("insert into test(ts) values (current_timestamp)")
|
||||||
|
|
|
@ -162,11 +162,8 @@ class FunctionTests(unittest.TestCase):
|
||||||
self.con.close()
|
self.con.close()
|
||||||
|
|
||||||
def CheckFuncErrorOnCreate(self):
|
def CheckFuncErrorOnCreate(self):
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
self.con.create_function("bla", -100, lambda x: 2*x)
|
self.con.create_function("bla", -100, lambda x: 2*x)
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
except sqlite.OperationalError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckFuncRefCount(self):
|
def CheckFuncRefCount(self):
|
||||||
def getfunc():
|
def getfunc():
|
||||||
|
@ -231,12 +228,10 @@ class FunctionTests(unittest.TestCase):
|
||||||
|
|
||||||
def CheckFuncException(self):
|
def CheckFuncException(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
cur.execute("select raiseexception()")
|
cur.execute("select raiseexception()")
|
||||||
cur.fetchone()
|
cur.fetchone()
|
||||||
self.fail("should have raised OperationalError")
|
self.assertEqual(str(cm.exception), 'user-defined function raised exception')
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
self.assertEqual(e.args[0], 'user-defined function raised exception')
|
|
||||||
|
|
||||||
def CheckParamString(self):
|
def CheckParamString(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
|
@ -312,55 +307,42 @@ class AggregateTests(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def CheckAggrErrorOnCreate(self):
|
def CheckAggrErrorOnCreate(self):
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError):
|
||||||
self.con.create_function("bla", -100, AggrSum)
|
self.con.create_function("bla", -100, AggrSum)
|
||||||
self.fail("should have raised an OperationalError")
|
|
||||||
except sqlite.OperationalError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CheckAggrNoStep(self):
|
def CheckAggrNoStep(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
try:
|
with self.assertRaises(AttributeError) as cm:
|
||||||
cur.execute("select nostep(t) from test")
|
cur.execute("select nostep(t) from test")
|
||||||
self.fail("should have raised an AttributeError")
|
self.assertEqual(str(cm.exception), "'AggrNoStep' object has no attribute 'step'")
|
||||||
except AttributeError as e:
|
|
||||||
self.assertEqual(e.args[0], "'AggrNoStep' object has no attribute 'step'")
|
|
||||||
|
|
||||||
def CheckAggrNoFinalize(self):
|
def CheckAggrNoFinalize(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
cur.execute("select nofinalize(t) from test")
|
cur.execute("select nofinalize(t) from test")
|
||||||
val = cur.fetchone()[0]
|
val = cur.fetchone()[0]
|
||||||
self.fail("should have raised an OperationalError")
|
self.assertEqual(str(cm.exception), "user-defined aggregate's 'finalize' method raised error")
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
self.assertEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
|
|
||||||
|
|
||||||
def CheckAggrExceptionInInit(self):
|
def CheckAggrExceptionInInit(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
cur.execute("select excInit(t) from test")
|
cur.execute("select excInit(t) from test")
|
||||||
val = cur.fetchone()[0]
|
val = cur.fetchone()[0]
|
||||||
self.fail("should have raised an OperationalError")
|
self.assertEqual(str(cm.exception), "user-defined aggregate's '__init__' method raised error")
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
self.assertEqual(e.args[0], "user-defined aggregate's '__init__' method raised error")
|
|
||||||
|
|
||||||
def CheckAggrExceptionInStep(self):
|
def CheckAggrExceptionInStep(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
cur.execute("select excStep(t) from test")
|
cur.execute("select excStep(t) from test")
|
||||||
val = cur.fetchone()[0]
|
val = cur.fetchone()[0]
|
||||||
self.fail("should have raised an OperationalError")
|
self.assertEqual(str(cm.exception), "user-defined aggregate's 'step' method raised error")
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
self.assertEqual(e.args[0], "user-defined aggregate's 'step' method raised error")
|
|
||||||
|
|
||||||
def CheckAggrExceptionInFinalize(self):
|
def CheckAggrExceptionInFinalize(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
try:
|
with self.assertRaises(sqlite.OperationalError) as cm:
|
||||||
cur.execute("select excFinalize(t) from test")
|
cur.execute("select excFinalize(t) from test")
|
||||||
val = cur.fetchone()[0]
|
val = cur.fetchone()[0]
|
||||||
self.fail("should have raised an OperationalError")
|
self.assertEqual(str(cm.exception), "user-defined aggregate's 'finalize' method raised error")
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
self.assertEqual(e.args[0], "user-defined aggregate's 'finalize' method raised error")
|
|
||||||
|
|
||||||
def CheckAggrCheckParamStr(self):
|
def CheckAggrCheckParamStr(self):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
|
@ -433,22 +415,14 @@ class AuthorizerTests(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_table_access(self):
|
def test_table_access(self):
|
||||||
try:
|
with self.assertRaises(sqlite.DatabaseError) as cm:
|
||||||
self.con.execute("select * from t2")
|
self.con.execute("select * from t2")
|
||||||
except sqlite.DatabaseError as e:
|
self.assertIn('prohibited', str(cm.exception))
|
||||||
if not e.args[0].endswith("prohibited"):
|
|
||||||
self.fail("wrong exception text: %s" % e.args[0])
|
|
||||||
return
|
|
||||||
self.fail("should have raised an exception due to missing privileges")
|
|
||||||
|
|
||||||
def test_column_access(self):
|
def test_column_access(self):
|
||||||
try:
|
with self.assertRaises(sqlite.DatabaseError) as cm:
|
||||||
self.con.execute("select c2 from t1")
|
self.con.execute("select c2 from t1")
|
||||||
except sqlite.DatabaseError as e:
|
self.assertIn('prohibited', str(cm.exception))
|
||||||
if not e.args[0].endswith("prohibited"):
|
|
||||||
self.fail("wrong exception text: %s" % e.args[0])
|
|
||||||
return
|
|
||||||
self.fail("should have raised an exception due to missing privileges")
|
|
||||||
|
|
||||||
class AuthorizerRaiseExceptionTests(AuthorizerTests):
|
class AuthorizerRaiseExceptionTests(AuthorizerTests):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -1349,7 +1349,8 @@ def transient_internet(resource_name, *, timeout=30.0, errnos=()):
|
||||||
500 <= err.code <= 599) or
|
500 <= err.code <= 599) or
|
||||||
(isinstance(err, urllib.error.URLError) and
|
(isinstance(err, urllib.error.URLError) and
|
||||||
(("ConnectionRefusedError" in err.reason) or
|
(("ConnectionRefusedError" in err.reason) or
|
||||||
("TimeoutError" in err.reason))) or
|
("TimeoutError" in err.reason) or
|
||||||
|
("EOFError" in err.reason))) or
|
||||||
n in captured_errnos):
|
n in captured_errnos):
|
||||||
if not verbose:
|
if not verbose:
|
||||||
sys.stderr.write(denied.args[0] + "\n")
|
sys.stderr.write(denied.args[0] + "\n")
|
||||||
|
|
|
@ -73,6 +73,10 @@ def run_python_until_end(*args, **env_vars):
|
||||||
# Need to preserve the original environment, for in-place testing of
|
# Need to preserve the original environment, for in-place testing of
|
||||||
# shared library builds.
|
# shared library builds.
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
|
# set TERM='' unless the TERM environment variable is passed explicitly
|
||||||
|
# see issues #11390 and #18300
|
||||||
|
if 'TERM' not in env_vars:
|
||||||
|
env['TERM'] = ''
|
||||||
# But a special flag that can be set to override -- in this case, the
|
# But a special flag that can be set to override -- in this case, the
|
||||||
# caller is responsible to pass the full environment.
|
# caller is responsible to pass the full environment.
|
||||||
if env_vars.pop('__cleanenv', None):
|
if env_vars.pop('__cleanenv', None):
|
||||||
|
|
|
@ -1185,14 +1185,14 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
|
||||||
test_utils.run_briefly(self.loop) # allow transport to close
|
test_utils.run_briefly(self.loop) # allow transport to close
|
||||||
|
|
||||||
sock.family = socket.AF_INET6
|
sock.family = socket.AF_INET6
|
||||||
coro = self.loop.create_connection(asyncio.Protocol, '::2', 80)
|
coro = self.loop.create_connection(asyncio.Protocol, '::1', 80)
|
||||||
t, p = self.loop.run_until_complete(coro)
|
t, p = self.loop.run_until_complete(coro)
|
||||||
try:
|
try:
|
||||||
# Without inet_pton we use getaddrinfo, which transforms ('::2', 80)
|
# Without inet_pton we use getaddrinfo, which transforms ('::1', 80)
|
||||||
# to ('::0.0.0.2', 80, 0, 0). The last 0s are flow info, scope id.
|
# to ('::1', 80, 0, 0). The last 0s are flow info, scope id.
|
||||||
[address] = sock.connect.call_args[0]
|
[address] = sock.connect.call_args[0]
|
||||||
host, port = address[:2]
|
host, port = address[:2]
|
||||||
self.assertRegex(host, r'::(0\.)*2')
|
self.assertRegex(host, r'::(0\.)*1')
|
||||||
self.assertEqual(port, 80)
|
self.assertEqual(port, 80)
|
||||||
_, kwargs = m_socket.socket.call_args
|
_, kwargs = m_socket.socket.call_args
|
||||||
self.assertEqual(kwargs['family'], m_socket.AF_INET6)
|
self.assertEqual(kwargs['family'], m_socket.AF_INET6)
|
||||||
|
|
|
@ -472,6 +472,13 @@ if 1:
|
||||||
d = {f(): f(), f(): f()}
|
d = {f(): f(), f(): f()}
|
||||||
self.assertEqual(d, {1: 2, 3: 4})
|
self.assertEqual(d, {1: 2, 3: 4})
|
||||||
|
|
||||||
|
def test_compile_filename(self):
|
||||||
|
for filename in ('file.py', b'file.py',
|
||||||
|
bytearray(b'file.py'), memoryview(b'file.py')):
|
||||||
|
code = compile('pass', filename, 'exec')
|
||||||
|
self.assertEqual(code.co_filename, 'file.py')
|
||||||
|
self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec')
|
||||||
|
|
||||||
@support.cpython_only
|
@support.cpython_only
|
||||||
def test_same_filename_used(self):
|
def test_same_filename_used(self):
|
||||||
s = """def f(): pass\ndef g(): pass"""
|
s = """def f(): pass\ndef g(): pass"""
|
||||||
|
|
|
@ -762,6 +762,40 @@ class TestExitStack(unittest.TestCase):
|
||||||
stack.push(cm)
|
stack.push(cm)
|
||||||
self.assertIs(stack._exit_callbacks[-1], cm)
|
self.assertIs(stack._exit_callbacks[-1], cm)
|
||||||
|
|
||||||
|
def test_dont_reraise_RuntimeError(self):
|
||||||
|
# https://bugs.python.org/issue27122
|
||||||
|
class UniqueException(Exception): pass
|
||||||
|
class UniqueRuntimeError(RuntimeError): pass
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def second():
|
||||||
|
try:
|
||||||
|
yield 1
|
||||||
|
except Exception as exc:
|
||||||
|
raise UniqueException("new exception") from exc
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def first():
|
||||||
|
try:
|
||||||
|
yield 1
|
||||||
|
except Exception as exc:
|
||||||
|
raise exc
|
||||||
|
|
||||||
|
# The UniqueRuntimeError should be caught by second()'s exception
|
||||||
|
# handler which chain raised a new UniqueException.
|
||||||
|
with self.assertRaises(UniqueException) as err_ctx:
|
||||||
|
with ExitStack() as es_ctx:
|
||||||
|
es_ctx.enter_context(second())
|
||||||
|
es_ctx.enter_context(first())
|
||||||
|
raise UniqueRuntimeError("please no infinite loop.")
|
||||||
|
|
||||||
|
exc = err_ctx.exception
|
||||||
|
self.assertIsInstance(exc, UniqueException)
|
||||||
|
self.assertIsInstance(exc.__context__, UniqueRuntimeError)
|
||||||
|
self.assertIsNone(exc.__context__.__context__)
|
||||||
|
self.assertIsNone(exc.__context__.__cause__)
|
||||||
|
self.assertIs(exc.__cause__, exc.__context__)
|
||||||
|
|
||||||
|
|
||||||
class TestRedirectStream:
|
class TestRedirectStream:
|
||||||
|
|
||||||
|
|
|
@ -1423,7 +1423,7 @@ class CoroutineTest(unittest.TestCase):
|
||||||
|
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("error")
|
warnings.simplefilter("error")
|
||||||
# Test that __aiter__ that returns an asyncronous iterator
|
# Test that __aiter__ that returns an asynchronous iterator
|
||||||
# directly does not throw any warnings.
|
# directly does not throw any warnings.
|
||||||
run_async(main())
|
run_async(main())
|
||||||
self.assertEqual(I, 111011)
|
self.assertEqual(I, 111011)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import string
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -399,6 +400,55 @@ class MiscTests(unittest.TestCase):
|
||||||
|
|
||||||
class TestAscii(unittest.TestCase):
|
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):
|
||||||
|
with self.subTest(ch=c, func=func):
|
||||||
|
self.assertEqual(func(i), expected)
|
||||||
|
self.assertEqual(func(c), expected)
|
||||||
|
|
||||||
|
for i in range(256):
|
||||||
|
c = chr(i)
|
||||||
|
b = bytes([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):
|
def test_unctrl(self):
|
||||||
unctrl = curses.ascii.unctrl
|
unctrl = curses.ascii.unctrl
|
||||||
self.assertEqual(unctrl('a'), 'a')
|
self.assertEqual(unctrl('a'), 'a')
|
||||||
|
@ -408,9 +458,13 @@ class TestAscii(unittest.TestCase):
|
||||||
self.assertEqual(unctrl('\x7f'), '^?')
|
self.assertEqual(unctrl('\x7f'), '^?')
|
||||||
self.assertEqual(unctrl('\n'), '^J')
|
self.assertEqual(unctrl('\n'), '^J')
|
||||||
self.assertEqual(unctrl('\0'), '^@')
|
self.assertEqual(unctrl('\0'), '^@')
|
||||||
|
self.assertEqual(unctrl(ord('A')), 'A')
|
||||||
|
self.assertEqual(unctrl(ord('\n')), '^J')
|
||||||
# Meta-bit characters
|
# Meta-bit characters
|
||||||
self.assertEqual(unctrl('\x8a'), '!^J')
|
self.assertEqual(unctrl('\x8a'), '!^J')
|
||||||
self.assertEqual(unctrl('\xc1'), '!A')
|
self.assertEqual(unctrl('\xc1'), '!A')
|
||||||
|
self.assertEqual(unctrl(ord('\x8a')), '!^J')
|
||||||
|
self.assertEqual(unctrl(ord('\xc1')), '!A')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -2491,7 +2491,8 @@ class PythonAPItests(unittest.TestCase):
|
||||||
Decimal = self.decimal.Decimal
|
Decimal = self.decimal.Decimal
|
||||||
|
|
||||||
class MyDecimal(Decimal):
|
class MyDecimal(Decimal):
|
||||||
pass
|
def __init__(self, _):
|
||||||
|
self.x = 'y'
|
||||||
|
|
||||||
self.assertTrue(issubclass(MyDecimal, Decimal))
|
self.assertTrue(issubclass(MyDecimal, Decimal))
|
||||||
|
|
||||||
|
@ -2499,6 +2500,8 @@ class PythonAPItests(unittest.TestCase):
|
||||||
self.assertEqual(type(r), MyDecimal)
|
self.assertEqual(type(r), MyDecimal)
|
||||||
self.assertEqual(str(r),
|
self.assertEqual(str(r),
|
||||||
'0.1000000000000000055511151231257827021181583404541015625')
|
'0.1000000000000000055511151231257827021181583404541015625')
|
||||||
|
self.assertEqual(r.x, 'y')
|
||||||
|
|
||||||
bigint = 12345678901234567890123456789
|
bigint = 12345678901234567890123456789
|
||||||
self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
|
self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
|
||||||
self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
|
self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
|
||||||
|
|
|
@ -2719,12 +2719,6 @@ output into something we can doctest against:
|
||||||
>>> def normalize(s):
|
>>> def normalize(s):
|
||||||
... return '\n'.join(s.decode().splitlines())
|
... return '\n'.join(s.decode().splitlines())
|
||||||
|
|
||||||
Note: we also pass TERM='' to all the assert_python calls to avoid a bug
|
|
||||||
in the readline library that is triggered in these tests because we are
|
|
||||||
running them in a new python process. See:
|
|
||||||
|
|
||||||
http://lists.gnu.org/archive/html/bug-readline/2013-06/msg00000.html
|
|
||||||
|
|
||||||
With those preliminaries out of the way, we'll start with a file with two
|
With those preliminaries out of the way, we'll start with a file with two
|
||||||
simple tests and no errors. We'll run both the unadorned doctest command, and
|
simple tests and no errors. We'll run both the unadorned doctest command, and
|
||||||
the verbose version, and then check the output:
|
the verbose version, and then check the output:
|
||||||
|
@ -2741,9 +2735,9 @@ the verbose version, and then check the output:
|
||||||
... _ = f.write('\n')
|
... _ = f.write('\n')
|
||||||
... _ = f.write('And that is it.\n')
|
... _ = f.write('And that is it.\n')
|
||||||
... rc1, out1, err1 = script_helper.assert_python_ok(
|
... rc1, out1, err1 = script_helper.assert_python_ok(
|
||||||
... '-m', 'doctest', fn, TERM='')
|
... '-m', 'doctest', fn)
|
||||||
... rc2, out2, err2 = script_helper.assert_python_ok(
|
... rc2, out2, err2 = script_helper.assert_python_ok(
|
||||||
... '-m', 'doctest', '-v', fn, TERM='')
|
... '-m', 'doctest', '-v', fn)
|
||||||
|
|
||||||
With no arguments and passing tests, we should get no output:
|
With no arguments and passing tests, we should get no output:
|
||||||
|
|
||||||
|
@ -2806,17 +2800,17 @@ text files).
|
||||||
... _ = f.write(' \"\"\"\n')
|
... _ = f.write(' \"\"\"\n')
|
||||||
... import shutil
|
... import shutil
|
||||||
... rc1, out1, err1 = script_helper.assert_python_failure(
|
... rc1, out1, err1 = script_helper.assert_python_failure(
|
||||||
... '-m', 'doctest', fn, fn2, TERM='')
|
... '-m', 'doctest', fn, fn2)
|
||||||
... rc2, out2, err2 = script_helper.assert_python_ok(
|
... rc2, out2, err2 = script_helper.assert_python_ok(
|
||||||
... '-m', 'doctest', '-o', 'ELLIPSIS', fn, TERM='')
|
... '-m', 'doctest', '-o', 'ELLIPSIS', fn)
|
||||||
... rc3, out3, err3 = script_helper.assert_python_ok(
|
... rc3, out3, err3 = script_helper.assert_python_ok(
|
||||||
... '-m', 'doctest', '-o', 'ELLIPSIS',
|
... '-m', 'doctest', '-o', 'ELLIPSIS',
|
||||||
... '-o', 'NORMALIZE_WHITESPACE', fn, fn2, TERM='')
|
... '-o', 'NORMALIZE_WHITESPACE', fn, fn2)
|
||||||
... rc4, out4, err4 = script_helper.assert_python_failure(
|
... rc4, out4, err4 = script_helper.assert_python_failure(
|
||||||
... '-m', 'doctest', '-f', fn, fn2, TERM='')
|
... '-m', 'doctest', '-f', fn, fn2)
|
||||||
... rc5, out5, err5 = script_helper.assert_python_ok(
|
... rc5, out5, err5 = script_helper.assert_python_ok(
|
||||||
... '-m', 'doctest', '-v', '-o', 'ELLIPSIS',
|
... '-m', 'doctest', '-v', '-o', 'ELLIPSIS',
|
||||||
... '-o', 'NORMALIZE_WHITESPACE', fn, fn2, TERM='')
|
... '-o', 'NORMALIZE_WHITESPACE', fn, fn2)
|
||||||
|
|
||||||
Our first test run will show the errors from the first file (doctest stops if a
|
Our first test run will show the errors from the first file (doctest stops if a
|
||||||
file has errors). Note that doctest test-run error output appears on stdout,
|
file has errors). Note that doctest test-run error output appears on stdout,
|
||||||
|
@ -2922,7 +2916,7 @@ We should also check some typical error cases.
|
||||||
Invalid file name:
|
Invalid file name:
|
||||||
|
|
||||||
>>> rc, out, err = script_helper.assert_python_failure(
|
>>> rc, out, err = script_helper.assert_python_failure(
|
||||||
... '-m', 'doctest', 'nosuchfile', TERM='')
|
... '-m', 'doctest', 'nosuchfile')
|
||||||
>>> rc, out
|
>>> rc, out
|
||||||
(1, b'')
|
(1, b'')
|
||||||
>>> print(normalize(err)) # doctest: +ELLIPSIS
|
>>> print(normalize(err)) # doctest: +ELLIPSIS
|
||||||
|
@ -2933,7 +2927,7 @@ Invalid file name:
|
||||||
Invalid doctest option:
|
Invalid doctest option:
|
||||||
|
|
||||||
>>> rc, out, err = script_helper.assert_python_failure(
|
>>> rc, out, err = script_helper.assert_python_failure(
|
||||||
... '-m', 'doctest', '-o', 'nosuchoption', TERM='')
|
... '-m', 'doctest', '-o', 'nosuchoption')
|
||||||
>>> rc, out
|
>>> rc, out
|
||||||
(2, b'')
|
(2, b'')
|
||||||
>>> print(normalize(err)) # doctest: +ELLIPSIS
|
>>> print(normalize(err)) # doctest: +ELLIPSIS
|
||||||
|
|
|
@ -57,6 +57,10 @@ Here we add keyword arguments
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: f() got multiple values for keyword argument 'a'
|
TypeError: f() got multiple values for keyword argument 'a'
|
||||||
|
>>> f(1, 2, a=3, **{'a': 4}, **{'a': 5})
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
TypeError: f() got multiple values for keyword argument 'a'
|
||||||
>>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7})
|
>>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7})
|
||||||
(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
|
(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
|
||||||
>>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9})
|
>>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9})
|
||||||
|
|
|
@ -217,6 +217,33 @@ class TestPartialC(TestPartial, unittest.TestCase):
|
||||||
['{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr)
|
['{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr)
|
||||||
for kwargs_repr in kwargs_reprs])
|
for kwargs_repr in kwargs_reprs])
|
||||||
|
|
||||||
|
def test_recursive_repr(self):
|
||||||
|
if self.partial is c_functools.partial:
|
||||||
|
name = 'functools.partial'
|
||||||
|
else:
|
||||||
|
name = self.partial.__name__
|
||||||
|
|
||||||
|
f = self.partial(capture)
|
||||||
|
f.__setstate__((f, (), {}, {}))
|
||||||
|
try:
|
||||||
|
self.assertEqual(repr(f), '%s(%s(...))' % (name, name))
|
||||||
|
finally:
|
||||||
|
f.__setstate__((capture, (), {}, {}))
|
||||||
|
|
||||||
|
f = self.partial(capture)
|
||||||
|
f.__setstate__((capture, (f,), {}, {}))
|
||||||
|
try:
|
||||||
|
self.assertEqual(repr(f), '%s(%r, %s(...))' % (name, capture, name))
|
||||||
|
finally:
|
||||||
|
f.__setstate__((capture, (), {}, {}))
|
||||||
|
|
||||||
|
f = self.partial(capture)
|
||||||
|
f.__setstate__((capture, (), {'a': f}, {}))
|
||||||
|
try:
|
||||||
|
self.assertEqual(repr(f), '%s(%r, a=%s(...))' % (name, capture, name))
|
||||||
|
finally:
|
||||||
|
f.__setstate__((capture, (), {}, {}))
|
||||||
|
|
||||||
def test_pickle(self):
|
def test_pickle(self):
|
||||||
f = self.partial(signature, ['asdf'], bar=[True])
|
f = self.partial(signature, ['asdf'], bar=[True])
|
||||||
f.attr = []
|
f.attr = []
|
||||||
|
@ -297,6 +324,40 @@ class TestPartialC(TestPartial, unittest.TestCase):
|
||||||
self.assertEqual(r, ((1, 2), {}))
|
self.assertEqual(r, ((1, 2), {}))
|
||||||
self.assertIs(type(r[0]), tuple)
|
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(RecursionError):
|
||||||
|
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
|
# Issue 6083: Reference counting bug
|
||||||
def test_setstate_refcount(self):
|
def test_setstate_refcount(self):
|
||||||
class BadSequence:
|
class BadSequence:
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import importlib
|
import importlib
|
||||||
from importlib import abc
|
from importlib import abc
|
||||||
from importlib import util
|
from importlib import util
|
||||||
|
import sys
|
||||||
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from . import util as test_util
|
from . import util as test_util
|
||||||
|
@ -122,12 +124,20 @@ class LazyLoaderTests(unittest.TestCase):
|
||||||
self.assertFalse(hasattr(module, '__name__'))
|
self.assertFalse(hasattr(module, '__name__'))
|
||||||
|
|
||||||
def test_module_substitution_error(self):
|
def test_module_substitution_error(self):
|
||||||
source_code = 'import sys; sys.modules[__name__] = 42'
|
|
||||||
module = self.new_module(source_code)
|
|
||||||
with test_util.uncache(TestingImporter.module_name):
|
with test_util.uncache(TestingImporter.module_name):
|
||||||
with self.assertRaises(ValueError):
|
fresh_module = types.ModuleType(TestingImporter.module_name)
|
||||||
|
sys.modules[TestingImporter.module_name] = fresh_module
|
||||||
|
module = self.new_module()
|
||||||
|
with self.assertRaisesRegex(ValueError, "substituted"):
|
||||||
module.__name__
|
module.__name__
|
||||||
|
|
||||||
|
def test_module_already_in_sys(self):
|
||||||
|
with test_util.uncache(TestingImporter.module_name):
|
||||||
|
module = self.new_module()
|
||||||
|
sys.modules[TestingImporter.module_name] = module
|
||||||
|
# Force the load; just care that no exception is raised.
|
||||||
|
module.__name__
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -627,6 +627,22 @@ class CompileTestCase(unittest.TestCase):
|
||||||
code2 = parser.compilest(st)
|
code2 = parser.compilest(st)
|
||||||
self.assertEqual(eval(code2), -3)
|
self.assertEqual(eval(code2), -3)
|
||||||
|
|
||||||
|
def test_compile_filename(self):
|
||||||
|
st = parser.expr('a + 5')
|
||||||
|
code = parser.compilest(st)
|
||||||
|
self.assertEqual(code.co_filename, '<syntax-tree>')
|
||||||
|
code = st.compile()
|
||||||
|
self.assertEqual(code.co_filename, '<syntax-tree>')
|
||||||
|
for filename in ('file.py', b'file.py',
|
||||||
|
bytearray(b'file.py'), memoryview(b'file.py')):
|
||||||
|
code = parser.compilest(st, filename)
|
||||||
|
self.assertEqual(code.co_filename, 'file.py')
|
||||||
|
code = st.compile(filename)
|
||||||
|
self.assertEqual(code.co_filename, 'file.py')
|
||||||
|
self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
|
||||||
|
self.assertRaises(TypeError, st.compile, list(b'file.py'))
|
||||||
|
|
||||||
|
|
||||||
class ParserStackLimitTestCase(unittest.TestCase):
|
class ParserStackLimitTestCase(unittest.TestCase):
|
||||||
"""try to push the parser to/over its limits.
|
"""try to push the parser to/over its limits.
|
||||||
see http://bugs.python.org/issue1881 for a discussion
|
see http://bugs.python.org/issue1881 for a discussion
|
||||||
|
|
|
@ -356,7 +356,7 @@ def get_pydoc_html(module):
|
||||||
def get_pydoc_link(module):
|
def get_pydoc_link(module):
|
||||||
"Returns a documentation web link of a module"
|
"Returns a documentation web link of a module"
|
||||||
dirname = os.path.dirname
|
dirname = os.path.dirname
|
||||||
basedir = os.path.join(dirname(dirname(__file__)))
|
basedir = dirname(dirname(__file__))
|
||||||
doc = pydoc.TextDoc()
|
doc = pydoc.TextDoc()
|
||||||
loc = doc.getdocloc(module, basedir=basedir)
|
loc = doc.getdocloc(module, basedir=basedir)
|
||||||
return loc
|
return loc
|
||||||
|
|
|
@ -1,15 +1,25 @@
|
||||||
"""
|
"""
|
||||||
Very minimal unittests for parts of the readline module.
|
Very minimal unittests for parts of the readline module.
|
||||||
"""
|
"""
|
||||||
|
from contextlib import ExitStack
|
||||||
|
from errno import EIO
|
||||||
import os
|
import os
|
||||||
|
import selectors
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import import_module, unlink
|
from test.support import import_module, unlink, TESTFN
|
||||||
from test.support.script_helper import assert_python_ok
|
from test.support.script_helper import assert_python_ok
|
||||||
|
|
||||||
# Skip tests if there is no readline module
|
# Skip tests if there is no readline module
|
||||||
readline = import_module('readline')
|
readline = import_module('readline')
|
||||||
|
|
||||||
|
is_editline = readline.__doc__ and "libedit" in readline.__doc__
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(readline, "clear_history"),
|
||||||
|
"The history update test cannot be run because the "
|
||||||
|
"clear_history method is not available.")
|
||||||
class TestHistoryManipulation (unittest.TestCase):
|
class TestHistoryManipulation (unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
These tests were added to check that the libedit emulation on OSX and the
|
These tests were added to check that the libedit emulation on OSX and the
|
||||||
|
@ -17,9 +27,6 @@ class TestHistoryManipulation (unittest.TestCase):
|
||||||
why the tests cover only a small subset of the interface.
|
why the tests cover only a small subset of the interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(readline, "clear_history"),
|
|
||||||
"The history update test cannot be run because the "
|
|
||||||
"clear_history method is not available.")
|
|
||||||
def testHistoryUpdates(self):
|
def testHistoryUpdates(self):
|
||||||
readline.clear_history()
|
readline.clear_history()
|
||||||
|
|
||||||
|
@ -82,11 +89,29 @@ class TestHistoryManipulation (unittest.TestCase):
|
||||||
# write_history_file can create the target
|
# write_history_file can create the target
|
||||||
readline.write_history_file(hfilename)
|
readline.write_history_file(hfilename)
|
||||||
|
|
||||||
|
def test_nonascii_history(self):
|
||||||
|
readline.clear_history()
|
||||||
|
try:
|
||||||
|
readline.add_history("entrée 1")
|
||||||
|
except UnicodeEncodeError as err:
|
||||||
|
self.skipTest("Locale cannot encode test data: " + format(err))
|
||||||
|
readline.add_history("entrée 2")
|
||||||
|
readline.replace_history_item(1, "entrée 22")
|
||||||
|
readline.write_history_file(TESTFN)
|
||||||
|
self.addCleanup(os.remove, TESTFN)
|
||||||
|
readline.clear_history()
|
||||||
|
readline.read_history_file(TESTFN)
|
||||||
|
if is_editline:
|
||||||
|
# An add_history() call seems to be required for get_history_
|
||||||
|
# item() to register items from the file
|
||||||
|
readline.add_history("dummy")
|
||||||
|
self.assertEqual(readline.get_history_item(1), "entrée 1")
|
||||||
|
self.assertEqual(readline.get_history_item(2), "entrée 22")
|
||||||
|
|
||||||
|
|
||||||
class TestReadline(unittest.TestCase):
|
class TestReadline(unittest.TestCase):
|
||||||
|
|
||||||
@unittest.skipIf(readline._READLINE_VERSION < 0x0600
|
@unittest.skipIf(readline._READLINE_VERSION < 0x0600 and not is_editline,
|
||||||
and "libedit" not in readline.__doc__,
|
|
||||||
"not supported in this library version")
|
"not supported in this library version")
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
# Issue #19884: Ensure that the ANSI sequence "\033[1034h" is not
|
# Issue #19884: Ensure that the ANSI sequence "\033[1034h" is not
|
||||||
|
@ -96,6 +121,130 @@ class TestReadline(unittest.TestCase):
|
||||||
TERM='xterm-256color')
|
TERM='xterm-256color')
|
||||||
self.assertEqual(stdout, b'')
|
self.assertEqual(stdout, b'')
|
||||||
|
|
||||||
|
def test_nonascii(self):
|
||||||
|
try:
|
||||||
|
readline.add_history("\xEB\xEF")
|
||||||
|
except UnicodeEncodeError as err:
|
||||||
|
self.skipTest("Locale cannot encode test data: " + format(err))
|
||||||
|
|
||||||
|
script = r"""import readline
|
||||||
|
|
||||||
|
is_editline = readline.__doc__ and "libedit" in readline.__doc__
|
||||||
|
inserted = "[\xEFnserted]"
|
||||||
|
macro = "|t\xEB[after]"
|
||||||
|
set_pre_input_hook = getattr(readline, "set_pre_input_hook", None)
|
||||||
|
if is_editline or not set_pre_input_hook:
|
||||||
|
# The insert_line() call via pre_input_hook() does nothing with Editline,
|
||||||
|
# so include the extra text that would have been inserted here
|
||||||
|
macro = inserted + macro
|
||||||
|
|
||||||
|
if is_editline:
|
||||||
|
readline.parse_and_bind(r'bind ^B ed-prev-char')
|
||||||
|
readline.parse_and_bind(r'bind "\t" rl_complete')
|
||||||
|
readline.parse_and_bind(r'bind -s ^A "{}"'.format(macro))
|
||||||
|
else:
|
||||||
|
readline.parse_and_bind(r'Control-b: backward-char')
|
||||||
|
readline.parse_and_bind(r'"\t": complete')
|
||||||
|
readline.parse_and_bind(r'set disable-completion off')
|
||||||
|
readline.parse_and_bind(r'set show-all-if-ambiguous off')
|
||||||
|
readline.parse_and_bind(r'set show-all-if-unmodified off')
|
||||||
|
readline.parse_and_bind(r'Control-a: "{}"'.format(macro))
|
||||||
|
|
||||||
|
def pre_input_hook():
|
||||||
|
readline.insert_text(inserted)
|
||||||
|
readline.redisplay()
|
||||||
|
if set_pre_input_hook:
|
||||||
|
set_pre_input_hook(pre_input_hook)
|
||||||
|
|
||||||
|
def completer(text, state):
|
||||||
|
if text == "t\xEB":
|
||||||
|
if state == 0:
|
||||||
|
print("text", ascii(text))
|
||||||
|
print("line", ascii(readline.get_line_buffer()))
|
||||||
|
print("indexes", readline.get_begidx(), readline.get_endidx())
|
||||||
|
return "t\xEBnt"
|
||||||
|
if state == 1:
|
||||||
|
return "t\xEBxt"
|
||||||
|
if text == "t\xEBx" and state == 0:
|
||||||
|
return "t\xEBxt"
|
||||||
|
return None
|
||||||
|
readline.set_completer(completer)
|
||||||
|
|
||||||
|
def display(substitution, matches, longest_match_length):
|
||||||
|
print("substitution", ascii(substitution))
|
||||||
|
print("matches", ascii(matches))
|
||||||
|
readline.set_completion_display_matches_hook(display)
|
||||||
|
|
||||||
|
print("result", ascii(input()))
|
||||||
|
print("history", ascii(readline.get_history_item(1)))
|
||||||
|
"""
|
||||||
|
|
||||||
|
input = b"\x01" # Ctrl-A, expands to "|t\xEB[after]"
|
||||||
|
input += b"\x02" * len("[after]") # Move cursor back
|
||||||
|
input += b"\t\t" # Display possible completions
|
||||||
|
input += b"x\t" # Complete "t\xEBx" -> "t\xEBxt"
|
||||||
|
input += b"\r"
|
||||||
|
output = run_pty(script, input)
|
||||||
|
self.assertIn(b"text 't\\xeb'\r\n", output)
|
||||||
|
self.assertIn(b"line '[\\xefnserted]|t\\xeb[after]'\r\n", output)
|
||||||
|
self.assertIn(b"indexes 11 13\r\n", output)
|
||||||
|
if not is_editline and hasattr(readline, "set_pre_input_hook"):
|
||||||
|
self.assertIn(b"substitution 't\\xeb'\r\n", output)
|
||||||
|
self.assertIn(b"matches ['t\\xebnt', 't\\xebxt']\r\n", output)
|
||||||
|
expected = br"'[\xefnserted]|t\xebxt[after]'"
|
||||||
|
self.assertIn(b"result " + expected + b"\r\n", output)
|
||||||
|
self.assertIn(b"history " + expected + b"\r\n", output)
|
||||||
|
|
||||||
|
|
||||||
|
def run_pty(script, input=b"dummy input\r"):
|
||||||
|
pty = import_module('pty')
|
||||||
|
output = bytearray()
|
||||||
|
[master, slave] = pty.openpty()
|
||||||
|
args = (sys.executable, '-c', script)
|
||||||
|
proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave)
|
||||||
|
os.close(slave)
|
||||||
|
with ExitStack() as cleanup:
|
||||||
|
cleanup.enter_context(proc)
|
||||||
|
def terminate(proc):
|
||||||
|
try:
|
||||||
|
proc.terminate()
|
||||||
|
except ProcessLookupError:
|
||||||
|
# Workaround for Open/Net BSD bug (Issue 16762)
|
||||||
|
pass
|
||||||
|
cleanup.callback(terminate, proc)
|
||||||
|
cleanup.callback(os.close, master)
|
||||||
|
# Avoid using DefaultSelector and PollSelector. Kqueue() does not
|
||||||
|
# work with pseudo-terminals on OS X < 10.9 (Issue 20365) and Open
|
||||||
|
# BSD (Issue 20667). Poll() does not work with OS X 10.6 or 10.4
|
||||||
|
# either (Issue 20472). Hopefully the file descriptor is low enough
|
||||||
|
# to use with select().
|
||||||
|
sel = cleanup.enter_context(selectors.SelectSelector())
|
||||||
|
sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE)
|
||||||
|
os.set_blocking(master, False)
|
||||||
|
while True:
|
||||||
|
for [_, events] in sel.select():
|
||||||
|
if events & selectors.EVENT_READ:
|
||||||
|
try:
|
||||||
|
chunk = os.read(master, 0x10000)
|
||||||
|
except OSError as err:
|
||||||
|
# Linux raises EIO when slave is closed (Issue 5380)
|
||||||
|
if err.errno != EIO:
|
||||||
|
raise
|
||||||
|
chunk = b""
|
||||||
|
if not chunk:
|
||||||
|
return output
|
||||||
|
output.extend(chunk)
|
||||||
|
if events & selectors.EVENT_WRITE:
|
||||||
|
try:
|
||||||
|
input = input[os.write(master, input):]
|
||||||
|
except OSError as err:
|
||||||
|
# Apparently EIO means the slave was closed
|
||||||
|
if err.errno != EIO:
|
||||||
|
raise
|
||||||
|
input = b"" # Stop writing
|
||||||
|
if not input:
|
||||||
|
sel.modify(master, selectors.EVENT_READ)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -157,6 +157,12 @@ class SymtableTest(unittest.TestCase):
|
||||||
self.fail("no SyntaxError for %r" % (brokencode,))
|
self.fail("no SyntaxError for %r" % (brokencode,))
|
||||||
checkfilename("def f(x): foo)(") # parse-time
|
checkfilename("def f(x): foo)(") # parse-time
|
||||||
checkfilename("def f(x): global x") # symtable-build-time
|
checkfilename("def f(x): global x") # symtable-build-time
|
||||||
|
symtable.symtable("pass", b"spam", "exec")
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
symtable.symtable("pass", bytearray(b"spam"), "exec")
|
||||||
|
symtable.symtable("pass", memoryview(b"spam"), "exec")
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
symtable.symtable("pass", list(b"spam"), "exec")
|
||||||
|
|
||||||
def test_eval(self):
|
def test_eval(self):
|
||||||
symbols = symtable.symtable("42", "?", "eval")
|
symbols = symtable.symtable("42", "?", "eval")
|
||||||
|
|
|
@ -248,6 +248,11 @@ Overridden parameters
|
||||||
...
|
...
|
||||||
TypeError: f() got multiple values for keyword argument 'x'
|
TypeError: f() got multiple values for keyword argument 'x'
|
||||||
|
|
||||||
|
>>> f(x=5, **{'x': 3}, **{'x': 2})
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
TypeError: f() got multiple values for keyword argument 'x'
|
||||||
|
|
||||||
>>> f(**{1: 3}, **{1: 5})
|
>>> f(**{1: 3}, **{1: 5})
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
|
|
|
@ -18,7 +18,7 @@ import weakref
|
||||||
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import TESTFN, findfile, import_fresh_module, gc_collect
|
from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr
|
||||||
|
|
||||||
# pyET is the pure-Python implementation.
|
# pyET is the pure-Python implementation.
|
||||||
#
|
#
|
||||||
|
@ -1860,6 +1860,12 @@ class BadElementTest(ElementTestCase, unittest.TestCase):
|
||||||
e.extend([ET.Element('bar')])
|
e.extend([ET.Element('bar')])
|
||||||
self.assertRaises(ValueError, e.remove, X('baz'))
|
self.assertRaises(ValueError, e.remove, X('baz'))
|
||||||
|
|
||||||
|
def test_recursive_repr(self):
|
||||||
|
# Issue #25455
|
||||||
|
e = ET.Element('foo')
|
||||||
|
with swap_attr(e, 'tag', e):
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
repr(e) # Should not crash
|
||||||
|
|
||||||
class MutatingElementPath(str):
|
class MutatingElementPath(str):
|
||||||
def __new__(cls, elem, *args):
|
def __new__(cls, elem, *args):
|
||||||
|
|
|
@ -600,6 +600,19 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
|
||||||
finally:
|
finally:
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|
||||||
|
def testBytesPath(self):
|
||||||
|
filename = support.TESTFN + ".zip"
|
||||||
|
self.addCleanup(support.unlink, filename)
|
||||||
|
with ZipFile(filename, "w") as z:
|
||||||
|
zinfo = ZipInfo(TESTMOD + ".py", time.localtime(NOW))
|
||||||
|
zinfo.compress_type = self.compression
|
||||||
|
z.writestr(zinfo, test_src)
|
||||||
|
|
||||||
|
zipimport.zipimporter(filename)
|
||||||
|
zipimport.zipimporter(os.fsencode(filename))
|
||||||
|
zipimport.zipimporter(bytearray(os.fsencode(filename)))
|
||||||
|
zipimport.zipimporter(memoryview(os.fsencode(filename)))
|
||||||
|
|
||||||
|
|
||||||
@support.requires_zlib
|
@support.requires_zlib
|
||||||
class CompressedZipImportTestCase(UncompressedZipImportTestCase):
|
class CompressedZipImportTestCase(UncompressedZipImportTestCase):
|
||||||
|
@ -620,6 +633,8 @@ class BadFileZipImportTestCase(unittest.TestCase):
|
||||||
def testBadArgs(self):
|
def testBadArgs(self):
|
||||||
self.assertRaises(TypeError, zipimport.zipimporter, None)
|
self.assertRaises(TypeError, zipimport.zipimporter, None)
|
||||||
self.assertRaises(TypeError, zipimport.zipimporter, TESTMOD, kwd=None)
|
self.assertRaises(TypeError, zipimport.zipimporter, TESTMOD, kwd=None)
|
||||||
|
self.assertRaises(TypeError, zipimport.zipimporter,
|
||||||
|
list(os.fsencode(TESTMOD)))
|
||||||
|
|
||||||
def testFilenameTooLong(self):
|
def testFilenameTooLong(self):
|
||||||
self.assertZipFailure('A' * 33000)
|
self.assertZipFailure('A' * 33000)
|
||||||
|
|
|
@ -271,7 +271,7 @@ class Variable:
|
||||||
|
|
||||||
Return the name of the callback.
|
Return the name of the callback.
|
||||||
"""
|
"""
|
||||||
f = CallWrapper(callback, None, self).__call__
|
f = CallWrapper(callback, None, self._root).__call__
|
||||||
cbname = repr(id(f))
|
cbname = repr(id(f))
|
||||||
try:
|
try:
|
||||||
callback = callback.__func__
|
callback = callback.__func__
|
||||||
|
@ -295,14 +295,19 @@ class Variable:
|
||||||
CBNAME is the name of the callback returned from trace_variable or trace.
|
CBNAME is the name of the callback returned from trace_variable or trace.
|
||||||
"""
|
"""
|
||||||
self._tk.call("trace", "vdelete", self._name, mode, cbname)
|
self._tk.call("trace", "vdelete", self._name, mode, cbname)
|
||||||
self._tk.deletecommand(cbname)
|
cbname = self._tk.splitlist(cbname)[0]
|
||||||
try:
|
for m, ca in self.trace_vinfo():
|
||||||
self._tclCommands.remove(cbname)
|
if self._tk.splitlist(ca)[0] == cbname:
|
||||||
except ValueError:
|
break
|
||||||
pass
|
else:
|
||||||
|
self._tk.deletecommand(cbname)
|
||||||
|
try:
|
||||||
|
self._tclCommands.remove(cbname)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
def trace_vinfo(self):
|
def trace_vinfo(self):
|
||||||
"""Return all trace callback information."""
|
"""Return all trace callback information."""
|
||||||
return [self._tk.split(x) for x in self._tk.splitlist(
|
return [self._tk.splitlist(x) for x in self._tk.splitlist(
|
||||||
self._tk.call("trace", "vinfo", self._name))]
|
self._tk.call("trace", "vinfo", self._name))]
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""Comparison for equality (==).
|
"""Comparison for equality (==).
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
import gc
|
||||||
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
|
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
|
||||||
TclError)
|
TclError)
|
||||||
|
|
||||||
|
@ -87,6 +87,55 @@ class TestVariable(TestBase):
|
||||||
v.set("value")
|
v.set("value")
|
||||||
self.assertTrue(v.side_effect)
|
self.assertTrue(v.side_effect)
|
||||||
|
|
||||||
|
def test_trace(self):
|
||||||
|
v = Variable(self.root)
|
||||||
|
vname = str(v)
|
||||||
|
trace = []
|
||||||
|
def read_tracer(*args):
|
||||||
|
trace.append(('read',) + args)
|
||||||
|
def write_tracer(*args):
|
||||||
|
trace.append(('write',) + args)
|
||||||
|
cb1 = v.trace_variable('r', read_tracer)
|
||||||
|
cb2 = v.trace_variable('wu', write_tracer)
|
||||||
|
self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)])
|
||||||
|
self.assertEqual(trace, [])
|
||||||
|
|
||||||
|
v.set('spam')
|
||||||
|
self.assertEqual(trace, [('write', vname, '', 'w')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
v.get()
|
||||||
|
self.assertEqual(trace, [('read', vname, '', 'r')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
info = sorted(v.trace_vinfo())
|
||||||
|
v.trace_vdelete('w', cb1) # Wrong mode
|
||||||
|
self.assertEqual(sorted(v.trace_vinfo()), info)
|
||||||
|
with self.assertRaises(TclError):
|
||||||
|
v.trace_vdelete('r', 'spam') # Wrong command name
|
||||||
|
self.assertEqual(sorted(v.trace_vinfo()), info)
|
||||||
|
v.trace_vdelete('r', (cb1, 43)) # Wrong arguments
|
||||||
|
self.assertEqual(sorted(v.trace_vinfo()), info)
|
||||||
|
v.get()
|
||||||
|
self.assertEqual(trace, [('read', vname, '', 'r')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
v.trace_vdelete('r', cb1)
|
||||||
|
self.assertEqual(v.trace_vinfo(), [('wu', cb2)])
|
||||||
|
v.get()
|
||||||
|
self.assertEqual(trace, [])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
del write_tracer
|
||||||
|
gc.collect()
|
||||||
|
v.set('eggs')
|
||||||
|
self.assertEqual(trace, [('write', vname, '', 'w')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
del v
|
||||||
|
gc.collect()
|
||||||
|
self.assertEqual(trace, [('write', vname, '', 'u')])
|
||||||
|
|
||||||
|
|
||||||
class TestStringVar(TestBase):
|
class TestStringVar(TestBase):
|
||||||
|
|
||||||
|
|
|
@ -1486,6 +1486,57 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
|
||||||
value)
|
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',))
|
||||||
|
|
||||||
|
self.tv.insert('', 'end', id='unicode\u20ac')
|
||||||
|
self.tv.selection_set('unicode\u20ac')
|
||||||
|
self.assertEqual(self.tv.selection(), ('unicode\u20ac',))
|
||||||
|
|
||||||
|
self.tv.insert('', 'end', id=b'bytes\xe2\x82\xac')
|
||||||
|
self.tv.selection_set(b'bytes\xe2\x82\xac')
|
||||||
|
self.assertEqual(self.tv.selection(), ('bytes\xe2\x82\xac',))
|
||||||
|
|
||||||
|
|
||||||
def test_set(self):
|
def test_set(self):
|
||||||
self.tv['columns'] = ['A', 'B']
|
self.tv['columns'] = ['A', 'B']
|
||||||
item = self.tv.insert('', 'end', values=['a', 'b'])
|
item = self.tv.insert('', 'end', values=['a', 'b'])
|
||||||
|
|
|
@ -1392,7 +1392,9 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
|
||||||
|
|
||||||
def selection(self, selop=None, items=None):
|
def selection(self, selop=None, items=None):
|
||||||
"""If selop is not specified, returns selected items."""
|
"""If selop is not specified, returns selected items."""
|
||||||
return self.tk.call(self._w, "selection", selop, items)
|
if isinstance(items, (str, bytes)):
|
||||||
|
items = (items,)
|
||||||
|
return self.tk.splitlist(self.tk.call(self._w, "selection", selop, items))
|
||||||
|
|
||||||
|
|
||||||
def selection_set(self, items):
|
def selection_set(self, items):
|
||||||
|
|
|
@ -179,7 +179,7 @@ def config_dict(filename):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
key, value = line.split("=")
|
key, value = line.split("=")
|
||||||
except:
|
except ValueError:
|
||||||
print("Bad line in config-file %s:\n%s" % (filename,line))
|
print("Bad line in config-file %s:\n%s" % (filename,line))
|
||||||
continue
|
continue
|
||||||
key = key.strip()
|
key = key.strip()
|
||||||
|
@ -192,7 +192,7 @@ def config_dict(filename):
|
||||||
value = float(value)
|
value = float(value)
|
||||||
else:
|
else:
|
||||||
value = int(value)
|
value = int(value)
|
||||||
except:
|
except ValueError:
|
||||||
pass # value need not be converted
|
pass # value need not be converted
|
||||||
cfgdict[key] = value
|
cfgdict[key] = value
|
||||||
return cfgdict
|
return cfgdict
|
||||||
|
@ -220,7 +220,7 @@ def readconfig(cfgdict):
|
||||||
try:
|
try:
|
||||||
head, tail = split(__file__)
|
head, tail = split(__file__)
|
||||||
cfg_file2 = join(head, default_cfg)
|
cfg_file2 = join(head, default_cfg)
|
||||||
except:
|
except Exception:
|
||||||
cfg_file2 = ""
|
cfg_file2 = ""
|
||||||
if isfile(cfg_file2):
|
if isfile(cfg_file2):
|
||||||
cfgdict2 = config_dict(cfg_file2)
|
cfgdict2 = config_dict(cfg_file2)
|
||||||
|
@ -229,7 +229,7 @@ def readconfig(cfgdict):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
readconfig(_CFG)
|
readconfig(_CFG)
|
||||||
except:
|
except Exception:
|
||||||
print ("No configfile read, reason unknown")
|
print ("No configfile read, reason unknown")
|
||||||
|
|
||||||
|
|
||||||
|
@ -653,7 +653,7 @@ class TurtleScreenBase(object):
|
||||||
x, y = (self.cv.canvasx(event.x)/self.xscale,
|
x, y = (self.cv.canvasx(event.x)/self.xscale,
|
||||||
-self.cv.canvasy(event.y)/self.yscale)
|
-self.cv.canvasy(event.y)/self.yscale)
|
||||||
fun(x, y)
|
fun(x, y)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
|
self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
|
||||||
|
|
||||||
|
@ -1158,7 +1158,7 @@ class TurtleScreen(TurtleScreenBase):
|
||||||
raise TurtleGraphicsError("bad color string: %s" % str(color))
|
raise TurtleGraphicsError("bad color string: %s" % str(color))
|
||||||
try:
|
try:
|
||||||
r, g, b = color
|
r, g, b = color
|
||||||
except:
|
except (TypeError, ValueError):
|
||||||
raise TurtleGraphicsError("bad color arguments: %s" % str(color))
|
raise TurtleGraphicsError("bad color arguments: %s" % str(color))
|
||||||
if self._colormode == 1.0:
|
if self._colormode == 1.0:
|
||||||
r, g, b = [round(255.0*x) for x in (r, g, b)]
|
r, g, b = [round(255.0*x) for x in (r, g, b)]
|
||||||
|
@ -2702,7 +2702,7 @@ class RawTurtle(TPen, TNavigator):
|
||||||
return args
|
return args
|
||||||
try:
|
try:
|
||||||
r, g, b = args
|
r, g, b = args
|
||||||
except:
|
except (TypeError, ValueError):
|
||||||
raise TurtleGraphicsError("bad color arguments: %s" % str(args))
|
raise TurtleGraphicsError("bad color arguments: %s" % str(args))
|
||||||
if self.screen._colormode == 1.0:
|
if self.screen._colormode == 1.0:
|
||||||
r, g, b = [round(255.0*x) for x in (r, g, b)]
|
r, g, b = [round(255.0*x) for x in (r, g, b)]
|
||||||
|
@ -3865,7 +3865,7 @@ def read_docstrings(lang):
|
||||||
try:
|
try:
|
||||||
# eval(key).im_func.__doc__ = docsdict[key]
|
# eval(key).im_func.__doc__ = docsdict[key]
|
||||||
eval(key).__doc__ = docsdict[key]
|
eval(key).__doc__ = docsdict[key]
|
||||||
except:
|
except Exception:
|
||||||
print("Bad docstring-entry: %s" % key)
|
print("Bad docstring-entry: %s" % key)
|
||||||
|
|
||||||
_LANGUAGE = _CFG["language"]
|
_LANGUAGE = _CFG["language"]
|
||||||
|
@ -3875,7 +3875,7 @@ try:
|
||||||
read_docstrings(_LANGUAGE)
|
read_docstrings(_LANGUAGE)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("Cannot find docsdict for", _LANGUAGE)
|
print("Cannot find docsdict for", _LANGUAGE)
|
||||||
except:
|
except Exception:
|
||||||
print ("Unknown Error when trying to import %s-docstring-dictionary" %
|
print ("Unknown Error when trying to import %s-docstring-dictionary" %
|
||||||
_LANGUAGE)
|
_LANGUAGE)
|
||||||
|
|
||||||
|
|
|
@ -1694,6 +1694,7 @@ _non_defaults = {
|
||||||
'__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__',
|
'__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__',
|
||||||
'__getstate__', '__setstate__', '__getformat__', '__setformat__',
|
'__getstate__', '__setstate__', '__getformat__', '__setformat__',
|
||||||
'__repr__', '__dir__', '__subclasses__', '__format__',
|
'__repr__', '__dir__', '__subclasses__', '__format__',
|
||||||
|
'__getnewargs_ex__',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,6 @@ for idx, value in enumerate(sys.argv):
|
||||||
break
|
break
|
||||||
|
|
||||||
# Now it is safe to import idlelib.
|
# Now it is safe to import idlelib.
|
||||||
from idlelib import macosxSupport
|
|
||||||
macosxSupport._appbundle = True
|
|
||||||
from idlelib.PyShell import main
|
from idlelib.PyShell import main
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1655,6 +1655,7 @@ Uwe Zessin
|
||||||
Cheng Zhang
|
Cheng Zhang
|
||||||
Kai Zhu
|
Kai Zhu
|
||||||
Tarek Ziadé
|
Tarek Ziadé
|
||||||
|
Jelle Zijlstra
|
||||||
Gennadiy Zlobin
|
Gennadiy Zlobin
|
||||||
Doug Zongker
|
Doug Zongker
|
||||||
Peter Åstrand
|
Peter Åstrand
|
||||||
|
|
63
Misc/NEWS
63
Misc/NEWS
|
@ -2,8 +2,8 @@
|
||||||
Python News
|
Python News
|
||||||
+++++++++++
|
+++++++++++
|
||||||
|
|
||||||
What's New in Python 3.5.3rc1?
|
What's New in Python 3.5.3 release candidate 1?
|
||||||
==============================
|
===============================================
|
||||||
|
|
||||||
Release date: TBA
|
Release date: TBA
|
||||||
|
|
||||||
|
@ -13,6 +13,65 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #22115: Fixed tracing Tkinter variables: trace_vdelete() with wrong
|
||||||
|
mode no longer break tracing, trace_vinfo() now always returns a list of
|
||||||
|
pairs of strings, tracing in the "u" mode now works.
|
||||||
|
|
||||||
|
- Fix a scoping issue in importlib.util.LazyLoader which triggered an
|
||||||
|
UnboundLocalError when lazy-loading a module that was already put into
|
||||||
|
sys.modules.
|
||||||
|
|
||||||
|
- Issue #27079: Fixed curses.ascii functions isblank(), iscntrl() and ispunct().
|
||||||
|
|
||||||
|
- Issue #26754: Some functions (compile() etc) accepted a filename argument
|
||||||
|
encoded as an iterable of integers. Now only strings and byte-like objects
|
||||||
|
are accepted.
|
||||||
|
|
||||||
|
- Issue #27048: Prevents distutils failing on Windows when environment
|
||||||
|
variables contain non-ASCII characters
|
||||||
|
|
||||||
|
- 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 #27122: When an exception is raised within the context being managed
|
||||||
|
by a contextlib.ExitStack() and one of the exit stack generators
|
||||||
|
catches and raises it in a chain, do not re-raise the original exception
|
||||||
|
when exiting, let the new chained one through. This avoids the PEP 479
|
||||||
|
bug described in issue25782.
|
||||||
|
|
||||||
|
- Issue #27278: Fix os.urandom() implementation using getrandom() on Linux.
|
||||||
|
Truncate size to INT_MAX and loop until we collected enough random bytes,
|
||||||
|
instead of casting a directly Py_ssize_t to int.
|
||||||
|
|
||||||
|
- Issue #26386: Fixed ttk.TreeView selection operations with item id's
|
||||||
|
containing spaces.
|
||||||
|
|
||||||
|
- Issue #22636: Avoid shell injection problems with
|
||||||
|
ctypes.util.find_library().
|
||||||
|
|
||||||
|
- Issue #16182: Fix various functions in the "readline" module to use the
|
||||||
|
locale encoding, and fix get_begidx() and get_endidx() to return code point
|
||||||
|
indexes.
|
||||||
|
|
||||||
|
- Issue #26930: Update Windows builds to use OpenSSL 1.0.2h.
|
||||||
|
|
||||||
|
IDLE
|
||||||
|
----
|
||||||
|
|
||||||
|
- Issue #27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names.
|
||||||
|
|
||||||
|
- Issue #27245: IDLE: Cleanly delete custom themes and key bindings.
|
||||||
|
Previously, when IDLE was started from a console or by import, a cascade
|
||||||
|
of warnings was emitted. Patch by Serhiy Storchaka.
|
||||||
|
|
||||||
|
C API
|
||||||
|
-----
|
||||||
|
|
||||||
|
- Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as
|
||||||
|
an iterable of integers. Now only strings and bytes-like objects are accepted.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.5.2?
|
What's New in Python 3.5.2?
|
||||||
===========================
|
===========================
|
||||||
|
|
|
@ -1124,7 +1124,7 @@ CharArray_get_raw(CDataObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
CharArray_get_value(CDataObject *self)
|
CharArray_get_value(CDataObject *self)
|
||||||
{
|
{
|
||||||
int i;
|
Py_ssize_t i;
|
||||||
char *ptr = self->b_ptr;
|
char *ptr = self->b_ptr;
|
||||||
for (i = 0; i < self->b_size; ++i)
|
for (i = 0; i < self->b_size; ++i)
|
||||||
if (*ptr++ == '\0')
|
if (*ptr++ == '\0')
|
||||||
|
@ -1180,9 +1180,9 @@ static PyGetSetDef CharArray_getsets[] = {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
WCharArray_get_value(CDataObject *self)
|
WCharArray_get_value(CDataObject *self)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
Py_ssize_t i;
|
||||||
wchar_t *ptr = (wchar_t *)self->b_ptr;
|
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)
|
if (*ptr++ == (wchar_t)0)
|
||||||
break;
|
break;
|
||||||
return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
|
return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
|
||||||
|
@ -1211,7 +1211,7 @@ WCharArray_set_value(CDataObject *self, PyObject *value)
|
||||||
wstr = PyUnicode_AsUnicodeAndSize(value, &len);
|
wstr = PyUnicode_AsUnicodeAndSize(value, &len);
|
||||||
if (wstr == NULL)
|
if (wstr == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if ((unsigned)len > self->b_size/sizeof(wchar_t)) {
|
if ((size_t)len > self->b_size/sizeof(wchar_t)) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"string too long");
|
"string too long");
|
||||||
result = -1;
|
result = -1;
|
||||||
|
@ -1252,8 +1252,10 @@ add_methods(PyTypeObject *type, PyMethodDef *meth)
|
||||||
descr = PyDescr_NewMethod(type, meth);
|
descr = PyDescr_NewMethod(type, meth);
|
||||||
if (descr == NULL)
|
if (descr == NULL)
|
||||||
return -1;
|
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;
|
return -1;
|
||||||
|
}
|
||||||
Py_DECREF(descr);
|
Py_DECREF(descr);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1268,8 +1270,10 @@ add_members(PyTypeObject *type, PyMemberDef *memb)
|
||||||
descr = PyDescr_NewMember(type, memb);
|
descr = PyDescr_NewMember(type, memb);
|
||||||
if (descr == NULL)
|
if (descr == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (PyDict_SetItemString(dict, memb->name, descr) < 0)
|
if (PyDict_SetItemString(dict, memb->name, descr) < 0) {
|
||||||
|
Py_DECREF(descr);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
Py_DECREF(descr);
|
Py_DECREF(descr);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1285,8 +1289,10 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp)
|
||||||
descr = PyDescr_NewGetSet(type, gsp);
|
descr = PyDescr_NewGetSet(type, gsp);
|
||||||
if (descr == NULL)
|
if (descr == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
|
if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
|
||||||
|
Py_DECREF(descr);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
Py_DECREF(descr);
|
Py_DECREF(descr);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1778,6 +1784,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
|
||||||
|
|
||||||
newname = PyUnicode_Concat(name, suffix);
|
newname = PyUnicode_Concat(name, suffix);
|
||||||
if (newname == NULL) {
|
if (newname == NULL) {
|
||||||
|
Py_DECREF(swapped_args);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1797,8 +1804,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
|
||||||
|
|
||||||
stgdict = (StgDictObject *)PyObject_CallObject(
|
stgdict = (StgDictObject *)PyObject_CallObject(
|
||||||
(PyObject *)&PyCStgDict_Type, NULL);
|
(PyObject *)&PyCStgDict_Type, NULL);
|
||||||
if (!stgdict) /* XXX leaks result! */
|
if (!stgdict) {
|
||||||
|
Py_DECREF(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
stgdict->ffi_type_pointer = *fmt->pffi_type;
|
stgdict->ffi_type_pointer = *fmt->pffi_type;
|
||||||
stgdict->align = fmt->pffi_type->alignment;
|
stgdict->align = fmt->pffi_type->alignment;
|
||||||
|
@ -1978,8 +1987,10 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *meth;
|
PyObject *meth;
|
||||||
int x;
|
int x;
|
||||||
meth = PyDescr_NewClassMethod(result, ml);
|
meth = PyDescr_NewClassMethod(result, ml);
|
||||||
if (!meth)
|
if (!meth) {
|
||||||
|
Py_DECREF(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
x = PyDict_SetItemString(result->tp_dict,
|
x = PyDict_SetItemString(result->tp_dict,
|
||||||
ml->ml_name,
|
ml->ml_name,
|
||||||
meth);
|
meth);
|
||||||
|
@ -2159,8 +2170,10 @@ converters_from_argtypes(PyObject *ob)
|
||||||
|
|
||||||
nArgs = PyTuple_GET_SIZE(ob);
|
nArgs = PyTuple_GET_SIZE(ob);
|
||||||
converters = PyTuple_New(nArgs);
|
converters = PyTuple_New(nArgs);
|
||||||
if (!converters)
|
if (!converters) {
|
||||||
|
Py_DECREF(ob);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* I have to check if this is correct. Using c_char, which has a size
|
/* 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!
|
of 1, will be assumed to be pushed as only one byte!
|
||||||
|
@ -4052,14 +4065,9 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
|
||||||
}
|
}
|
||||||
val = PyTuple_GET_ITEM(args, i + index);
|
val = PyTuple_GET_ITEM(args, i + index);
|
||||||
if (kwds && PyDict_GetItem(kwds, name)) {
|
if (kwds && PyDict_GetItem(kwds, name)) {
|
||||||
char *field = PyBytes_AsString(name);
|
|
||||||
if (field == NULL) {
|
|
||||||
PyErr_Clear();
|
|
||||||
field = "???";
|
|
||||||
}
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"duplicate values for field '%s'",
|
"duplicate values for field %R",
|
||||||
field);
|
name);
|
||||||
Py_DECREF(pair);
|
Py_DECREF(pair);
|
||||||
Py_DECREF(name);
|
Py_DECREF(name);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -157,8 +157,10 @@ _ctypes_get_errobj(int **pspace)
|
||||||
return NULL;
|
return NULL;
|
||||||
memset(space, 0, sizeof(int) * 2);
|
memset(space, 0, sizeof(int) * 2);
|
||||||
errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
|
errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
|
||||||
if (errobj == NULL)
|
if (errobj == NULL) {
|
||||||
|
PyMem_Free(space);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
if (-1 == PyDict_SetItem(dict, error_object_name,
|
if (-1 == PyDict_SetItem(dict, error_object_name,
|
||||||
errobj)) {
|
errobj)) {
|
||||||
Py_DECREF(errobj);
|
Py_DECREF(errobj);
|
||||||
|
@ -1681,6 +1683,10 @@ POINTER(PyObject *self, PyObject *cls)
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return result;
|
return result;
|
||||||
key = PyLong_FromVoidPtr(result);
|
key = PyLong_FromVoidPtr(result);
|
||||||
|
if (key == NULL) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else if (PyType_Check(cls)) {
|
} else if (PyType_Check(cls)) {
|
||||||
typ = (PyTypeObject *)cls;
|
typ = (PyTypeObject *)cls;
|
||||||
buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1);
|
buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1);
|
||||||
|
|
|
@ -1246,8 +1246,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
"unicode string expected instead of %s instance",
|
"unicode string expected instead of %s instance",
|
||||||
value->ob_type->tp_name);
|
value->ob_type->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else
|
}
|
||||||
Py_INCREF(value);
|
|
||||||
|
|
||||||
wstr = PyUnicode_AsUnicodeAndSize(value, &size);
|
wstr = PyUnicode_AsUnicodeAndSize(value, &size);
|
||||||
if (wstr == NULL)
|
if (wstr == NULL)
|
||||||
|
@ -1256,7 +1255,6 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"string too long (%zd, maximum length %zd)",
|
"string too long (%zd, maximum length %zd)",
|
||||||
size, length);
|
size, length);
|
||||||
Py_DECREF(value);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (size < length-1)
|
} else if (size < length-1)
|
||||||
/* copy terminating NUL character if there is space */
|
/* copy terminating NUL character if there is space */
|
||||||
|
@ -1266,6 +1264,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_INCREF(value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,9 +1291,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
char *data;
|
char *data;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
|
|
||||||
if(PyBytes_Check(value)) {
|
if(!PyBytes_Check(value)) {
|
||||||
Py_INCREF(value);
|
|
||||||
} else {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"expected bytes, %s found",
|
"expected bytes, %s found",
|
||||||
value->ob_type->tp_name);
|
value->ob_type->tp_name);
|
||||||
|
@ -1302,11 +1299,9 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
data = PyBytes_AS_STRING(value);
|
data = PyBytes_AS_STRING(value);
|
||||||
if (!data)
|
|
||||||
return NULL;
|
|
||||||
size = strlen(data); /* XXX Why not Py_SIZE(value)? */
|
size = strlen(data); /* XXX Why not Py_SIZE(value)? */
|
||||||
if (size < length) {
|
if (size < length) {
|
||||||
/* This will copy the leading NUL character
|
/* This will copy the terminating NUL character
|
||||||
* if there is space for it.
|
* if there is space for it.
|
||||||
*/
|
*/
|
||||||
++size;
|
++size;
|
||||||
|
@ -1314,13 +1309,11 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"bytes too long (%zd, maximum length %zd)",
|
"bytes too long (%zd, maximum length %zd)",
|
||||||
size, length);
|
size, length);
|
||||||
Py_DECREF(value);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Also copy the terminating NUL character if there is space */
|
/* Also copy the terminating NUL character if there is space */
|
||||||
memcpy((char *)ptr, data, size);
|
memcpy((char *)ptr, data, size);
|
||||||
|
|
||||||
Py_DECREF(value);
|
|
||||||
_RET(value);
|
_RET(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,9 +1421,7 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
|
||||||
/* convert value into a PyUnicodeObject or NULL */
|
/* convert value into a PyUnicodeObject or NULL */
|
||||||
if (Py_None == value) {
|
if (Py_None == value) {
|
||||||
value = NULL;
|
value = NULL;
|
||||||
} else if (PyUnicode_Check(value)) {
|
} else if (!PyUnicode_Check(value)) {
|
||||||
Py_INCREF(value); /* for the descref below */
|
|
||||||
} else {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"unicode string expected instead of %s instance",
|
"unicode string expected instead of %s instance",
|
||||||
value->ob_type->tp_name);
|
value->ob_type->tp_name);
|
||||||
|
@ -1449,7 +1440,6 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
bstr = SysAllocStringLen(wvalue, (unsigned)wsize);
|
bstr = SysAllocStringLen(wvalue, (unsigned)wsize);
|
||||||
Py_DECREF(value);
|
|
||||||
} else
|
} else
|
||||||
bstr = NULL;
|
bstr = NULL;
|
||||||
|
|
||||||
|
|
|
@ -2630,12 +2630,18 @@ PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
|
||||||
|
|
||||||
/* class method */
|
/* class method */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dec_from_float(PyObject *dec, PyObject *pyfloat)
|
dec_from_float(PyObject *type, PyObject *pyfloat)
|
||||||
{
|
{
|
||||||
PyObject *context;
|
PyObject *context;
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
CURRENT_CONTEXT(context);
|
CURRENT_CONTEXT(context);
|
||||||
return PyDecType_FromFloatExact((PyTypeObject *)dec, pyfloat, context);
|
result = PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context);
|
||||||
|
if (type != (PyObject *)&PyDec_Type && result != NULL) {
|
||||||
|
Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create_decimal_from_float */
|
/* create_decimal_from_float */
|
||||||
|
|
|
@ -1582,10 +1582,23 @@ _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
|
||||||
static PyObject*
|
static PyObject*
|
||||||
element_repr(ElementObject* self)
|
element_repr(ElementObject* self)
|
||||||
{
|
{
|
||||||
if (self->tag)
|
int status;
|
||||||
return PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
|
|
||||||
else
|
if (self->tag == NULL)
|
||||||
return PyUnicode_FromFormat("<Element at %p>", self);
|
return PyUnicode_FromFormat("<Element at %p>", self);
|
||||||
|
|
||||||
|
status = Py_ReprEnter((PyObject *)self);
|
||||||
|
if (status == 0) {
|
||||||
|
PyObject *res;
|
||||||
|
res = PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
|
||||||
|
Py_ReprLeave((PyObject *)self);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (status > 0)
|
||||||
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
|
"reentrant call inside %s.__repr__",
|
||||||
|
Py_TYPE(self)->tp_name);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
|
|
@ -203,40 +203,45 @@ static PyGetSetDef partial_getsetlist[] = {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
partial_repr(partialobject *pto)
|
partial_repr(partialobject *pto)
|
||||||
{
|
{
|
||||||
PyObject *result;
|
PyObject *result = NULL;
|
||||||
PyObject *arglist;
|
PyObject *arglist;
|
||||||
PyObject *tmp;
|
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = Py_ReprEnter((PyObject *)pto);
|
||||||
|
if (status != 0) {
|
||||||
|
if (status < 0)
|
||||||
|
return NULL;
|
||||||
|
return PyUnicode_FromFormat("%s(...)", Py_TYPE(pto)->tp_name);
|
||||||
|
}
|
||||||
|
|
||||||
arglist = PyUnicode_FromString("");
|
arglist = PyUnicode_FromString("");
|
||||||
if (arglist == NULL) {
|
if (arglist == NULL)
|
||||||
return NULL;
|
goto done;
|
||||||
}
|
|
||||||
/* Pack positional arguments */
|
/* Pack positional arguments */
|
||||||
assert (PyTuple_Check(pto->args));
|
assert (PyTuple_Check(pto->args));
|
||||||
n = PyTuple_GET_SIZE(pto->args);
|
n = PyTuple_GET_SIZE(pto->args);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
tmp = PyUnicode_FromFormat("%U, %R", arglist,
|
Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
|
||||||
PyTuple_GET_ITEM(pto->args, i));
|
PyTuple_GET_ITEM(pto->args, i)));
|
||||||
Py_DECREF(arglist);
|
if (arglist == NULL)
|
||||||
if (tmp == NULL)
|
goto done;
|
||||||
return NULL;
|
|
||||||
arglist = tmp;
|
|
||||||
}
|
}
|
||||||
/* Pack keyword arguments */
|
/* Pack keyword arguments */
|
||||||
assert (PyDict_Check(pto->kw));
|
assert (PyDict_Check(pto->kw));
|
||||||
for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
|
for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
|
||||||
tmp = PyUnicode_FromFormat("%U, %U=%R", arglist,
|
Py_SETREF(arglist, PyUnicode_FromFormat("%U, %U=%R", arglist,
|
||||||
key, value);
|
key, value));
|
||||||
Py_DECREF(arglist);
|
if (arglist == NULL)
|
||||||
if (tmp == NULL)
|
goto done;
|
||||||
return NULL;
|
|
||||||
arglist = tmp;
|
|
||||||
}
|
}
|
||||||
result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name,
|
result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name,
|
||||||
pto->fn, arglist);
|
pto->fn, arglist);
|
||||||
Py_DECREF(arglist);
|
Py_DECREF(arglist);
|
||||||
|
|
||||||
|
done:
|
||||||
|
Py_ReprLeave((PyObject *)pto);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,10 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
self->thread_ident = PyThread_get_thread_ident();
|
self->thread_ident = PyThread_get_thread_ident();
|
||||||
#endif
|
#endif
|
||||||
|
if (!check_same_thread && sqlite3_libversion_number() < 3003001) {
|
||||||
|
PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
self->check_same_thread = check_same_thread;
|
self->check_same_thread = check_same_thread;
|
||||||
|
|
||||||
self->function_pinboard = PyDict_New();
|
self->function_pinboard = PyDict_New();
|
||||||
|
|
|
@ -42,7 +42,7 @@ extern PyObject* pysqlite_NotSupportedError;
|
||||||
extern PyObject* time_time;
|
extern PyObject* time_time;
|
||||||
extern PyObject* time_sleep;
|
extern PyObject* time_sleep;
|
||||||
|
|
||||||
/* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter
|
/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter
|
||||||
* functions, that convert the SQL value to the appropriate Python value.
|
* functions, that convert the SQL value to the appropriate Python value.
|
||||||
* The key is uppercase.
|
* The key is uppercase.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1268,7 +1268,7 @@ array_array_buffer_info_impl(arrayobject *self)
|
||||||
}
|
}
|
||||||
PyTuple_SET_ITEM(retval, 0, v);
|
PyTuple_SET_ITEM(retval, 0, v);
|
||||||
|
|
||||||
v = PyLong_FromLong((long)(Py_SIZE(self)));
|
v = PyLong_FromSsize_t(Py_SIZE(self));
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
Py_DECREF(retval);
|
Py_DECREF(retval);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
See the file COPYING for copying permission.
|
See the file COPYING for copying permission.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef COMPILED_FROM_DSP
|
#ifdef COMPILED_FROM_DSP
|
||||||
#include "winconfig.h"
|
#include "winconfig.h"
|
||||||
#elif defined(MACOS_CLASSIC)
|
#elif defined(MACOS_CLASSIC)
|
||||||
|
@ -16,8 +18,6 @@
|
||||||
#endif
|
#endif
|
||||||
#endif /* ndef COMPILED_FROM_DSP */
|
#endif /* ndef COMPILED_FROM_DSP */
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "expat_external.h"
|
#include "expat_external.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "xmlrole.h"
|
#include "xmlrole.h"
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
See the file COPYING for copying permission.
|
See the file COPYING for copying permission.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef COMPILED_FROM_DSP
|
#ifdef COMPILED_FROM_DSP
|
||||||
#include "winconfig.h"
|
#include "winconfig.h"
|
||||||
#elif defined(MACOS_CLASSIC)
|
#elif defined(MACOS_CLASSIC)
|
||||||
|
@ -16,8 +18,6 @@
|
||||||
#endif
|
#endif
|
||||||
#endif /* ndef COMPILED_FROM_DSP */
|
#endif /* ndef COMPILED_FROM_DSP */
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "expat_external.h"
|
#include "expat_external.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "xmltok.h"
|
#include "xmltok.h"
|
||||||
|
|
|
@ -128,20 +128,40 @@ static PyModuleDef readlinemodule;
|
||||||
#define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule)))
|
#define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule)))
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert to/from multibyte C strings */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
encode(PyObject *b)
|
||||||
|
{
|
||||||
|
return PyUnicode_EncodeLocale(b, "surrogateescape");
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
decode(const char *s)
|
||||||
|
{
|
||||||
|
return PyUnicode_DecodeLocale(s, "surrogateescape");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Exported function to send one line to readline's init file parser */
|
/* Exported function to send one line to readline's init file parser */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
parse_and_bind(PyObject *self, PyObject *args)
|
parse_and_bind(PyObject *self, PyObject *string)
|
||||||
{
|
{
|
||||||
char *s, *copy;
|
char *copy;
|
||||||
if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
|
PyObject *encoded = encode(string);
|
||||||
|
if (encoded == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
/* Make a copy -- rl_parse_and_bind() modifies its argument */
|
/* Make a copy -- rl_parse_and_bind() modifies its argument */
|
||||||
/* Bernard Herzog */
|
/* Bernard Herzog */
|
||||||
copy = PyMem_Malloc(1 + strlen(s));
|
copy = PyMem_Malloc(1 + PyBytes_GET_SIZE(encoded));
|
||||||
if (copy == NULL)
|
if (copy == NULL) {
|
||||||
|
Py_DECREF(encoded);
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
strcpy(copy, s);
|
}
|
||||||
|
strcpy(copy, PyBytes_AS_STRING(encoded));
|
||||||
|
Py_DECREF(encoded);
|
||||||
rl_parse_and_bind(copy);
|
rl_parse_and_bind(copy);
|
||||||
PyMem_Free(copy); /* Free the copy */
|
PyMem_Free(copy); /* Free the copy */
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -441,17 +461,18 @@ get the ending index of the completion scope");
|
||||||
/* Set the tab-completion word-delimiters that readline uses */
|
/* Set the tab-completion word-delimiters that readline uses */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_completer_delims(PyObject *self, PyObject *args)
|
set_completer_delims(PyObject *self, PyObject *string)
|
||||||
{
|
{
|
||||||
char *break_chars;
|
char *break_chars;
|
||||||
|
PyObject *encoded = encode(string);
|
||||||
if (!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
|
if (encoded == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Keep a reference to the allocated memory in the module state in case
|
/* Keep a reference to the allocated memory in the module state in case
|
||||||
some other module modifies rl_completer_word_break_characters
|
some other module modifies rl_completer_word_break_characters
|
||||||
(see issue #17289). */
|
(see issue #17289). */
|
||||||
break_chars = strdup(break_chars);
|
break_chars = strdup(PyBytes_AS_STRING(encoded));
|
||||||
|
Py_DECREF(encoded);
|
||||||
if (break_chars) {
|
if (break_chars) {
|
||||||
free(completer_word_break_characters);
|
free(completer_word_break_characters);
|
||||||
completer_word_break_characters = break_chars;
|
completer_word_break_characters = break_chars;
|
||||||
|
@ -531,10 +552,11 @@ static PyObject *
|
||||||
py_replace_history(PyObject *self, PyObject *args)
|
py_replace_history(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int entry_number;
|
int entry_number;
|
||||||
char *line;
|
PyObject *line;
|
||||||
|
PyObject *encoded;
|
||||||
HIST_ENTRY *old_entry;
|
HIST_ENTRY *old_entry;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "is:replace_history_item", &entry_number,
|
if (!PyArg_ParseTuple(args, "iU:replace_history_item", &entry_number,
|
||||||
&line)) {
|
&line)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -543,7 +565,12 @@ py_replace_history(PyObject *self, PyObject *args)
|
||||||
"History index cannot be negative");
|
"History index cannot be negative");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
old_entry = replace_history_entry(entry_number, line, (void *)NULL);
|
encoded = encode(line);
|
||||||
|
if (encoded == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
old_entry = replace_history_entry(entry_number, PyBytes_AS_STRING(encoded), (void *)NULL);
|
||||||
|
Py_DECREF(encoded);
|
||||||
if (!old_entry) {
|
if (!old_entry) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"No history item at position %d",
|
"No history item at position %d",
|
||||||
|
@ -562,14 +589,14 @@ replaces history item given by its position with contents of line");
|
||||||
/* Add a line to the history buffer */
|
/* Add a line to the history buffer */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
py_add_history(PyObject *self, PyObject *args)
|
py_add_history(PyObject *self, PyObject *string)
|
||||||
{
|
{
|
||||||
char *line;
|
PyObject *encoded = encode(string);
|
||||||
|
if (encoded == NULL) {
|
||||||
if(!PyArg_ParseTuple(args, "s:add_history", &line)) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
add_history(line);
|
add_history(PyBytes_AS_STRING(encoded));
|
||||||
|
Py_DECREF(encoded);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +610,7 @@ add an item to the history buffer");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
get_completer_delims(PyObject *self, PyObject *noarg)
|
get_completer_delims(PyObject *self, PyObject *noarg)
|
||||||
{
|
{
|
||||||
return PyUnicode_FromString(rl_completer_word_break_characters);
|
return decode(rl_completer_word_break_characters);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(doc_get_completer_delims,
|
PyDoc_STRVAR(doc_get_completer_delims,
|
||||||
|
@ -673,7 +700,7 @@ get_history_item(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
if ((hist_ent = history_get(idx)))
|
if ((hist_ent = history_get(idx)))
|
||||||
return PyUnicode_FromString(hist_ent->line);
|
return decode(hist_ent->line);
|
||||||
else {
|
else {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
@ -702,7 +729,7 @@ return the current (not the maximum) length of history.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
get_line_buffer(PyObject *self, PyObject *noarg)
|
get_line_buffer(PyObject *self, PyObject *noarg)
|
||||||
{
|
{
|
||||||
return PyUnicode_FromString(rl_line_buffer);
|
return decode(rl_line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(doc_get_line_buffer,
|
PyDoc_STRVAR(doc_get_line_buffer,
|
||||||
|
@ -730,12 +757,14 @@ Clear the current readline history.");
|
||||||
/* Exported function to insert text into the line buffer */
|
/* Exported function to insert text into the line buffer */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
insert_text(PyObject *self, PyObject *args)
|
insert_text(PyObject *self, PyObject *string)
|
||||||
{
|
{
|
||||||
char *s;
|
PyObject *encoded = encode(string);
|
||||||
if (!PyArg_ParseTuple(args, "s:insert_text", &s))
|
if (encoded == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
rl_insert_text(s);
|
}
|
||||||
|
rl_insert_text(PyBytes_AS_STRING(encoded));
|
||||||
|
Py_DECREF(encoded);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,9 +792,9 @@ contents of the line buffer.");
|
||||||
|
|
||||||
static struct PyMethodDef readline_methods[] =
|
static struct PyMethodDef readline_methods[] =
|
||||||
{
|
{
|
||||||
{"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind},
|
{"parse_and_bind", parse_and_bind, METH_O, doc_parse_and_bind},
|
||||||
{"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer},
|
{"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer},
|
||||||
{"insert_text", insert_text, METH_VARARGS, doc_insert_text},
|
{"insert_text", insert_text, METH_O, doc_insert_text},
|
||||||
{"redisplay", redisplay, METH_NOARGS, doc_redisplay},
|
{"redisplay", redisplay, METH_NOARGS, doc_redisplay},
|
||||||
{"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
|
{"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
|
||||||
{"read_history_file", read_history_file,
|
{"read_history_file", read_history_file,
|
||||||
|
@ -792,8 +821,8 @@ static struct PyMethodDef readline_methods[] =
|
||||||
{"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
|
{"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
|
||||||
|
|
||||||
{"set_completer_delims", set_completer_delims,
|
{"set_completer_delims", set_completer_delims,
|
||||||
METH_VARARGS, doc_set_completer_delims},
|
METH_O, doc_set_completer_delims},
|
||||||
{"add_history", py_add_history, METH_VARARGS, doc_add_history},
|
{"add_history", py_add_history, METH_O, doc_add_history},
|
||||||
{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
|
{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
|
||||||
{"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
|
{"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
|
||||||
{"get_completer_delims", get_completer_delims,
|
{"get_completer_delims", get_completer_delims,
|
||||||
|
@ -890,7 +919,7 @@ on_completion_display_matches_hook(char **matches,
|
||||||
int num_matches, int max_length)
|
int num_matches, int max_length)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
PyObject *m=NULL, *s=NULL, *r=NULL;
|
PyObject *sub, *m=NULL, *s=NULL, *r=NULL;
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
#endif
|
#endif
|
||||||
|
@ -898,16 +927,17 @@ on_completion_display_matches_hook(char **matches,
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
for (i = 0; i < num_matches; i++) {
|
for (i = 0; i < num_matches; i++) {
|
||||||
s = PyUnicode_FromString(matches[i+1]);
|
s = decode(matches[i+1]);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
if (PyList_SetItem(m, i, s) == -1)
|
if (PyList_SetItem(m, i, s) == -1)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
sub = decode(matches[0]);
|
||||||
r = PyObject_CallFunction(readlinestate_global->completion_display_matches_hook,
|
r = PyObject_CallFunction(readlinestate_global->completion_display_matches_hook,
|
||||||
"sOi", matches[0], m, max_length);
|
"NNi", sub, m, max_length);
|
||||||
|
|
||||||
Py_DECREF(m); m=NULL;
|
m=NULL;
|
||||||
|
|
||||||
if (r == NULL ||
|
if (r == NULL ||
|
||||||
(r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) {
|
(r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) {
|
||||||
|
@ -955,22 +985,24 @@ on_completion(const char *text, int state)
|
||||||
{
|
{
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
if (readlinestate_global->completer != NULL) {
|
if (readlinestate_global->completer != NULL) {
|
||||||
PyObject *r;
|
PyObject *r = NULL, *t;
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
#endif
|
#endif
|
||||||
rl_attempted_completion_over = 1;
|
rl_attempted_completion_over = 1;
|
||||||
r = PyObject_CallFunction(readlinestate_global->completer, "si", text, state);
|
t = decode(text);
|
||||||
|
r = PyObject_CallFunction(readlinestate_global->completer, "Ni", t, state);
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
if (r == Py_None) {
|
if (r == Py_None) {
|
||||||
result = NULL;
|
result = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *s = _PyUnicode_AsString(r);
|
PyObject *encoded = encode(r);
|
||||||
if (s == NULL)
|
if (encoded == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
result = strdup(s);
|
result = strdup(PyBytes_AS_STRING(encoded));
|
||||||
|
Py_DECREF(encoded);
|
||||||
}
|
}
|
||||||
Py_DECREF(r);
|
Py_DECREF(r);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -994,6 +1026,9 @@ static char **
|
||||||
flex_complete(const char *text, int start, int end)
|
flex_complete(const char *text, int start, int end)
|
||||||
{
|
{
|
||||||
char **result;
|
char **result;
|
||||||
|
char saved;
|
||||||
|
size_t start_size, end_size;
|
||||||
|
wchar_t *s;
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1003,6 +1038,27 @@ flex_complete(const char *text, int start, int end)
|
||||||
#ifdef HAVE_RL_COMPLETION_SUPPRESS_APPEND
|
#ifdef HAVE_RL_COMPLETION_SUPPRESS_APPEND
|
||||||
rl_completion_suppress_append = 0;
|
rl_completion_suppress_append = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
saved = rl_line_buffer[start];
|
||||||
|
rl_line_buffer[start] = 0;
|
||||||
|
s = Py_DecodeLocale(rl_line_buffer, &start_size);
|
||||||
|
rl_line_buffer[start] = saved;
|
||||||
|
if (s == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
PyMem_RawFree(s);
|
||||||
|
saved = rl_line_buffer[end];
|
||||||
|
rl_line_buffer[end] = 0;
|
||||||
|
s = Py_DecodeLocale(rl_line_buffer + start, &end_size);
|
||||||
|
rl_line_buffer[end] = saved;
|
||||||
|
if (s == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
PyMem_RawFree(s);
|
||||||
|
start = (int)start_size;
|
||||||
|
end = start + (int)end_size;
|
||||||
|
|
||||||
|
done:
|
||||||
Py_XDECREF(readlinestate_global->begidx);
|
Py_XDECREF(readlinestate_global->begidx);
|
||||||
Py_XDECREF(readlinestate_global->endidx);
|
Py_XDECREF(readlinestate_global->endidx);
|
||||||
readlinestate_global->begidx = PyLong_FromLong((long) start);
|
readlinestate_global->begidx = PyLong_FromLong((long) start);
|
||||||
|
|
|
@ -2109,7 +2109,7 @@ _Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where)
|
||||||
"%s returned NULL without setting an error",
|
"%s returned NULL without setting an error",
|
||||||
where);
|
where);
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
/* Ensure that the bug is catched in debug mode */
|
/* Ensure that the bug is caught in debug mode */
|
||||||
Py_FatalError("a function returned NULL without setting an error");
|
Py_FatalError("a function returned NULL without setting an error");
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2132,7 +2132,7 @@ _Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where)
|
||||||
where);
|
where);
|
||||||
_PyErr_ChainExceptions(exc, val, tb);
|
_PyErr_ChainExceptions(exc, val, tb);
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
/* Ensure that the bug is catched in debug mode */
|
/* Ensure that the bug is caught in debug mode */
|
||||||
Py_FatalError("a function returned a result with an error set");
|
Py_FatalError("a function returned a result with an error set");
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue