mirror of https://github.com/python/cpython
Merge.
This commit is contained in:
commit
3a260d228b
|
@ -132,8 +132,14 @@ Importing Modules
|
||||||
such modules have no way to know that the module object is an unknown (and
|
such modules have no way to know that the module object is an unknown (and
|
||||||
probably damaged with respect to the module author's intents) state.
|
probably damaged with respect to the module author's intents) state.
|
||||||
|
|
||||||
|
The module's :attr:`__spec__` and :attr:`__loader__` will be set, if
|
||||||
|
not set already, with the appropriate values. The spec's loader will
|
||||||
|
be set to the module's ``__loader__`` (if set) and to an instance of
|
||||||
|
:class:`SourceFileLoader` otherwise.
|
||||||
|
|
||||||
The module's :attr:`__file__` attribute will be set to the code object's
|
The module's :attr:`__file__` attribute will be set to the code object's
|
||||||
:c:member:`co_filename`.
|
:c:member:`co_filename`. If applicable, :attr:`__cached__` will also
|
||||||
|
be set.
|
||||||
|
|
||||||
This function will reload the module if it was already imported. See
|
This function will reload the module if it was already imported. See
|
||||||
:c:func:`PyImport_ReloadModule` for the intended way to reload a module.
|
:c:func:`PyImport_ReloadModule` for the intended way to reload a module.
|
||||||
|
|
|
@ -8,7 +8,7 @@ Operating system support
|
||||||
|
|
||||||
On Windows, the default event loop uses :class:`selectors.SelectSelector`
|
On Windows, the default event loop uses :class:`selectors.SelectSelector`
|
||||||
which only supports sockets. The :class:`ProactorEventLoop` should be used to
|
which only supports sockets. The :class:`ProactorEventLoop` should be used to
|
||||||
support subprocesses.
|
support subprocesses. However, the latter does not support SSL.
|
||||||
|
|
||||||
On Mac OS X older than 10.9 (Mavericks), :class:`selectors.KqueueSelector`
|
On Mac OS X older than 10.9 (Mavericks), :class:`selectors.KqueueSelector`
|
||||||
does not support character devices like PTY, whereas it is used by the
|
does not support character devices like PTY, whereas it is used by the
|
||||||
|
@ -262,9 +262,7 @@ display the output::
|
||||||
stdout = stdout.decode('ascii').rstrip()
|
stdout = stdout.decode('ascii').rstrip()
|
||||||
print("Platform: %s" % stdout)
|
print("Platform: %s" % stdout)
|
||||||
else:
|
else:
|
||||||
print("Python failed with exit code %s:" % exitcode)
|
print("Python failed with exit code %s:" % exitcode, flush=True)
|
||||||
sys.stdout.flush()
|
|
||||||
sys.stdout.buffer.flush()
|
|
||||||
sys.stdout.buffer.write(stdout)
|
sys.stdout.buffer.write(stdout)
|
||||||
sys.stdout.buffer.flush()
|
sys.stdout.buffer.flush()
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
|
@ -22,9 +22,10 @@ manages the codec and error handling lookup process.
|
||||||
|
|
||||||
It defines the following functions:
|
It defines the following functions:
|
||||||
|
|
||||||
.. function:: encode(obj, encoding='utf-8', errors='strict')
|
.. function:: encode(obj, [encoding[, errors]])
|
||||||
|
|
||||||
Encodes *obj* using the codec registered for *encoding*.
|
Encodes *obj* using the codec registered for *encoding*. The default
|
||||||
|
encoding is ``utf-8``.
|
||||||
|
|
||||||
*Errors* may be given to set the desired error handling scheme. The
|
*Errors* may be given to set the desired error handling scheme. The
|
||||||
default error handler is ``strict`` meaning that encoding errors raise
|
default error handler is ``strict`` meaning that encoding errors raise
|
||||||
|
@ -32,9 +33,10 @@ It defines the following functions:
|
||||||
:exc:`UnicodeEncodeError`). Refer to :ref:`codec-base-classes` for more
|
:exc:`UnicodeEncodeError`). Refer to :ref:`codec-base-classes` for more
|
||||||
information on codec error handling.
|
information on codec error handling.
|
||||||
|
|
||||||
.. function:: decode(obj, encoding='utf-8', errors='strict')
|
.. function:: decode(obj, [encoding[, errors]])
|
||||||
|
|
||||||
Decodes *obj* using the codec registered for *encoding*.
|
Decodes *obj* using the codec registered for *encoding*. The default
|
||||||
|
encoding is ``utf-8``.
|
||||||
|
|
||||||
*Errors* may be given to set the desired error handling scheme. The
|
*Errors* may be given to set the desired error handling scheme. The
|
||||||
default error handler is ``strict`` meaning that decoding errors raise
|
default error handler is ``strict`` meaning that decoding errors raise
|
||||||
|
|
|
@ -112,7 +112,7 @@ formatted string representation of a message object. For more detail, see
|
||||||
:mod:`email.message`.
|
:mod:`email.message`.
|
||||||
|
|
||||||
.. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78, *, \
|
.. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78, *, \
|
||||||
policy=policy.default)
|
policy=None)
|
||||||
|
|
||||||
The constructor for the :class:`BytesGenerator` class takes a binary
|
The constructor for the :class:`BytesGenerator` class takes a binary
|
||||||
:term:`file-like object` called *outfp* for an argument. *outfp* must
|
:term:`file-like object` called *outfp* for an argument. *outfp* must
|
||||||
|
@ -134,9 +134,11 @@ formatted string representation of a message object. For more detail, see
|
||||||
wrapping. The default is 78, as recommended (but not required) by
|
wrapping. The default is 78, as recommended (but not required) by
|
||||||
:rfc:`2822`.
|
:rfc:`2822`.
|
||||||
|
|
||||||
|
|
||||||
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
|
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
|
||||||
number of aspects of the generator's operation. The default policy
|
number of aspects of the generator's operation. If no *policy* is specified,
|
||||||
maintains backward compatibility.
|
then the *policy* attached to the message object passed to :attr:`flatten`
|
||||||
|
is used.
|
||||||
|
|
||||||
.. versionchanged:: 3.3 Added the *policy* keyword.
|
.. versionchanged:: 3.3 Added the *policy* keyword.
|
||||||
|
|
||||||
|
@ -174,7 +176,7 @@ formatted string representation of a message object. For more detail, see
|
||||||
|
|
||||||
Optional *linesep* specifies the line separator character used to
|
Optional *linesep* specifies the line separator character used to
|
||||||
terminate lines in the output. If specified it overrides the value
|
terminate lines in the output. If specified it overrides the value
|
||||||
specified by the ``Generator``\ 's ``policy``.
|
specified by the ``Generator``\ or *msg*\ 's ``policy``.
|
||||||
|
|
||||||
.. method:: clone(fp)
|
.. method:: clone(fp)
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Here are the methods of the :class:`Message` class:
|
||||||
.. class:: Message(policy=compat32)
|
.. class:: Message(policy=compat32)
|
||||||
|
|
||||||
If *policy* is specified (it must be an instance of a :mod:`~email.policy`
|
If *policy* is specified (it must be an instance of a :mod:`~email.policy`
|
||||||
class) use the rules it specifies to udpate and serialize the representation
|
class) use the rules it specifies to update and serialize the representation
|
||||||
of the message. If *policy* is not set, use the :class:`compat32
|
of the message. If *policy* is not set, use the :class:`compat32
|
||||||
<email.policy.Compat32>` policy, which maintains backward compatibility with
|
<email.policy.Compat32>` policy, which maintains backward compatibility with
|
||||||
the Python 3.2 version of the email package. For more information see the
|
the Python 3.2 version of the email package. For more information see the
|
||||||
|
|
|
@ -60,15 +60,18 @@ list of defects that it can find.
|
||||||
Here is the API for the :class:`FeedParser`:
|
Here is the API for the :class:`FeedParser`:
|
||||||
|
|
||||||
|
|
||||||
.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.default)
|
.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.compat32)
|
||||||
|
|
||||||
Create a :class:`FeedParser` instance. Optional *_factory* is a no-argument
|
Create a :class:`FeedParser` instance. Optional *_factory* is a no-argument
|
||||||
callable that will be called whenever a new message object is needed. It
|
callable that will be called whenever a new message object is needed. It
|
||||||
defaults to the :class:`email.message.Message` class.
|
defaults to the :class:`email.message.Message` class.
|
||||||
|
|
||||||
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
|
If *policy* is specified (it must be an instance of a :mod:`~email.policy`
|
||||||
number of aspects of the parser's operation. The default policy maintains
|
class) use the rules it specifies to update the representation of the
|
||||||
backward compatibility.
|
message. If *policy* is not set, use the :class:`compat32
|
||||||
|
<email.policy.Compat32>` policy, which maintains backward compatibility with
|
||||||
|
the Python 3.2 version of the email package. For more information see the
|
||||||
|
:mod:`~email.policy` documentation.
|
||||||
|
|
||||||
.. versionchanged:: 3.3 Added the *policy* keyword.
|
.. versionchanged:: 3.3 Added the *policy* keyword.
|
||||||
|
|
||||||
|
@ -113,7 +116,7 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes.
|
||||||
The BytesHeaderParser class.
|
The BytesHeaderParser class.
|
||||||
|
|
||||||
|
|
||||||
.. class:: Parser(_class=email.message.Message, *, policy=policy.default)
|
.. class:: Parser(_class=email.message.Message, *, policy=policy.compat32)
|
||||||
|
|
||||||
The constructor for the :class:`Parser` class takes an optional argument
|
The constructor for the :class:`Parser` class takes an optional argument
|
||||||
*_class*. This must be a callable factory (such as a function or a class), and
|
*_class*. This must be a callable factory (such as a function or a class), and
|
||||||
|
@ -121,9 +124,12 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes.
|
||||||
:class:`~email.message.Message` (see :mod:`email.message`). The factory will
|
:class:`~email.message.Message` (see :mod:`email.message`). The factory will
|
||||||
be called without arguments.
|
be called without arguments.
|
||||||
|
|
||||||
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
|
If *policy* is specified (it must be an instance of a :mod:`~email.policy`
|
||||||
number of aspects of the parser's operation. The default policy maintains
|
class) use the rules it specifies to update the representation of the
|
||||||
backward compatibility.
|
message. If *policy* is not set, use the :class:`compat32
|
||||||
|
<email.policy.Compat32>` policy, which maintains backward compatibility with
|
||||||
|
the Python 3.2 version of the email package. For more information see the
|
||||||
|
:mod:`~email.policy` documentation.
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
Removed the *strict* argument that was deprecated in 2.4. Added the
|
Removed the *strict* argument that was deprecated in 2.4. Added the
|
||||||
|
@ -159,15 +165,18 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes.
|
||||||
Optional *headersonly* is as with the :meth:`parse` method.
|
Optional *headersonly* is as with the :meth:`parse` method.
|
||||||
|
|
||||||
|
|
||||||
.. class:: BytesParser(_class=email.message.Message, *, policy=policy.default)
|
.. class:: BytesParser(_class=email.message.Message, *, policy=policy.compat32)
|
||||||
|
|
||||||
This class is exactly parallel to :class:`Parser`, but handles bytes input.
|
This class is exactly parallel to :class:`Parser`, but handles bytes input.
|
||||||
The *_class* and *strict* arguments are interpreted in the same way as for
|
The *_class* and *strict* arguments are interpreted in the same way as for
|
||||||
the :class:`Parser` constructor.
|
the :class:`Parser` constructor.
|
||||||
|
|
||||||
The *policy* keyword specifies a :mod:`~email.policy` object that
|
If *policy* is specified (it must be an instance of a :mod:`~email.policy`
|
||||||
controls a number of aspects of the parser's operation. The default
|
class) use the rules it specifies to update the representation of the
|
||||||
policy maintains backward compatibility.
|
message. If *policy* is not set, use the :class:`compat32
|
||||||
|
<email.policy.Compat32>` policy, which maintains backward compatibility with
|
||||||
|
the Python 3.2 version of the email package. For more information see the
|
||||||
|
:mod:`~email.policy` documentation.
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
Removed the *strict* argument. Added the *policy* keyword.
|
Removed the *strict* argument. Added the *policy* keyword.
|
||||||
|
@ -209,7 +218,7 @@ in the top-level :mod:`email` package namespace.
|
||||||
.. currentmodule:: email
|
.. currentmodule:: email
|
||||||
|
|
||||||
.. function:: message_from_string(s, _class=email.message.Message, *, \
|
.. function:: message_from_string(s, _class=email.message.Message, *, \
|
||||||
policy=policy.default)
|
policy=policy.compat32)
|
||||||
|
|
||||||
Return a message object structure from a string. This is exactly equivalent to
|
Return a message object structure from a string. This is exactly equivalent to
|
||||||
``Parser().parsestr(s)``. *_class* and *policy* are interpreted as
|
``Parser().parsestr(s)``. *_class* and *policy* are interpreted as
|
||||||
|
@ -219,7 +228,7 @@ in the top-level :mod:`email` package namespace.
|
||||||
Removed the *strict* argument. Added the *policy* keyword.
|
Removed the *strict* argument. Added the *policy* keyword.
|
||||||
|
|
||||||
.. function:: message_from_bytes(s, _class=email.message.Message, *, \
|
.. function:: message_from_bytes(s, _class=email.message.Message, *, \
|
||||||
policy=policy.default)
|
policy=policy.compat32)
|
||||||
|
|
||||||
Return a message object structure from a byte string. This is exactly
|
Return a message object structure from a byte string. This is exactly
|
||||||
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
|
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
|
||||||
|
@ -231,7 +240,7 @@ in the top-level :mod:`email` package namespace.
|
||||||
Removed the *strict* argument. Added the *policy* keyword.
|
Removed the *strict* argument. Added the *policy* keyword.
|
||||||
|
|
||||||
.. function:: message_from_file(fp, _class=email.message.Message, *, \
|
.. function:: message_from_file(fp, _class=email.message.Message, *, \
|
||||||
policy=policy.default)
|
policy=policy.compat32)
|
||||||
|
|
||||||
Return a message object structure tree from an open :term:`file object`.
|
Return a message object structure tree from an open :term:`file object`.
|
||||||
This is exactly equivalent to ``Parser().parse(fp)``. *_class*
|
This is exactly equivalent to ``Parser().parse(fp)``. *_class*
|
||||||
|
@ -242,7 +251,7 @@ in the top-level :mod:`email` package namespace.
|
||||||
Removed the *strict* argument. Added the *policy* keyword.
|
Removed the *strict* argument. Added the *policy* keyword.
|
||||||
|
|
||||||
.. function:: message_from_binary_file(fp, _class=email.message.Message, *, \
|
.. function:: message_from_binary_file(fp, _class=email.message.Message, *, \
|
||||||
policy=policy.default)
|
policy=policy.compat32)
|
||||||
|
|
||||||
Return a message object structure tree from an open binary :term:`file
|
Return a message object structure tree from an open binary :term:`file
|
||||||
object`. This is exactly equivalent to ``BytesParser().parse(fp)``.
|
object`. This is exactly equivalent to ``BytesParser().parse(fp)``.
|
||||||
|
|
|
@ -79,7 +79,9 @@ This module provides an interface to the mechanisms used to implement the
|
||||||
When *P* itself has a dotted name, apply this recipe recursively.
|
When *P* itself has a dotted name, apply this recipe recursively.
|
||||||
|
|
||||||
.. deprecated:: 3.3
|
.. deprecated:: 3.3
|
||||||
Use :func:`importlib.find_loader` instead.
|
Use :func:`importlib.util.find_spec` instead unless Python 3.3
|
||||||
|
compatibility is required, in which case use
|
||||||
|
:func:`importlib.find_loader`.
|
||||||
|
|
||||||
|
|
||||||
.. function:: load_module(name, file, pathname, description)
|
.. function:: load_module(name, file, pathname, description)
|
||||||
|
@ -104,9 +106,11 @@ This module provides an interface to the mechanisms used to implement the
|
||||||
|
|
||||||
.. deprecated:: 3.3
|
.. deprecated:: 3.3
|
||||||
If previously used in conjunction with :func:`imp.find_module` then
|
If previously used in conjunction with :func:`imp.find_module` then
|
||||||
call ``load_module()`` on the returned loader. If you wish to load a
|
consider using :func:`importlib.import_module`, otherwise use the loader
|
||||||
module from a specific file, then use one of the file-based loaders found
|
returned by the replacement you chose for :func:`imp.find_module`. If you
|
||||||
in :mod:`importlib.machinery`.
|
called :func:`imp.load_module` and related functions directly then use the
|
||||||
|
classes in :mod:`importlib.machinery`, e.g.
|
||||||
|
``importlib.machinery.SourceFileLoader(name, path).load_module()``.
|
||||||
|
|
||||||
|
|
||||||
.. function:: new_module(name)
|
.. function:: new_module(name)
|
||||||
|
|
|
@ -887,6 +887,11 @@ find and load modules.
|
||||||
|
|
||||||
Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`.
|
Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`.
|
||||||
|
|
||||||
|
.. method:: load_module(name=None)
|
||||||
|
|
||||||
|
Concrete implementation of :meth:`importlib.abc.Loader.load_module` where
|
||||||
|
specifying the name of the module to load is optional.
|
||||||
|
|
||||||
|
|
||||||
.. class:: SourcelessFileLoader(fullname, path)
|
.. class:: SourcelessFileLoader(fullname, path)
|
||||||
|
|
||||||
|
@ -921,6 +926,11 @@ find and load modules.
|
||||||
Returns ``None`` as bytecode files have no source when this loader is
|
Returns ``None`` as bytecode files have no source when this loader is
|
||||||
used.
|
used.
|
||||||
|
|
||||||
|
.. method:: load_module(name=None)
|
||||||
|
|
||||||
|
Concrete implementation of :meth:`importlib.abc.Loader.load_module` where
|
||||||
|
specifying the name of the module to load is optional.
|
||||||
|
|
||||||
|
|
||||||
.. class:: ExtensionFileLoader(fullname, path)
|
.. class:: ExtensionFileLoader(fullname, path)
|
||||||
|
|
||||||
|
@ -940,7 +950,7 @@ find and load modules.
|
||||||
|
|
||||||
Path to the extension module.
|
Path to the extension module.
|
||||||
|
|
||||||
.. method:: load_module(fullname)
|
.. method:: load_module(name=None)
|
||||||
|
|
||||||
Loads the extension module if and only if *fullname* is the same as
|
Loads the extension module if and only if *fullname* is the same as
|
||||||
:attr:`name` or is ``None``.
|
:attr:`name` or is ``None``.
|
||||||
|
|
|
@ -1588,8 +1588,19 @@ the sockets in non-blocking mode and use an event loop).
|
||||||
Notes on non-blocking sockets
|
Notes on non-blocking sockets
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
When working with non-blocking sockets, there are several things you need
|
SSL sockets behave slightly different than regular sockets in
|
||||||
to be aware of:
|
non-blocking mode. When working with non-blocking sockets, there are
|
||||||
|
thus several things you need to be aware of:
|
||||||
|
|
||||||
|
- Most :class:`SSLSocket` methods will raise either
|
||||||
|
:exc:`SSLWantWriteError` or :exc:`SSLWantReadError` instead of
|
||||||
|
:exc:`BlockingIOError` if an I/O operation would
|
||||||
|
block. :exc:`SSLWantReadError` will be raised if a read operation on
|
||||||
|
the underlying socket is necessary, and :exc:`SSLWantWriteError` for
|
||||||
|
a write operation on the underlying socket. Note that attempts to
|
||||||
|
*write* to an SSL socket may require *reading* from the underlying
|
||||||
|
socket first, and attempts to *read* from the SSL socket may require
|
||||||
|
a prior *write* to the underlying socket.
|
||||||
|
|
||||||
- Calling :func:`~select.select` tells you that the OS-level socket can be
|
- Calling :func:`~select.select` tells you that the OS-level socket can be
|
||||||
read from (or written to), but it does not imply that there is sufficient
|
read from (or written to), but it does not imply that there is sufficient
|
||||||
|
@ -1598,8 +1609,14 @@ to be aware of:
|
||||||
and :meth:`SSLSocket.send` failures, and retry after another call to
|
and :meth:`SSLSocket.send` failures, and retry after another call to
|
||||||
:func:`~select.select`.
|
:func:`~select.select`.
|
||||||
|
|
||||||
|
- Conversely, since the SSL layer has its own framing, a SSL socket may
|
||||||
|
still have data available for reading without :func:`~select.select`
|
||||||
|
being aware of it. Therefore, you should first call
|
||||||
|
:meth:`SSLSocket.recv` to drain any potentially available data, and then
|
||||||
|
only block on a :func:`~select.select` call if still necessary.
|
||||||
|
|
||||||
(of course, similar provisions apply when using other primitives such as
|
(of course, similar provisions apply when using other primitives such as
|
||||||
:func:`~select.poll`)
|
:func:`~select.poll`, or those in the :mod:`selectors` module)
|
||||||
|
|
||||||
- The SSL handshake itself will be non-blocking: the
|
- The SSL handshake itself will be non-blocking: the
|
||||||
:meth:`SSLSocket.do_handshake` method has to be retried until it returns
|
:meth:`SSLSocket.do_handshake` method has to be retried until it returns
|
||||||
|
|
|
@ -54,18 +54,12 @@ use cases, the underlying :class:`Popen` interface can be used directly.
|
||||||
>>> subprocess.call("exit 1", shell=True)
|
>>> subprocess.call("exit 1", shell=True)
|
||||||
1
|
1
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Invoking the system shell with ``shell=True`` can be a security hazard
|
|
||||||
if combined with untrusted input. See the warning under
|
|
||||||
:ref:`frequently-used-arguments` for details.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this function. As
|
Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this
|
||||||
the pipes are not being read in the current process, the child
|
function. The child process will block if it generates enough
|
||||||
process may block if it generates enough output to a pipe to fill up
|
output to a pipe to fill up the OS pipe buffer as the pipes are
|
||||||
the OS pipe buffer.
|
not being read from.
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
*timeout* was added.
|
*timeout* was added.
|
||||||
|
@ -99,18 +93,12 @@ use cases, the underlying :class:`Popen` interface can be used directly.
|
||||||
...
|
...
|
||||||
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
|
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Invoking the system shell with ``shell=True`` can be a security hazard
|
|
||||||
if combined with untrusted input. See the warning under
|
|
||||||
:ref:`frequently-used-arguments` for details.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this function. As
|
Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this
|
||||||
the pipes are not being read in the current process, the child
|
function. The child process will block if it generates enough
|
||||||
process may block if it generates enough output to a pipe to fill up
|
output to a pipe to fill up the OS pipe buffer as the pipes are
|
||||||
the OS pipe buffer.
|
not being read from.
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
*timeout* was added.
|
*timeout* was added.
|
||||||
|
@ -177,17 +165,12 @@ use cases, the underlying :class:`Popen` interface can be used directly.
|
||||||
... shell=True)
|
... shell=True)
|
||||||
'ls: non_existent_file: No such file or directory\n'
|
'ls: non_existent_file: No such file or directory\n'
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Invoking the system shell with ``shell=True`` can be a security hazard
|
|
||||||
if combined with untrusted input. See the warning under
|
|
||||||
:ref:`frequently-used-arguments` for details.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Do not use ``stderr=PIPE`` with this function. As the pipe is not being
|
Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this
|
||||||
read in the current process, the child process may block if it
|
function. The child process will block if it generates enough
|
||||||
generates enough output to the pipe to fill up the OS pipe buffer.
|
output to a pipe to fill up the OS pipe buffer as the pipes are
|
||||||
|
not being read from.
|
||||||
|
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
@ -210,7 +193,7 @@ use cases, the underlying :class:`Popen` interface can be used directly.
|
||||||
|
|
||||||
Special value that can be used as the *stdin*, *stdout* or *stderr* argument
|
Special value that can be used as the *stdin*, *stdout* or *stderr* argument
|
||||||
to :class:`Popen` and indicates that a pipe to the standard stream should be
|
to :class:`Popen` and indicates that a pipe to the standard stream should be
|
||||||
opened.
|
opened. Most useful with :meth:`Popen.communicate`.
|
||||||
|
|
||||||
|
|
||||||
.. data:: STDOUT
|
.. data:: STDOUT
|
||||||
|
@ -336,28 +319,9 @@ default values. The arguments that are most commonly needed are:
|
||||||
instead of ``locale.getpreferredencoding()``. See the
|
instead of ``locale.getpreferredencoding()``. See the
|
||||||
:class:`io.TextIOWrapper` class for more information on this change.
|
:class:`io.TextIOWrapper` class for more information on this change.
|
||||||
|
|
||||||
.. warning::
|
.. note::
|
||||||
|
|
||||||
Executing shell commands that incorporate unsanitized input from an
|
Read the `Security Considerations`_ section before using ``shell=True``.
|
||||||
untrusted source makes a program vulnerable to `shell injection
|
|
||||||
<http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_,
|
|
||||||
a serious security flaw which can result in arbitrary command execution.
|
|
||||||
For this reason, the use of ``shell=True`` is **strongly discouraged**
|
|
||||||
in cases where the command string is constructed from external input::
|
|
||||||
|
|
||||||
>>> from subprocess import call
|
|
||||||
>>> filename = input("What file would you like to display?\n")
|
|
||||||
What file would you like to display?
|
|
||||||
non_existent; rm -rf / #
|
|
||||||
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
|
|
||||||
|
|
||||||
``shell=False`` disables all shell based features, but does not suffer
|
|
||||||
from this vulnerability; see the Note in the :class:`Popen` constructor
|
|
||||||
documentation for helpful hints in getting ``shell=False`` to work.
|
|
||||||
|
|
||||||
When using ``shell=True``, :func:`shlex.quote` can be used to properly
|
|
||||||
escape whitespace and shell metacharacters in strings that are going to
|
|
||||||
be used to construct shell commands.
|
|
||||||
|
|
||||||
These options, along with all of the other options, are described in more
|
These options, along with all of the other options, are described in more
|
||||||
detail in the :class:`Popen` constructor documentation.
|
detail in the :class:`Popen` constructor documentation.
|
||||||
|
@ -378,7 +342,7 @@ functions.
|
||||||
startupinfo=None, creationflags=0, restore_signals=True, \
|
startupinfo=None, creationflags=0, restore_signals=True, \
|
||||||
start_new_session=False, pass_fds=())
|
start_new_session=False, pass_fds=())
|
||||||
|
|
||||||
Execute a child program in a new process. On Unix, the class uses
|
Execute a child program in a new process. On POSIX, the class uses
|
||||||
:meth:`os.execvp`-like behavior to execute the child program. On Windows,
|
:meth:`os.execvp`-like behavior to execute the child program. On Windows,
|
||||||
the class uses the Windows ``CreateProcess()`` function. The arguments to
|
the class uses the Windows ``CreateProcess()`` function. The arguments to
|
||||||
:class:`Popen` are as follows.
|
:class:`Popen` are as follows.
|
||||||
|
@ -390,7 +354,7 @@ functions.
|
||||||
arguments for additional differences from the default behavior. Unless
|
arguments for additional differences from the default behavior. Unless
|
||||||
otherwise stated, it is recommended to pass *args* as a sequence.
|
otherwise stated, it is recommended to pass *args* as a sequence.
|
||||||
|
|
||||||
On Unix, if *args* is a string, the string is interpreted as the name or
|
On POSIX, if *args* is a string, the string is interpreted as the name or
|
||||||
path of the program to execute. However, this can only be done if not
|
path of the program to execute. However, this can only be done if not
|
||||||
passing arguments to the program.
|
passing arguments to the program.
|
||||||
|
|
||||||
|
@ -421,7 +385,7 @@ functions.
|
||||||
the shell as the program to execute. If *shell* is *True*, it is
|
the shell as the program to execute. If *shell* is *True*, it is
|
||||||
recommended to pass *args* as a string rather than as a sequence.
|
recommended to pass *args* as a string rather than as a sequence.
|
||||||
|
|
||||||
On Unix with ``shell=True``, the shell defaults to :file:`/bin/sh`. If
|
On POSIX with ``shell=True``, the shell defaults to :file:`/bin/sh`. If
|
||||||
*args* is a string, the string specifies the command
|
*args* is a string, the string specifies the command
|
||||||
to execute through the shell. This means that the string must be
|
to execute through the shell. This means that the string must be
|
||||||
formatted exactly as it would be when typed at the shell prompt. This
|
formatted exactly as it would be when typed at the shell prompt. This
|
||||||
|
@ -438,11 +402,9 @@ functions.
|
||||||
into the shell (e.g. :command:`dir` or :command:`copy`). You do not need
|
into the shell (e.g. :command:`dir` or :command:`copy`). You do not need
|
||||||
``shell=True`` to run a batch file or console-based executable.
|
``shell=True`` to run a batch file or console-based executable.
|
||||||
|
|
||||||
.. warning::
|
.. note::
|
||||||
|
|
||||||
Passing ``shell=True`` can be a security hazard if combined with
|
Read the `Security Considerations`_ section before using ``shell=True``.
|
||||||
untrusted input. See the warning under :ref:`frequently-used-arguments`
|
|
||||||
for details.
|
|
||||||
|
|
||||||
*bufsize* will be supplied as the corresponding argument to the :func:`open`
|
*bufsize* will be supplied as the corresponding argument to the :func:`open`
|
||||||
function when creating the stdin/stdout/stderr pipe file objects: :const:`0`
|
function when creating the stdin/stdout/stderr pipe file objects: :const:`0`
|
||||||
|
@ -463,9 +425,9 @@ functions.
|
||||||
program to execute specified by *args*. However, the original *args* is
|
program to execute specified by *args*. However, the original *args* is
|
||||||
still passed to the program. Most programs treat the program specified
|
still passed to the program. Most programs treat the program specified
|
||||||
by *args* as the command name, which can then be different from the program
|
by *args* as the command name, which can then be different from the program
|
||||||
actually executed. On Unix, the *args* name
|
actually executed. On POSIX, the *args* name
|
||||||
becomes the display name for the executable in utilities such as
|
becomes the display name for the executable in utilities such as
|
||||||
:program:`ps`. If ``shell=True``, on Unix the *executable* argument
|
:program:`ps`. If ``shell=True``, on POSIX the *executable* argument
|
||||||
specifies a replacement shell for the default :file:`/bin/sh`.
|
specifies a replacement shell for the default :file:`/bin/sh`.
|
||||||
|
|
||||||
*stdin*, *stdout* and *stderr* specify the executed program's standard input,
|
*stdin*, *stdout* and *stderr* specify the executed program's standard input,
|
||||||
|
@ -481,7 +443,7 @@ functions.
|
||||||
|
|
||||||
If *preexec_fn* is set to a callable object, this object will be called in the
|
If *preexec_fn* is set to a callable object, this object will be called in the
|
||||||
child process just before the child is executed.
|
child process just before the child is executed.
|
||||||
(Unix only)
|
(POSIX only)
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
@ -499,8 +461,8 @@ functions.
|
||||||
common use of *preexec_fn* to call os.setsid() in the child.
|
common use of *preexec_fn* to call os.setsid() in the child.
|
||||||
|
|
||||||
If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and
|
If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and
|
||||||
:const:`2` will be closed before the child process is executed. (Unix only).
|
:const:`2` will be closed before the child process is executed. (POSIX only).
|
||||||
The default varies by platform: Always true on Unix. On Windows it is
|
The default varies by platform: Always true on POSIX. On Windows it is
|
||||||
true when *stdin*/*stdout*/*stderr* are :const:`None`, false otherwise.
|
true when *stdin*/*stdout*/*stderr* are :const:`None`, false otherwise.
|
||||||
On Windows, if *close_fds* is true then no handles will be inherited by the
|
On Windows, if *close_fds* is true then no handles will be inherited by the
|
||||||
child process. Note that on Windows, you cannot set *close_fds* to true and
|
child process. Note that on Windows, you cannot set *close_fds* to true and
|
||||||
|
@ -512,7 +474,7 @@ functions.
|
||||||
|
|
||||||
*pass_fds* is an optional sequence of file descriptors to keep open
|
*pass_fds* is an optional sequence of file descriptors to keep open
|
||||||
between the parent and child. Providing any *pass_fds* forces
|
between the parent and child. Providing any *pass_fds* forces
|
||||||
*close_fds* to be :const:`True`. (Unix only)
|
*close_fds* to be :const:`True`. (POSIX only)
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
The *pass_fds* parameter was added.
|
The *pass_fds* parameter was added.
|
||||||
|
@ -525,13 +487,13 @@ functions.
|
||||||
If *restore_signals* is true (the default) all signals that Python has set to
|
If *restore_signals* is true (the default) all signals that Python has set to
|
||||||
SIG_IGN are restored to SIG_DFL in the child process before the exec.
|
SIG_IGN are restored to SIG_DFL in the child process before the exec.
|
||||||
Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals.
|
Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals.
|
||||||
(Unix only)
|
(POSIX only)
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
*restore_signals* was added.
|
*restore_signals* was added.
|
||||||
|
|
||||||
If *start_new_session* is true the setsid() system call will be made in the
|
If *start_new_session* is true the setsid() system call will be made in the
|
||||||
child process prior to the execution of the subprocess. (Unix only)
|
child process prior to the execution of the subprocess. (POSIX only)
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
*start_new_session* was added.
|
*start_new_session* was added.
|
||||||
|
@ -598,14 +560,21 @@ Exceptions defined in this module all inherit from :exc:`SubprocessError`.
|
||||||
The :exc:`SubprocessError` base class was added.
|
The :exc:`SubprocessError` base class was added.
|
||||||
|
|
||||||
|
|
||||||
Security
|
Security Considerations
|
||||||
^^^^^^^^
|
-----------------------
|
||||||
|
|
||||||
Unlike some other popen functions, this implementation will never call a
|
Unlike some other popen functions, this implementation will never
|
||||||
system shell implicitly. This means that all characters, including shell
|
implicitly call a system shell. This means that all characters,
|
||||||
metacharacters, can safely be passed to child processes. Obviously, if the
|
including shell metacharacters, can safely be passed to child processes.
|
||||||
shell is invoked explicitly, then it is the application's responsibility to
|
If the shell is invoked explicitly, via ``shell=True``, it is the application's
|
||||||
ensure that all whitespace and metacharacters are quoted appropriately.
|
responsibility to ensure that all whitespace and metacharacters are
|
||||||
|
quoted appropriately to avoid
|
||||||
|
`shell injection <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
|
||||||
|
vulnerabilities.
|
||||||
|
|
||||||
|
When using ``shell=True``, the :func:`shlex.quote` function can be
|
||||||
|
used to properly escape whitespace and shell metacharacters in strings
|
||||||
|
that are going to be used to construct shell commands.
|
||||||
|
|
||||||
|
|
||||||
Popen Objects
|
Popen Objects
|
||||||
|
@ -629,27 +598,27 @@ Instances of the :class:`Popen` class have the following methods:
|
||||||
:exc:`TimeoutExpired` exception. It is safe to catch this exception and
|
:exc:`TimeoutExpired` exception. It is safe to catch this exception and
|
||||||
retry the wait.
|
retry the wait.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This will deadlock when using ``stdout=PIPE`` or ``stderr=PIPE``
|
||||||
|
and the child process generates enough output to a pipe such that
|
||||||
|
it blocks waiting for the OS pipe buffer to accept more data.
|
||||||
|
Use :meth:`Popen.communicate` when using pipes to avoid that.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The function is implemented using a busy loop (non-blocking call and
|
The function is implemented using a busy loop (non-blocking call and
|
||||||
short sleeps). Use the :mod:`asyncio` module for an asynchronous wait:
|
short sleeps). Use the :mod:`asyncio` module for an asynchronous wait:
|
||||||
see :class:`asyncio.create_subprocess_exec`.
|
see :class:`asyncio.create_subprocess_exec`.
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
This will deadlock when using ``stdout=PIPE`` and/or
|
|
||||||
``stderr=PIPE`` and the child process generates enough output to
|
|
||||||
a pipe such that it blocks waiting for the OS pipe buffer to
|
|
||||||
accept more data. Use :meth:`communicate` to avoid that.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
*timeout* was added.
|
*timeout* was added.
|
||||||
|
|
||||||
.. deprecated:: 3.4
|
.. deprecated:: 3.4
|
||||||
|
|
||||||
Do not use the undocumented *endtime* parameter. It is was
|
Do not use the *endtime* parameter. It is was unintentionally
|
||||||
unintentionally exposed in 3.3 but was intended to be private
|
exposed in 3.3 but was left undocumented as it was intended to be
|
||||||
for internal use. Use *timeout* instead.
|
private for internal use. Use *timeout* instead.
|
||||||
|
|
||||||
.. method:: Popen.communicate(input=None, timeout=None)
|
.. method:: Popen.communicate(input=None, timeout=None)
|
||||||
|
|
||||||
|
@ -716,13 +685,6 @@ Instances of the :class:`Popen` class have the following methods:
|
||||||
|
|
||||||
The following attributes are also available:
|
The following attributes are also available:
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Use :meth:`~Popen.communicate` rather than :attr:`.stdin.write <Popen.stdin>`,
|
|
||||||
:attr:`.stdout.read <Popen.stdout>` or :attr:`.stderr.read <Popen.stderr>` to avoid
|
|
||||||
deadlocks due to any of the other OS pipe buffers filling up and blocking the
|
|
||||||
child process.
|
|
||||||
|
|
||||||
.. attribute:: Popen.args
|
.. attribute:: Popen.args
|
||||||
|
|
||||||
The *args* argument as it was passed to :class:`Popen` -- a
|
The *args* argument as it was passed to :class:`Popen` -- a
|
||||||
|
@ -756,6 +718,13 @@ The following attributes are also available:
|
||||||
``True``, the stream is a text stream, otherwise it is a byte stream. If the
|
``True``, the stream is a text stream, otherwise it is a byte stream. If the
|
||||||
*stderr* argument was not :data:`PIPE`, this attribute is ``None``.
|
*stderr* argument was not :data:`PIPE`, this attribute is ``None``.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Use :meth:`~Popen.communicate` rather than :attr:`.stdin.write <Popen.stdin>`,
|
||||||
|
:attr:`.stdout.read <Popen.stdout>` or :attr:`.stderr.read <Popen.stderr>` to avoid
|
||||||
|
deadlocks due to any of the other OS pipe buffers filling up and blocking the
|
||||||
|
child process.
|
||||||
|
|
||||||
|
|
||||||
.. attribute:: Popen.pid
|
.. attribute:: Popen.pid
|
||||||
|
|
||||||
|
@ -772,7 +741,7 @@ The following attributes are also available:
|
||||||
hasn't terminated yet.
|
hasn't terminated yet.
|
||||||
|
|
||||||
A negative value ``-N`` indicates that the child was terminated by signal
|
A negative value ``-N`` indicates that the child was terminated by signal
|
||||||
``N`` (Unix only).
|
``N`` (POSIX only).
|
||||||
|
|
||||||
|
|
||||||
Windows Popen Helpers
|
Windows Popen Helpers
|
||||||
|
@ -1044,7 +1013,7 @@ Replacing functions from the :mod:`popen2` module
|
||||||
|
|
||||||
(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
|
(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
|
||||||
==>
|
==>
|
||||||
p = Popen(["somestring"], shell=True, bufsize=bufsize,
|
p = Popen("somestring", shell=True, bufsize=bufsize,
|
||||||
stdin=PIPE, stdout=PIPE, close_fds=True)
|
stdin=PIPE, stdout=PIPE, close_fds=True)
|
||||||
(child_stdout, child_stdin) = (p.stdout, p.stdin)
|
(child_stdout, child_stdin) = (p.stdout, p.stdin)
|
||||||
|
|
||||||
|
@ -1097,7 +1066,7 @@ handling consistency are valid for these functions.
|
||||||
>>> subprocess.getstatusoutput('/bin/junk')
|
>>> subprocess.getstatusoutput('/bin/junk')
|
||||||
(256, 'sh: /bin/junk: not found')
|
(256, 'sh: /bin/junk: not found')
|
||||||
|
|
||||||
Availability: Unix & Windows
|
Availability: POSIX & Windows
|
||||||
|
|
||||||
.. versionchanged:: 3.3.4
|
.. versionchanged:: 3.3.4
|
||||||
Windows support added
|
Windows support added
|
||||||
|
@ -1113,7 +1082,7 @@ handling consistency are valid for these functions.
|
||||||
>>> subprocess.getoutput('ls /bin/ls')
|
>>> subprocess.getoutput('ls /bin/ls')
|
||||||
'/bin/ls'
|
'/bin/ls'
|
||||||
|
|
||||||
Availability: Unix & Windows
|
Availability: POSIX & Windows
|
||||||
|
|
||||||
.. versionchanged:: 3.3.4
|
.. versionchanged:: 3.3.4
|
||||||
Windows support added
|
Windows support added
|
||||||
|
|
|
@ -1066,8 +1066,9 @@ always available.
|
||||||
statements and for the prompts of :func:`input`;
|
statements and for the prompts of :func:`input`;
|
||||||
* The interpreter's own prompts and its error messages go to ``stderr``.
|
* The interpreter's own prompts and its error messages go to ``stderr``.
|
||||||
|
|
||||||
By default, these streams are regular text streams as returned by the
|
These streams are regular :term:`text files <text file>` like those
|
||||||
:func:`open` function. Their parameters are chosen as follows:
|
returned by the :func:`open` function. Their parameters are chosen as
|
||||||
|
follows:
|
||||||
|
|
||||||
* The character encoding is platform-dependent. Under Windows, if the stream
|
* The character encoding is platform-dependent. Under Windows, if the stream
|
||||||
is interactive (that is, if its :meth:`isatty` method returns ``True``), the
|
is interactive (that is, if its :meth:`isatty` method returns ``True``), the
|
||||||
|
@ -1075,26 +1076,22 @@ always available.
|
||||||
platforms, the locale encoding is used (see :meth:`locale.getpreferredencoding`).
|
platforms, the locale encoding is used (see :meth:`locale.getpreferredencoding`).
|
||||||
|
|
||||||
Under all platforms though, you can override this value by setting the
|
Under all platforms though, you can override this value by setting the
|
||||||
:envvar:`PYTHONIOENCODING` environment variable.
|
:envvar:`PYTHONIOENCODING` environment variable before starting Python.
|
||||||
|
|
||||||
* When interactive, standard streams are line-buffered. Otherwise, they
|
* When interactive, standard streams are line-buffered. Otherwise, they
|
||||||
are block-buffered like regular text files. You can override this
|
are block-buffered like regular text files. You can override this
|
||||||
value with the :option:`-u` command-line option.
|
value with the :option:`-u` command-line option.
|
||||||
|
|
||||||
To write or read binary data from/to the standard streams, use the
|
.. note::
|
||||||
underlying binary :data:`~io.TextIOBase.buffer`. For example, to write
|
|
||||||
bytes to :data:`stdout`, use ``sys.stdout.buffer.write(b'abc')``. Using
|
|
||||||
:meth:`io.TextIOBase.detach`, streams can be made binary by default. This
|
|
||||||
function sets :data:`stdin` and :data:`stdout` to binary::
|
|
||||||
|
|
||||||
def make_streams_binary():
|
To write or read binary data from/to the standard streams, use the
|
||||||
sys.stdin = sys.stdin.detach()
|
underlying binary :data:`~io.TextIOBase.buffer` object. For example, to
|
||||||
sys.stdout = sys.stdout.detach()
|
write bytes to :data:`stdout`, use ``sys.stdout.buffer.write(b'abc')``.
|
||||||
|
|
||||||
Note that the streams may be replaced with objects (like :class:`io.StringIO`)
|
However, if you are writing a library (and do not control in which
|
||||||
that do not support the :attr:`~io.BufferedIOBase.buffer` attribute or the
|
context its code will be executed), be aware that the standard streams
|
||||||
:meth:`~io.BufferedIOBase.detach` method and can raise :exc:`AttributeError`
|
may be replaced with file-like objects like :class:`io.StringIO` which
|
||||||
or :exc:`io.UnsupportedOperation`.
|
do not support the :attr:`~io.BufferedIOBase.buffer` attribute.
|
||||||
|
|
||||||
|
|
||||||
.. data:: __stdin__
|
.. data:: __stdin__
|
||||||
|
|
|
@ -40,11 +40,11 @@ Creating virtual environments
|
||||||
A venv is a directory tree which contains Python executable files and
|
A venv is a directory tree which contains Python executable files and
|
||||||
other files which indicate that it is a venv.
|
other files which indicate that it is a venv.
|
||||||
|
|
||||||
Common installation tools such as ``Distribute`` and ``pip`` work as
|
Common installation tools such as ``Setuptools`` and ``pip`` work as
|
||||||
expected with venvs - i.e. when a venv is active, they install Python
|
expected with venvs - i.e. when a venv is active, they install Python
|
||||||
packages into the venv without needing to be told to do so explicitly.
|
packages into the venv without needing to be told to do so explicitly.
|
||||||
Of course, you need to install them into the venv first: this could be
|
Of course, you need to install them into the venv first: this could be
|
||||||
done by running ``distribute_setup.py`` with the venv activated,
|
done by running ``ez_setup.py`` with the venv activated,
|
||||||
followed by running ``easy_install pip``. Alternatively, you could download
|
followed by running ``easy_install pip``. Alternatively, you could download
|
||||||
the source tarballs and run ``python setup.py install`` after unpacking,
|
the source tarballs and run ``python setup.py install`` after unpacking,
|
||||||
with the venv activated.
|
with the venv activated.
|
||||||
|
|
|
@ -313,14 +313,14 @@ exception, the saved exception is set as the context of the new exception.
|
||||||
If the :keyword:`finally` clause executes a :keyword:`return` or :keyword:`break`
|
If the :keyword:`finally` clause executes a :keyword:`return` or :keyword:`break`
|
||||||
statement, the saved exception is discarded::
|
statement, the saved exception is discarded::
|
||||||
|
|
||||||
def f():
|
>>> def f():
|
||||||
try:
|
... try:
|
||||||
1/0
|
... 1/0
|
||||||
finally:
|
... finally:
|
||||||
return 42
|
... return 42
|
||||||
|
...
|
||||||
>>> f()
|
>>> f()
|
||||||
42
|
42
|
||||||
|
|
||||||
The exception information is not available to the program during execution of
|
The exception information is not available to the program during execution of
|
||||||
the :keyword:`finally` clause.
|
the :keyword:`finally` clause.
|
||||||
|
@ -337,6 +337,20 @@ statement, the :keyword:`finally` clause is also executed 'on the way out.' A
|
||||||
reason is a problem with the current implementation --- this restriction may be
|
reason is a problem with the current implementation --- this restriction may be
|
||||||
lifted in the future).
|
lifted in the future).
|
||||||
|
|
||||||
|
The return value of a function is determined by the last :keyword:`return`
|
||||||
|
statement executed. Since the :keyword:`finally` clause always executes, a
|
||||||
|
:keyword:`return` statement executed in the :keyword:`finally` clause will
|
||||||
|
always be the last one executed::
|
||||||
|
|
||||||
|
>>> def foo():
|
||||||
|
... try:
|
||||||
|
... return 'try'
|
||||||
|
... finally:
|
||||||
|
... return 'finally'
|
||||||
|
...
|
||||||
|
>>> foo()
|
||||||
|
'finally'
|
||||||
|
|
||||||
Additional information on exceptions can be found in section :ref:`exceptions`,
|
Additional information on exceptions can be found in section :ref:`exceptions`,
|
||||||
and information on using the :keyword:`raise` statement to generate exceptions
|
and information on using the :keyword:`raise` statement to generate exceptions
|
||||||
may be found in section :ref:`raise`.
|
may be found in section :ref:`raise`.
|
||||||
|
|
|
@ -323,8 +323,6 @@ Sequences
|
||||||
object: mutable sequence
|
object: mutable sequence
|
||||||
object: mutable
|
object: mutable
|
||||||
pair: assignment; statement
|
pair: assignment; statement
|
||||||
single: delete
|
|
||||||
statement: del
|
|
||||||
single: subscription
|
single: subscription
|
||||||
single: slicing
|
single: slicing
|
||||||
|
|
||||||
|
|
|
@ -775,11 +775,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
elif self._scheduled:
|
elif self._scheduled:
|
||||||
# Compute the desired timeout.
|
# Compute the desired timeout.
|
||||||
when = self._scheduled[0]._when
|
when = self._scheduled[0]._when
|
||||||
deadline = max(0, when - self.time())
|
timeout = max(0, when - self.time())
|
||||||
if timeout is None:
|
|
||||||
timeout = deadline
|
|
||||||
else:
|
|
||||||
timeout = min(timeout, deadline)
|
|
||||||
|
|
||||||
# TODO: Instrumentation only in debug mode?
|
# TODO: Instrumentation only in debug mode?
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
|
|
|
@ -87,10 +87,17 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _write_to_self(self):
|
def _write_to_self(self):
|
||||||
try:
|
# This may be called from a different thread, possibly after
|
||||||
self._csock.send(b'x')
|
# _close_self_pipe() has been called or even while it is
|
||||||
except (BlockingIOError, InterruptedError):
|
# running. Guard for self._csock being None or closed. When
|
||||||
pass
|
# a socket is closed, send() raises OSError (with errno set to
|
||||||
|
# EBADF, but let's not rely on the exact error code).
|
||||||
|
csock = self._csock
|
||||||
|
if csock is not None:
|
||||||
|
try:
|
||||||
|
csock.send(b'x')
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
def _start_serving(self, protocol_factory, sock,
|
def _start_serving(self, protocol_factory, sock,
|
||||||
sslcontext=None, server=None):
|
sslcontext=None, server=None):
|
||||||
|
|
|
@ -419,12 +419,17 @@ class StreamReader:
|
||||||
return b''
|
return b''
|
||||||
|
|
||||||
if n < 0:
|
if n < 0:
|
||||||
while not self._eof:
|
# This used to just loop creating a new waiter hoping to
|
||||||
self._waiter = self._create_waiter('read')
|
# collect everything in self._buffer, but that would
|
||||||
try:
|
# deadlock if the subprocess sends more than self.limit
|
||||||
yield from self._waiter
|
# bytes. So just call self.read(self._limit) until EOF.
|
||||||
finally:
|
blocks = []
|
||||||
self._waiter = None
|
while True:
|
||||||
|
block = yield from self.read(self._limit)
|
||||||
|
if not block:
|
||||||
|
break
|
||||||
|
blocks.append(block)
|
||||||
|
return b''.join(blocks)
|
||||||
else:
|
else:
|
||||||
if not self._buffer and not self._eof:
|
if not self._buffer and not self._eof:
|
||||||
self._waiter = self._create_waiter('read')
|
self._waiter = self._create_waiter('read')
|
||||||
|
|
|
@ -96,6 +96,9 @@ class EmptyStruct(Structure):
|
||||||
class aUnion(Union):
|
class aUnion(Union):
|
||||||
_fields_ = [("a", c_int)]
|
_fields_ = [("a", c_int)]
|
||||||
|
|
||||||
|
class StructWithArrays(Structure):
|
||||||
|
_fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)]
|
||||||
|
|
||||||
class Incomplete(Structure):
|
class Incomplete(Structure):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -145,10 +148,10 @@ native_types = [
|
||||||
|
|
||||||
## arrays and pointers
|
## arrays and pointers
|
||||||
|
|
||||||
(c_double * 4, "(4)<d", (4,), c_double),
|
(c_double * 4, "<d", (4,), c_double),
|
||||||
(c_float * 4 * 3 * 2, "(2,3,4)<f", (2,3,4), c_float),
|
(c_float * 4 * 3 * 2, "<f", (2,3,4), c_float),
|
||||||
(POINTER(c_short) * 2, "(2)&<h", (2,), POINTER(c_short)),
|
(POINTER(c_short) * 2, "&<h", (2,), POINTER(c_short)),
|
||||||
(POINTER(c_short) * 2 * 3, "(3,2)&<h", (3,2,), POINTER(c_short)),
|
(POINTER(c_short) * 2 * 3, "&<h", (3,2,), POINTER(c_short)),
|
||||||
(POINTER(c_short * 2), "&(2)<h", (), POINTER(c_short)),
|
(POINTER(c_short * 2), "&(2)<h", (), POINTER(c_short)),
|
||||||
|
|
||||||
## structures and unions
|
## structures and unions
|
||||||
|
@ -160,6 +163,9 @@ native_types = [
|
||||||
(EmptyStruct, "T{}", (), EmptyStruct),
|
(EmptyStruct, "T{}", (), EmptyStruct),
|
||||||
# the pep does't support unions
|
# the pep does't support unions
|
||||||
(aUnion, "B", (), aUnion),
|
(aUnion, "B", (), aUnion),
|
||||||
|
# structure with sub-arrays
|
||||||
|
(StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (), StructWithArrays),
|
||||||
|
(StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,), StructWithArrays),
|
||||||
|
|
||||||
## pointer to incomplete structure
|
## pointer to incomplete structure
|
||||||
(Incomplete, "B", (), Incomplete),
|
(Incomplete, "B", (), Incomplete),
|
||||||
|
|
|
@ -207,4 +207,4 @@ def fixup_build_ext(cmd):
|
||||||
cmd.library_dirs = []
|
cmd.library_dirs = []
|
||||||
else:
|
else:
|
||||||
name, equals, value = runshared.partition('=')
|
name, equals, value = runshared.partition('=')
|
||||||
cmd.library_dirs = value.split(os.pathsep)
|
cmd.library_dirs = [d for d in value.split(os.pathsep) if d]
|
||||||
|
|
|
@ -51,8 +51,9 @@ class Generator:
|
||||||
by RFC 2822.
|
by RFC 2822.
|
||||||
|
|
||||||
The policy keyword specifies a policy object that controls a number of
|
The policy keyword specifies a policy object that controls a number of
|
||||||
aspects of the generator's operation. The default policy maintains
|
aspects of the generator's operation. If no policy is specified,
|
||||||
backward compatibility.
|
the policy associated with the Message object passed to the
|
||||||
|
flatten method is used.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._fp = outfp
|
self._fp = outfp
|
||||||
|
@ -76,7 +77,9 @@ class Generator:
|
||||||
Note that for subobjects, no From_ line is printed.
|
Note that for subobjects, no From_ line is printed.
|
||||||
|
|
||||||
linesep specifies the characters used to indicate a new line in
|
linesep specifies the characters used to indicate a new line in
|
||||||
the output. The default value is determined by the policy.
|
the output. The default value is determined by the policy specified
|
||||||
|
when the Generator instance was created or, if none was specified,
|
||||||
|
from the policy associated with the msg.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# We use the _XXX constants for operating on data that comes directly
|
# We use the _XXX constants for operating on data that comes directly
|
||||||
|
|
|
@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"]
|
||||||
|
|
||||||
_SETUPTOOLS_VERSION = "2.1"
|
_SETUPTOOLS_VERSION = "2.1"
|
||||||
|
|
||||||
_PIP_VERSION = "1.5.4"
|
_PIP_VERSION = "1.5.6"
|
||||||
|
|
||||||
# pip currently requires ssl support, so we try to provide a nicer
|
# pip currently requires ssl support, so we try to provide a nicer
|
||||||
# error message when that is missing (http://bugs.python.org/issue19744)
|
# error message when that is missing (http://bugs.python.org/issue19744)
|
||||||
|
|
Binary file not shown.
|
@ -320,7 +320,10 @@ class FileInput:
|
||||||
self._backupfilename = 0
|
self._backupfilename = 0
|
||||||
if self._filename == '-':
|
if self._filename == '-':
|
||||||
self._filename = '<stdin>'
|
self._filename = '<stdin>'
|
||||||
self._file = sys.stdin
|
if 'b' in self._mode:
|
||||||
|
self._file = sys.stdin.buffer
|
||||||
|
else:
|
||||||
|
self._file = sys.stdin
|
||||||
self._isstdin = True
|
self._isstdin = True
|
||||||
else:
|
else:
|
||||||
if self._inplace:
|
if self._inplace:
|
||||||
|
|
|
@ -79,6 +79,8 @@ class HelpDialog(object):
|
||||||
self.parent = None
|
self.parent = None
|
||||||
|
|
||||||
helpDialog = HelpDialog() # singleton instance
|
helpDialog = HelpDialog() # singleton instance
|
||||||
|
def _Help_dialog(parent): # wrapper for htest
|
||||||
|
helpDialog.show_dialog(parent)
|
||||||
|
|
||||||
|
|
||||||
class EditorWindow(object):
|
class EditorWindow(object):
|
||||||
|
@ -1064,7 +1066,7 @@ class EditorWindow(object):
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
mod = importlib.import_module('.' + name, package=__package__)
|
mod = importlib.import_module('.' + name, package=__package__)
|
||||||
except ImportError:
|
except (ImportError, TypeError):
|
||||||
mod = importlib.import_module(name)
|
mod = importlib.import_module(name)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("\nFailed to import extension: ", name)
|
print("\nFailed to import extension: ", name)
|
||||||
|
@ -1700,19 +1702,21 @@ def fixwordbreaks(root):
|
||||||
tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]')
|
tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]')
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def _Editor_window(parent):
|
||||||
root = Tk()
|
root = parent
|
||||||
fixwordbreaks(root)
|
fixwordbreaks(root)
|
||||||
root.withdraw()
|
root.withdraw()
|
||||||
if sys.argv[1:]:
|
if sys.argv[1:]:
|
||||||
filename = sys.argv[1]
|
filename = sys.argv[1]
|
||||||
else:
|
else:
|
||||||
filename = None
|
filename = None
|
||||||
|
macosxSupport.setupApp(root, None)
|
||||||
edit = EditorWindow(root=root, filename=filename)
|
edit = EditorWindow(root=root, filename=filename)
|
||||||
edit.set_close_hook(root.quit)
|
edit.set_close_hook(root.quit)
|
||||||
edit.text.bind("<<close-all-windows>>", edit.close_event)
|
edit.text.bind("<<close-all-windows>>", edit.close_event)
|
||||||
root.mainloop()
|
|
||||||
root.destroy()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test()
|
from idlelib.idle_test.htest import run
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
run(_Help_dialog)
|
||||||
|
run(_Editor_window)
|
||||||
|
|
|
@ -12,7 +12,7 @@ class AboutDialog(Toplevel):
|
||||||
"""Modal about dialog for idle
|
"""Modal about dialog for idle
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,parent,title):
|
def __init__(self, parent, title):
|
||||||
Toplevel.__init__(self, parent)
|
Toplevel.__init__(self, parent)
|
||||||
self.configure(borderwidth=5)
|
self.configure(borderwidth=5)
|
||||||
self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
|
self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
|
||||||
|
@ -136,10 +136,5 @@ class AboutDialog(Toplevel):
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# test the dialog
|
from idlelib.idle_test.htest import run
|
||||||
root = Tk()
|
run(AboutDialog)
|
||||||
def run():
|
|
||||||
from idlelib import aboutDialog
|
|
||||||
aboutDialog.AboutDialog(root, 'About')
|
|
||||||
Button(root, text='Dialog', command=run).pack()
|
|
||||||
root.mainloop()
|
|
||||||
|
|
|
@ -8,10 +8,11 @@ from tkinter import *
|
||||||
import tkinter.messagebox as tkMessageBox
|
import tkinter.messagebox as tkMessageBox
|
||||||
|
|
||||||
class GetCfgSectionNameDialog(Toplevel):
|
class GetCfgSectionNameDialog(Toplevel):
|
||||||
def __init__(self, parent, title, message, used_names):
|
def __init__(self, parent, title, message, used_names, _htest=False):
|
||||||
"""
|
"""
|
||||||
message - string, informational message to display
|
message - string, informational message to display
|
||||||
used_names - string collection, names already in use for validity check
|
used_names - string collection, names already in use for validity check
|
||||||
|
_htest - bool, change box location when running htest
|
||||||
"""
|
"""
|
||||||
Toplevel.__init__(self, parent)
|
Toplevel.__init__(self, parent)
|
||||||
self.configure(borderwidth=5)
|
self.configure(borderwidth=5)
|
||||||
|
@ -30,11 +31,12 @@ class GetCfgSectionNameDialog(Toplevel):
|
||||||
self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
|
self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
|
||||||
self.geometry(
|
self.geometry(
|
||||||
"+%d+%d" % (
|
"+%d+%d" % (
|
||||||
parent.winfo_rootx() +
|
parent.winfo_rootx() +
|
||||||
(parent.winfo_width()/2 - self.winfo_reqwidth()/2),
|
(parent.winfo_width()/2 - self.winfo_reqwidth()/2),
|
||||||
parent.winfo_rooty() +
|
parent.winfo_rooty() +
|
||||||
(parent.winfo_height()/2 - self.winfo_reqheight()/2)
|
((parent.winfo_height()/2 - self.winfo_reqheight()/2)
|
||||||
) ) #centre dialog over parent
|
if not _htest else 100)
|
||||||
|
) ) #centre dialog over parent (or below htest box)
|
||||||
self.deiconify() #geometry set, unhide
|
self.deiconify() #geometry set, unhide
|
||||||
self.wait_window()
|
self.wait_window()
|
||||||
|
|
||||||
|
@ -92,15 +94,5 @@ if __name__ == '__main__':
|
||||||
import unittest
|
import unittest
|
||||||
unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False)
|
unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False)
|
||||||
|
|
||||||
# also human test the dialog
|
from idlelib.idle_test.htest import run
|
||||||
root = Tk()
|
run(GetCfgSectionNameDialog)
|
||||||
def run():
|
|
||||||
dlg=GetCfgSectionNameDialog(root,'Get Name',
|
|
||||||
"After the text entered with [Ok] is stripped, <nothing>, "
|
|
||||||
"'abc', or more that 30 chars are errors. "
|
|
||||||
"Close with a valid entry (printed), [Cancel], or [X]",
|
|
||||||
{'abc'})
|
|
||||||
print(dlg.result)
|
|
||||||
Message(root, text='').pack() # will be needed for oher dialog tests
|
|
||||||
Button(root, text='Click to begin dialog test', command=run).pack()
|
|
||||||
root.mainloop()
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
'''Run human tests of Idle's window, dialog, and popup widgets.
|
||||||
|
|
||||||
|
run(test): run *test*, a callable that causes a widget to be displayed.
|
||||||
|
runall(): run all tests defined in this file.
|
||||||
|
|
||||||
|
Let X be a global name bound to a widget callable. End the module with
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
<unittest, if there is one>
|
||||||
|
from idlelib.idle_test.htest import run
|
||||||
|
run(X)
|
||||||
|
|
||||||
|
The X object must have a .__name__ attribute and a 'parent' parameter.
|
||||||
|
X will often be a widget class, but a callable instance with .__name__
|
||||||
|
or a wrapper function also work. The name of wrapper functions, like
|
||||||
|
'_Editor_Window', should start with '_'.
|
||||||
|
|
||||||
|
This file must contain a matching instance of the folling template,
|
||||||
|
with X.__name__ prepended, as in '_Editor_window_spec ...'.
|
||||||
|
|
||||||
|
_spec = {
|
||||||
|
'file': '',
|
||||||
|
'kwds': {'title': ''},
|
||||||
|
'msg': ""
|
||||||
|
}
|
||||||
|
|
||||||
|
file (no .py): used in runall() to import the file and get X.
|
||||||
|
kwds: passed to X (**kwds), after 'parent' is added, to initialize X.
|
||||||
|
title: an example; used for some widgets, delete if not.
|
||||||
|
msg: displayed in a master window. Hints as to how the user might
|
||||||
|
test the widget. Close the window to skip or end the test.
|
||||||
|
'''
|
||||||
|
from importlib import import_module
|
||||||
|
import tkinter as tk
|
||||||
|
|
||||||
|
|
||||||
|
_Editor_window_spec = {
|
||||||
|
'file': 'EditorWindow',
|
||||||
|
'kwds': {},
|
||||||
|
'msg': "Test editor functions of interest"
|
||||||
|
}
|
||||||
|
|
||||||
|
_Help_dialog_spec = {
|
||||||
|
'file': 'EditorWindow',
|
||||||
|
'kwds': {},
|
||||||
|
'msg': "If the help text displays, this works"
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDialog_spec = {
|
||||||
|
'file': 'aboutDialog',
|
||||||
|
'kwds': {'title': 'About test'},
|
||||||
|
'msg': "Try each button"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GetCfgSectionNameDialog_spec = {
|
||||||
|
'file': 'configSectionNameDialog',
|
||||||
|
'kwds': {'title':'Get Name',
|
||||||
|
'message':'Enter something',
|
||||||
|
'used_names': {'abc'},
|
||||||
|
'_htest': True},
|
||||||
|
'msg': "After the text entered with [Ok] is stripped, <nothing>, "
|
||||||
|
"'abc', or more that 30 chars are errors.\n"
|
||||||
|
"Close 'Get Name' with a valid entry (printed to Shell), [Cancel], or [X]",
|
||||||
|
}
|
||||||
|
|
||||||
|
def run(test):
|
||||||
|
"Display a widget with callable *test* using a _spec dict"
|
||||||
|
root = tk.Tk()
|
||||||
|
test_spec = globals()[test.__name__ + '_spec']
|
||||||
|
test_kwds = test_spec['kwds']
|
||||||
|
test_kwds['parent'] = root
|
||||||
|
|
||||||
|
def run_test():
|
||||||
|
widget = test(**test_kwds)
|
||||||
|
try:
|
||||||
|
print(widget.result)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
tk.Label(root, text=test_spec['msg'], justify='left').pack()
|
||||||
|
tk.Button(root, text='Test ' + test.__name__, command=run_test).pack()
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
|
def runall():
|
||||||
|
"Run all tests. Quick and dirty version."
|
||||||
|
for k, d in globals().items():
|
||||||
|
if k.endswith('_spec'):
|
||||||
|
mod = import_module('idlelib.' + d['file'])
|
||||||
|
test = getattr(mod, k[:-5])
|
||||||
|
run(test)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
runall()
|
|
@ -1220,6 +1220,29 @@ class _SpecMethods:
|
||||||
return self._load_unlocked()
|
return self._load_unlocked()
|
||||||
|
|
||||||
|
|
||||||
|
def _fix_up_module(ns, name, pathname, cpathname=None):
|
||||||
|
# This function is used by PyImport_ExecCodeModuleObject().
|
||||||
|
loader = ns.get('__loader__')
|
||||||
|
spec = ns.get('__spec__')
|
||||||
|
if not loader:
|
||||||
|
if spec:
|
||||||
|
loader = spec.loader
|
||||||
|
elif pathname == cpathname:
|
||||||
|
loader = SourcelessFileLoader(name, pathname)
|
||||||
|
else:
|
||||||
|
loader = SourceFileLoader(name, pathname)
|
||||||
|
if not spec:
|
||||||
|
spec = spec_from_file_location(name, pathname, loader=loader)
|
||||||
|
try:
|
||||||
|
ns['__spec__'] = spec
|
||||||
|
ns['__loader__'] = loader
|
||||||
|
ns['__file__'] = pathname
|
||||||
|
ns['__cached__'] = cpathname
|
||||||
|
except Exception:
|
||||||
|
# Not important enough to report.
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Loaders #####################################################################
|
# Loaders #####################################################################
|
||||||
|
|
||||||
class BuiltinImporter:
|
class BuiltinImporter:
|
||||||
|
|
|
@ -1404,6 +1404,9 @@ class _PlainTextDoc(TextDoc):
|
||||||
def pager(text):
|
def pager(text):
|
||||||
"""The first time this is called, determine what kind of pager to use."""
|
"""The first time this is called, determine what kind of pager to use."""
|
||||||
global pager
|
global pager
|
||||||
|
# Escape non-encodable characters to avoid encoding errors later
|
||||||
|
encoding = sys.getfilesystemencoding()
|
||||||
|
text = text.encode(encoding, 'backslashreplace').decode(encoding)
|
||||||
pager = getpager()
|
pager = getpager()
|
||||||
pager(text)
|
pager(text)
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,9 @@ class Random(_random.Random):
|
||||||
|
|
||||||
if a is None:
|
if a is None:
|
||||||
try:
|
try:
|
||||||
a = int.from_bytes(_urandom(32), 'big')
|
# Seed with enough bytes to span the 19937 bit
|
||||||
|
# state space for the Mersenne Twister
|
||||||
|
a = int.from_bytes(_urandom(2500), 'big')
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
import time
|
import time
|
||||||
a = int(time.time() * 256) # use fractional seconds
|
a = int(time.time() * 256) # use fractional seconds
|
||||||
|
|
|
@ -78,7 +78,7 @@ def assert_python_failure(*args, **env_vars):
|
||||||
"""
|
"""
|
||||||
return _assert_python(False, *args, **env_vars)
|
return _assert_python(False, *args, **env_vars)
|
||||||
|
|
||||||
def spawn_python(*args, **kw):
|
def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
|
||||||
"""Run a Python subprocess with the given arguments.
|
"""Run a Python subprocess with the given arguments.
|
||||||
|
|
||||||
kw is extra keyword args to pass to subprocess.Popen. Returns a Popen
|
kw is extra keyword args to pass to subprocess.Popen. Returns a Popen
|
||||||
|
@ -86,8 +86,16 @@ def spawn_python(*args, **kw):
|
||||||
"""
|
"""
|
||||||
cmd_line = [sys.executable, '-E']
|
cmd_line = [sys.executable, '-E']
|
||||||
cmd_line.extend(args)
|
cmd_line.extend(args)
|
||||||
|
# Under Fedora (?), GNU readline can output junk on stderr when initialized,
|
||||||
|
# depending on the TERM setting. Setting TERM=vt100 is supposed to disable
|
||||||
|
# that. References:
|
||||||
|
# - http://reinout.vanrees.org/weblog/2009/08/14/readline-invisible-character-hack.html
|
||||||
|
# - http://stackoverflow.com/questions/15760712/python-readline-module-prints-escape-character-during-import
|
||||||
|
# - http://lists.gnu.org/archive/html/bug-readline/2007-08/msg00004.html
|
||||||
|
env = kw.setdefault('env', dict(os.environ))
|
||||||
|
env['TERM'] = 'vt100'
|
||||||
return subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
|
return subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
stdout=stdout, stderr=stderr,
|
||||||
**kw)
|
**kw)
|
||||||
|
|
||||||
def kill_python(p):
|
def kill_python(p):
|
||||||
|
|
|
@ -121,8 +121,9 @@ class BaseSelectorEventLoopTests(unittest.TestCase):
|
||||||
self.assertIsNone(self.loop._write_to_self())
|
self.assertIsNone(self.loop._write_to_self())
|
||||||
|
|
||||||
def test_write_to_self_exception(self):
|
def test_write_to_self_exception(self):
|
||||||
self.loop._csock.send.side_effect = OSError()
|
# _write_to_self() swallows OSError
|
||||||
self.assertRaises(OSError, self.loop._write_to_self)
|
self.loop._csock.send.side_effect = RuntimeError()
|
||||||
|
self.assertRaises(RuntimeError, self.loop._write_to_self)
|
||||||
|
|
||||||
def test_sock_recv(self):
|
def test_sock_recv(self):
|
||||||
sock = mock.Mock()
|
sock = mock.Mock()
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
"""Tests for streams.py."""
|
"""Tests for streams.py."""
|
||||||
|
|
||||||
import gc
|
import gc
|
||||||
|
import os
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
try:
|
try:
|
||||||
|
@ -583,6 +585,43 @@ class StreamReaderTests(unittest.TestCase):
|
||||||
server.stop()
|
server.stop()
|
||||||
self.assertEqual(msg, b"hello world!\n")
|
self.assertEqual(msg, b"hello world!\n")
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == 'win32', "Don't have pipes")
|
||||||
|
def test_read_all_from_pipe_reader(self):
|
||||||
|
# See Tulip issue 168. This test is derived from the example
|
||||||
|
# subprocess_attach_read_pipe.py, but we configure the
|
||||||
|
# StreamReader's limit so that twice it is less than the size
|
||||||
|
# of the data writter. Also we must explicitly attach a child
|
||||||
|
# watcher to the event loop.
|
||||||
|
|
||||||
|
code = """\
|
||||||
|
import os, sys
|
||||||
|
fd = int(sys.argv[1])
|
||||||
|
os.write(fd, b'data')
|
||||||
|
os.close(fd)
|
||||||
|
"""
|
||||||
|
rfd, wfd = os.pipe()
|
||||||
|
args = [sys.executable, '-c', code, str(wfd)]
|
||||||
|
|
||||||
|
pipe = open(rfd, 'rb', 0)
|
||||||
|
reader = asyncio.StreamReader(loop=self.loop, limit=1)
|
||||||
|
protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop)
|
||||||
|
transport, _ = self.loop.run_until_complete(
|
||||||
|
self.loop.connect_read_pipe(lambda: protocol, pipe))
|
||||||
|
|
||||||
|
watcher = asyncio.SafeChildWatcher()
|
||||||
|
watcher.attach_loop(self.loop)
|
||||||
|
try:
|
||||||
|
asyncio.set_child_watcher(watcher)
|
||||||
|
proc = self.loop.run_until_complete(
|
||||||
|
asyncio.create_subprocess_exec(*args, pass_fds={wfd}, loop=self.loop))
|
||||||
|
self.loop.run_until_complete(proc.wait())
|
||||||
|
finally:
|
||||||
|
asyncio.set_child_watcher(None)
|
||||||
|
|
||||||
|
os.close(wfd)
|
||||||
|
data = self.loop.run_until_complete(reader.read(-1))
|
||||||
|
self.assertEqual(data, b'data')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# tests command line execution of scripts
|
# tests command line execution of scripts
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import importlib
|
import importlib
|
||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
import zipimport
|
import zipimport
|
||||||
|
@ -8,6 +9,7 @@ import sys
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import py_compile
|
import py_compile
|
||||||
|
import subprocess
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
from test import support
|
from test import support
|
||||||
|
@ -173,6 +175,53 @@ class CmdLineTest(unittest.TestCase):
|
||||||
expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
|
expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
|
||||||
self.assertIn(expected, out)
|
self.assertIn(expected, out)
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def interactive_python(self, separate_stderr=False):
|
||||||
|
if separate_stderr:
|
||||||
|
p = spawn_python('-i', bufsize=1, stderr=subprocess.PIPE)
|
||||||
|
stderr = p.stderr
|
||||||
|
else:
|
||||||
|
p = spawn_python('-i', bufsize=1, stderr=subprocess.STDOUT)
|
||||||
|
stderr = p.stdout
|
||||||
|
try:
|
||||||
|
# Drain stderr until prompt
|
||||||
|
while True:
|
||||||
|
data = stderr.read(4)
|
||||||
|
if data == b">>> ":
|
||||||
|
break
|
||||||
|
stderr.readline()
|
||||||
|
yield p
|
||||||
|
finally:
|
||||||
|
kill_python(p)
|
||||||
|
stderr.close()
|
||||||
|
|
||||||
|
def check_repl_stdout_flush(self, separate_stderr=False):
|
||||||
|
with self.interactive_python(separate_stderr) as p:
|
||||||
|
p.stdin.write(b"print('foo')\n")
|
||||||
|
p.stdin.flush()
|
||||||
|
self.assertEqual(b'foo', p.stdout.readline().strip())
|
||||||
|
|
||||||
|
def check_repl_stderr_flush(self, separate_stderr=False):
|
||||||
|
with self.interactive_python(separate_stderr) as p:
|
||||||
|
p.stdin.write(b"1/0\n")
|
||||||
|
p.stdin.flush()
|
||||||
|
stderr = p.stderr if separate_stderr else p.stdout
|
||||||
|
self.assertIn(b'Traceback ', stderr.readline())
|
||||||
|
self.assertIn(b'File "<stdin>"', stderr.readline())
|
||||||
|
self.assertIn(b'ZeroDivisionError', stderr.readline())
|
||||||
|
|
||||||
|
def test_repl_stdout_flush(self):
|
||||||
|
self.check_repl_stdout_flush()
|
||||||
|
|
||||||
|
def test_repl_stdout_flush_separate_stderr(self):
|
||||||
|
self.check_repl_stdout_flush(True)
|
||||||
|
|
||||||
|
def test_repl_stderr_flush(self):
|
||||||
|
self.check_repl_stderr_flush()
|
||||||
|
|
||||||
|
def test_repl_stderr_flush_separate_stderr(self):
|
||||||
|
self.check_repl_stderr_flush(True)
|
||||||
|
|
||||||
def test_basic_script(self):
|
def test_basic_script(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, 'script')
|
script_name = _make_test_script(script_dir, 'script')
|
||||||
|
|
|
@ -51,7 +51,7 @@ class TestInteractiveConsole(unittest.TestCase):
|
||||||
self.infunc.side_effect = ["undefined", EOFError('Finished')]
|
self.infunc.side_effect = ["undefined", EOFError('Finished')]
|
||||||
self.console.interact()
|
self.console.interact()
|
||||||
for call in self.stderr.method_calls:
|
for call in self.stderr.method_calls:
|
||||||
if 'NameError:' in ''.join(call[1]):
|
if 'NameError' in ''.join(call[1]):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise AssertionError("No syntax error from console")
|
raise AssertionError("No syntax error from console")
|
||||||
|
|
|
@ -591,6 +591,31 @@ sys.exit(exitcode)
|
||||||
def test_register_chain(self):
|
def test_register_chain(self):
|
||||||
self.check_register(chain=True)
|
self.check_register(chain=True)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def check_stderr_none(self):
|
||||||
|
stderr = sys.stderr
|
||||||
|
try:
|
||||||
|
sys.stderr = None
|
||||||
|
with self.assertRaises(RuntimeError) as cm:
|
||||||
|
yield
|
||||||
|
self.assertEqual(str(cm.exception), "sys.stderr is None")
|
||||||
|
finally:
|
||||||
|
sys.stderr = stderr
|
||||||
|
|
||||||
|
def test_stderr_None(self):
|
||||||
|
# Issue #21497: provide an helpful error if sys.stderr is None,
|
||||||
|
# instead of just an attribute error: "None has no attribute fileno".
|
||||||
|
with self.check_stderr_none():
|
||||||
|
faulthandler.enable()
|
||||||
|
with self.check_stderr_none():
|
||||||
|
faulthandler.dump_traceback()
|
||||||
|
if hasattr(faulthandler, 'dump_traceback_later'):
|
||||||
|
with self.check_stderr_none():
|
||||||
|
faulthandler.dump_traceback_later(1e-3)
|
||||||
|
if hasattr(faulthandler, "register"):
|
||||||
|
with self.check_stderr_none():
|
||||||
|
faulthandler.register(signal.SIGUSR1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -19,11 +19,12 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
gzip = None
|
gzip = None
|
||||||
|
|
||||||
from io import StringIO
|
from io import BytesIO, StringIO
|
||||||
from fileinput import FileInput, hook_encoded
|
from fileinput import FileInput, hook_encoded
|
||||||
|
|
||||||
from test.support import verbose, TESTFN, run_unittest, check_warnings
|
from test.support import verbose, TESTFN, run_unittest, check_warnings
|
||||||
from test.support import unlink as safe_unlink
|
from test.support import unlink as safe_unlink
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
|
||||||
# The fileinput module has 2 interfaces: the FileInput class which does
|
# The fileinput module has 2 interfaces: the FileInput class which does
|
||||||
|
@ -232,6 +233,13 @@ class FileInputTests(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
remove_tempfiles(t1)
|
remove_tempfiles(t1)
|
||||||
|
|
||||||
|
def test_stdin_binary_mode(self):
|
||||||
|
with mock.patch('sys.stdin') as m_stdin:
|
||||||
|
m_stdin.buffer = BytesIO(b'spam, bacon, sausage, and spam')
|
||||||
|
fi = FileInput(files=['-'], mode='rb')
|
||||||
|
lines = list(fi)
|
||||||
|
self.assertEqual(lines, [b'spam, bacon, sausage, and spam'])
|
||||||
|
|
||||||
def test_file_opening_hook(self):
|
def test_file_opening_hook(self):
|
||||||
try:
|
try:
|
||||||
# cannot use openhook and inplace mode
|
# cannot use openhook and inplace mode
|
||||||
|
|
|
@ -580,6 +580,38 @@ class GCTests(unittest.TestCase):
|
||||||
# would be damaged, with an empty __dict__.
|
# would be damaged, with an empty __dict__.
|
||||||
self.assertEqual(x, None)
|
self.assertEqual(x, None)
|
||||||
|
|
||||||
|
def test_bug21435(self):
|
||||||
|
# This is a poor test - its only virtue is that it happened to
|
||||||
|
# segfault on Tim's Windows box before the patch for 21435 was
|
||||||
|
# applied. That's a nasty bug relying on specific pieces of cyclic
|
||||||
|
# trash appearing in exactly the right order in finalize_garbage()'s
|
||||||
|
# input list.
|
||||||
|
# But there's no reliable way to force that order from Python code,
|
||||||
|
# so over time chances are good this test won't really be testing much
|
||||||
|
# of anything anymore. Still, if it blows up, there's _some_
|
||||||
|
# problem ;-)
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
|
class A:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class B:
|
||||||
|
def __init__(self, x):
|
||||||
|
self.x = x
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.attr = None
|
||||||
|
|
||||||
|
def do_work():
|
||||||
|
a = A()
|
||||||
|
b = B(A())
|
||||||
|
|
||||||
|
a.attr = b
|
||||||
|
b.attr = a
|
||||||
|
|
||||||
|
do_work()
|
||||||
|
gc.collect() # this blows up (bad C pointer) when it fails
|
||||||
|
|
||||||
@cpython_only
|
@cpython_only
|
||||||
def test_garbage_at_shutdown(self):
|
def test_garbage_at_shutdown(self):
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
|
@ -241,13 +241,13 @@ class ReloadTests:
|
||||||
'__file__': path,
|
'__file__': path,
|
||||||
'__cached__': cached,
|
'__cached__': cached,
|
||||||
'__doc__': None,
|
'__doc__': None,
|
||||||
'__builtins__': __builtins__,
|
|
||||||
}
|
}
|
||||||
support.create_empty_file(path)
|
support.create_empty_file(path)
|
||||||
module = self.init.import_module(name)
|
module = self.init.import_module(name)
|
||||||
ns = vars(module)
|
ns = vars(module).copy()
|
||||||
loader = ns.pop('__loader__')
|
loader = ns.pop('__loader__')
|
||||||
spec = ns.pop('__spec__')
|
spec = ns.pop('__spec__')
|
||||||
|
ns.pop('__builtins__', None) # An implementation detail.
|
||||||
self.assertEqual(spec.name, name)
|
self.assertEqual(spec.name, name)
|
||||||
self.assertEqual(spec.loader, loader)
|
self.assertEqual(spec.loader, loader)
|
||||||
self.assertEqual(loader.path, path)
|
self.assertEqual(loader.path, path)
|
||||||
|
@ -263,14 +263,14 @@ class ReloadTests:
|
||||||
'__cached__': cached,
|
'__cached__': cached,
|
||||||
'__path__': [os.path.dirname(init_path)],
|
'__path__': [os.path.dirname(init_path)],
|
||||||
'__doc__': None,
|
'__doc__': None,
|
||||||
'__builtins__': __builtins__,
|
|
||||||
}
|
}
|
||||||
os.mkdir(name)
|
os.mkdir(name)
|
||||||
os.rename(path, init_path)
|
os.rename(path, init_path)
|
||||||
reloaded = self.init.reload(module)
|
reloaded = self.init.reload(module)
|
||||||
ns = vars(reloaded)
|
ns = vars(reloaded).copy()
|
||||||
loader = ns.pop('__loader__')
|
loader = ns.pop('__loader__')
|
||||||
spec = ns.pop('__spec__')
|
spec = ns.pop('__spec__')
|
||||||
|
ns.pop('__builtins__', None) # An implementation detail.
|
||||||
self.assertEqual(spec.name, name)
|
self.assertEqual(spec.name, name)
|
||||||
self.assertEqual(spec.loader, loader)
|
self.assertEqual(spec.loader, loader)
|
||||||
self.assertIs(reloaded, module)
|
self.assertIs(reloaded, module)
|
||||||
|
@ -295,10 +295,11 @@ class ReloadTests:
|
||||||
with open(bad_path, 'w') as init_file:
|
with open(bad_path, 'w') as init_file:
|
||||||
init_file.write('eggs = None')
|
init_file.write('eggs = None')
|
||||||
module = self.init.import_module(name)
|
module = self.init.import_module(name)
|
||||||
ns = vars(module)
|
ns = vars(module).copy()
|
||||||
loader = ns.pop('__loader__')
|
loader = ns.pop('__loader__')
|
||||||
path = ns.pop('__path__')
|
path = ns.pop('__path__')
|
||||||
spec = ns.pop('__spec__')
|
spec = ns.pop('__spec__')
|
||||||
|
ns.pop('__builtins__', None) # An implementation detail.
|
||||||
self.assertEqual(spec.name, name)
|
self.assertEqual(spec.name, name)
|
||||||
self.assertIs(spec.loader, None)
|
self.assertIs(spec.loader, None)
|
||||||
self.assertIsNot(loader, None)
|
self.assertIsNot(loader, None)
|
||||||
|
@ -319,14 +320,14 @@ class ReloadTests:
|
||||||
'__cached__': cached,
|
'__cached__': cached,
|
||||||
'__path__': [os.path.dirname(init_path)],
|
'__path__': [os.path.dirname(init_path)],
|
||||||
'__doc__': None,
|
'__doc__': None,
|
||||||
'__builtins__': __builtins__,
|
|
||||||
'eggs': None,
|
'eggs': None,
|
||||||
}
|
}
|
||||||
os.rename(bad_path, init_path)
|
os.rename(bad_path, init_path)
|
||||||
reloaded = self.init.reload(module)
|
reloaded = self.init.reload(module)
|
||||||
ns = vars(reloaded)
|
ns = vars(reloaded).copy()
|
||||||
loader = ns.pop('__loader__')
|
loader = ns.pop('__loader__')
|
||||||
spec = ns.pop('__spec__')
|
spec = ns.pop('__spec__')
|
||||||
|
ns.pop('__builtins__', None) # An implementation detail.
|
||||||
self.assertEqual(spec.name, name)
|
self.assertEqual(spec.name, name)
|
||||||
self.assertEqual(spec.loader, loader)
|
self.assertEqual(spec.loader, loader)
|
||||||
self.assertIs(reloaded, module)
|
self.assertIs(reloaded, module)
|
||||||
|
|
|
@ -2615,6 +2615,38 @@ class TextIOWrapperTest(unittest.TestCase):
|
||||||
txt.write('5')
|
txt.write('5')
|
||||||
self.assertEqual(b''.join(raw._write_stack), b'123\n45')
|
self.assertEqual(b''.join(raw._write_stack), b'123\n45')
|
||||||
|
|
||||||
|
def test_bufio_write_through(self):
|
||||||
|
# Issue #21396: write_through=True doesn't force a flush()
|
||||||
|
# on the underlying binary buffered object.
|
||||||
|
flush_called, write_called = [], []
|
||||||
|
class BufferedWriter(self.BufferedWriter):
|
||||||
|
def flush(self, *args, **kwargs):
|
||||||
|
flush_called.append(True)
|
||||||
|
return super().flush(*args, **kwargs)
|
||||||
|
def write(self, *args, **kwargs):
|
||||||
|
write_called.append(True)
|
||||||
|
return super().write(*args, **kwargs)
|
||||||
|
|
||||||
|
rawio = self.BytesIO()
|
||||||
|
data = b"a"
|
||||||
|
bufio = BufferedWriter(rawio, len(data)*2)
|
||||||
|
textio = self.TextIOWrapper(bufio, encoding='ascii',
|
||||||
|
write_through=True)
|
||||||
|
# write to the buffered io but don't overflow the buffer
|
||||||
|
text = data.decode('ascii')
|
||||||
|
textio.write(text)
|
||||||
|
|
||||||
|
# buffer.flush is not called with write_through=True
|
||||||
|
self.assertFalse(flush_called)
|
||||||
|
# buffer.write *is* called with write_through=True
|
||||||
|
self.assertTrue(write_called)
|
||||||
|
self.assertEqual(rawio.getvalue(), b"") # no flush
|
||||||
|
|
||||||
|
write_called = [] # reset
|
||||||
|
textio.write(text * 10) # total content is larger than bufio buffer
|
||||||
|
self.assertTrue(write_called)
|
||||||
|
self.assertEqual(rawio.getvalue(), data * 11) # all flushed
|
||||||
|
|
||||||
def test_read_nonbytes(self):
|
def test_read_nonbytes(self):
|
||||||
# Issue #17106
|
# Issue #17106
|
||||||
# Crash when underlying read() returns non-bytes
|
# Crash when underlying read() returns non-bytes
|
||||||
|
|
|
@ -1235,6 +1235,13 @@ class LongTest(unittest.TestCase):
|
||||||
for n in map(int, integers):
|
for n in map(int, integers):
|
||||||
self.assertEqual(n, 0)
|
self.assertEqual(n, 0)
|
||||||
|
|
||||||
|
def test_shift_bool(self):
|
||||||
|
# Issue #21422: ensure that bool << int and bool >> int return int
|
||||||
|
for value in (True, False):
|
||||||
|
for shift in (0, 2):
|
||||||
|
self.assertEqual(type(value << shift), int)
|
||||||
|
self.assertEqual(type(value >> shift), int)
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(LongTest)
|
support.run_unittest(LongTest)
|
||||||
|
|
|
@ -1223,6 +1223,11 @@ class ReTests(unittest.TestCase):
|
||||||
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
|
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
|
||||||
(7, 9))
|
(7, 9))
|
||||||
|
|
||||||
|
def test_bug_20998(self):
|
||||||
|
# Issue #20998: Fullmatch of repeated single character pattern
|
||||||
|
# with ignore case.
|
||||||
|
self.assertEqual(re.fullmatch('[a-c]+', 'ABC', re.I).span(), (0, 3))
|
||||||
|
|
||||||
|
|
||||||
class PatternReprTests(unittest.TestCase):
|
class PatternReprTests(unittest.TestCase):
|
||||||
def check(self, pattern, expected):
|
def check(self, pattern, expected):
|
||||||
|
|
|
@ -454,7 +454,7 @@ class SiginterruptTest(unittest.TestCase):
|
||||||
stdout = first_line + stdout
|
stdout = first_line + stdout
|
||||||
exitcode = process.wait()
|
exitcode = process.wait()
|
||||||
if exitcode not in (2, 3):
|
if exitcode not in (2, 3):
|
||||||
raise Exception("Child error (exit code %s): %s"
|
raise Exception("Child error (exit code %s): %r"
|
||||||
% (exitcode, stdout))
|
% (exitcode, stdout))
|
||||||
return (exitcode == 3)
|
return (exitcode == 3)
|
||||||
|
|
||||||
|
|
|
@ -786,6 +786,7 @@ class ProcessTestCase(BaseTestCase):
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
universal_newlines=1)
|
universal_newlines=1)
|
||||||
p.stdin.write("line1\n")
|
p.stdin.write("line1\n")
|
||||||
|
p.stdin.flush()
|
||||||
self.assertEqual(p.stdout.readline(), "line1\n")
|
self.assertEqual(p.stdout.readline(), "line1\n")
|
||||||
p.stdin.write("line3\n")
|
p.stdin.write("line3\n")
|
||||||
p.stdin.close()
|
p.stdin.close()
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
2) PSF license for Python 2.2
|
2) PSF license for Python 2.2
|
||||||
|
|
||||||
The robots.txt Exclusion Protocol is implemented as specified in
|
The robots.txt Exclusion Protocol is implemented as specified in
|
||||||
http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html
|
http://www.robotstxt.org/norobots-rfc.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import urllib.parse, urllib.request
|
import urllib.parse, urllib.request
|
||||||
|
@ -57,7 +57,7 @@ class RobotFileParser:
|
||||||
except urllib.error.HTTPError as err:
|
except urllib.error.HTTPError as err:
|
||||||
if err.code in (401, 403):
|
if err.code in (401, 403):
|
||||||
self.disallow_all = True
|
self.disallow_all = True
|
||||||
elif err.code >= 400:
|
elif err.code >= 400 and err.code < 500:
|
||||||
self.allow_all = True
|
self.allow_all = True
|
||||||
else:
|
else:
|
||||||
raw = f.read()
|
raw = f.read()
|
||||||
|
@ -85,6 +85,7 @@ class RobotFileParser:
|
||||||
state = 0
|
state = 0
|
||||||
entry = Entry()
|
entry = Entry()
|
||||||
|
|
||||||
|
self.modified()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if not line:
|
if not line:
|
||||||
if state == 1:
|
if state == 1:
|
||||||
|
@ -129,6 +130,12 @@ class RobotFileParser:
|
||||||
return False
|
return False
|
||||||
if self.allow_all:
|
if self.allow_all:
|
||||||
return True
|
return True
|
||||||
|
# Until the robots.txt file has been read or found not
|
||||||
|
# to exist, we must assume that no url is allowable.
|
||||||
|
# This prevents false positives when a user erronenously
|
||||||
|
# calls can_fetch() before calling read().
|
||||||
|
if not self.last_checked:
|
||||||
|
return False
|
||||||
# search for given user agent matches
|
# search for given user agent matches
|
||||||
# the first match counts
|
# the first match counts
|
||||||
parsed_url = urllib.parse.urlparse(urllib.parse.unquote(url))
|
parsed_url = urllib.parse.urlparse(urllib.parse.unquote(url))
|
||||||
|
|
30
Mac/README
30
Mac/README
|
@ -12,6 +12,9 @@ Python on Mac OS X README
|
||||||
This document provides a quick overview of some Mac OS X specific features in
|
This document provides a quick overview of some Mac OS X specific features in
|
||||||
the Python distribution.
|
the Python distribution.
|
||||||
|
|
||||||
|
OS X specific arguments to configure
|
||||||
|
====================================
|
||||||
|
|
||||||
* ``--enable-framework[=DIR]``
|
* ``--enable-framework[=DIR]``
|
||||||
|
|
||||||
If this argument is specified the build will create a Python.framework rather
|
If this argument is specified the build will create a Python.framework rather
|
||||||
|
@ -121,7 +124,7 @@ on a system running OS X 10.5 or later. The ``all`` and ``64-bit`` flavors can
|
||||||
only be built with an 10.5 SDK because ``ppc64`` support was only included with
|
only be built with an 10.5 SDK because ``ppc64`` support was only included with
|
||||||
OS X 10.5. Although legacy ``ppc`` support was included with Xcode 3 on OS X
|
OS X 10.5. Although legacy ``ppc`` support was included with Xcode 3 on OS X
|
||||||
10.6, it was removed in Xcode 4, versions of which were released on OS X 10.6
|
10.6, it was removed in Xcode 4, versions of which were released on OS X 10.6
|
||||||
and which is the current standard for OS X 10.7 and 10.8. To summarize, the
|
and which is the standard for OS X 10.7. To summarize, the
|
||||||
following combinations of SDKs and universal-archs flavors are available:
|
following combinations of SDKs and universal-archs flavors are available:
|
||||||
|
|
||||||
* 10.4u SDK with Xcode 2 supports ``32-bit`` only
|
* 10.4u SDK with Xcode 2 supports ``32-bit`` only
|
||||||
|
@ -134,6 +137,8 @@ following combinations of SDKs and universal-archs flavors are available:
|
||||||
|
|
||||||
* 10.7 and 10.8 SDKs with Xcode 4 support ``intel`` only
|
* 10.7 and 10.8 SDKs with Xcode 4 support ``intel`` only
|
||||||
|
|
||||||
|
* 10.8 and 10.9 SDKs with Xcode 5 support ``intel`` only
|
||||||
|
|
||||||
The makefile for a framework build will also install ``python3.4-32``
|
The makefile for a framework build will also install ``python3.4-32``
|
||||||
binaries when the universal architecture includes at least one 32-bit
|
binaries when the universal architecture includes at least one 32-bit
|
||||||
architecture (that is, for all flavors but ``64-bit``).
|
architecture (that is, for all flavors but ``64-bit``).
|
||||||
|
@ -161,7 +166,6 @@ subprocesses also run in 32-bit-mode if the main interpreter does, use
|
||||||
a ``python3.4-32`` binary and use the value of ``sys.executable`` as the
|
a ``python3.4-32`` binary and use the value of ``sys.executable`` as the
|
||||||
``subprocess`` ``Popen`` executable value.
|
``subprocess`` ``Popen`` executable value.
|
||||||
|
|
||||||
|
|
||||||
Building and using a framework-based Python on Mac OS X.
|
Building and using a framework-based Python on Mac OS X.
|
||||||
========================================================
|
========================================================
|
||||||
|
|
||||||
|
@ -171,7 +175,7 @@ Building and using a framework-based Python on Mac OS X.
|
||||||
|
|
||||||
The main reason is because you want to create GUI programs in Python. With the
|
The main reason is because you want to create GUI programs in Python. With the
|
||||||
exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run
|
exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run
|
||||||
from a Mac OSX application bundle (".app").
|
from a Mac OS X application bundle (".app").
|
||||||
|
|
||||||
While it is technically possible to create a .app without using frameworks you
|
While it is technically possible to create a .app without using frameworks you
|
||||||
will have to do the work yourself if you really want this.
|
will have to do the work yourself if you really want this.
|
||||||
|
@ -196,7 +200,7 @@ Versions/Current and you will see the familiar bin and lib directories.
|
||||||
3. Do I need extra packages?
|
3. Do I need extra packages?
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Yes, probably. If you want Tkinter support you need to get the OSX AquaTk
|
Yes, probably. If you want Tkinter support you need to get the OS X AquaTk
|
||||||
distribution, this is installed by default on Mac OS X 10.4 or later. Be
|
distribution, this is installed by default on Mac OS X 10.4 or later. Be
|
||||||
aware, though, that the Cocoa-based AquaTk's supplied starting with OS X
|
aware, though, that the Cocoa-based AquaTk's supplied starting with OS X
|
||||||
10.6 have proven to be unstable. If possible, you should consider
|
10.6 have proven to be unstable. If possible, you should consider
|
||||||
|
@ -212,9 +216,9 @@ If you want Cocoa you need to get PyObjC.
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
This directory contains a Makefile that will create a couple of python-related
|
This directory contains a Makefile that will create a couple of python-related
|
||||||
applications (full-blown OSX .app applications, that is) in
|
applications (full-blown OS X .app applications, that is) in
|
||||||
"/Applications/Python <VERSION>", and a hidden helper application Python.app
|
"/Applications/Python <VERSION>", and a hidden helper application Python.app
|
||||||
inside the Python.framework, and unix tools "python" and "pythonw" into
|
inside the Python.framework, and unix tools including "python" into
|
||||||
/usr/local/bin. In addition it has a target "installmacsubtree" that installs
|
/usr/local/bin. In addition it has a target "installmacsubtree" that installs
|
||||||
the relevant portions of the Mac subtree into the Python.framework.
|
the relevant portions of the Mac subtree into the Python.framework.
|
||||||
|
|
||||||
|
@ -252,18 +256,18 @@ What do all these programs do?
|
||||||
"IDLE.app" is an integrated development environment for Python: editor,
|
"IDLE.app" is an integrated development environment for Python: editor,
|
||||||
debugger, etc.
|
debugger, etc.
|
||||||
|
|
||||||
"PythonLauncher.app" is a helper application that will handle things when you
|
"Python Launcher.app" is a helper application that will handle things when you
|
||||||
double-click a .py, .pyc or .pyw file. For the first two it creates a Terminal
|
double-click a .py, .pyc or .pyw file. For the first two it creates a Terminal
|
||||||
window and runs the scripts with the normal command-line Python. For the
|
window and runs the scripts with the normal command-line Python. For the
|
||||||
latter it runs the script in the Python.app interpreter so the script can do
|
latter it runs the script in the Python.app interpreter so the script can do
|
||||||
GUI-things. Keep the ``Option`` key depressed while dragging or double-clicking
|
GUI-things. Keep the ``Option`` key depressed while dragging or double-clicking
|
||||||
a script to set runtime options. These options can be set persistently
|
a script to set runtime options. These options can be set persistently
|
||||||
through PythonLauncher's preferences dialog.
|
through Python Launcher's preferences dialog.
|
||||||
|
|
||||||
The program ``pythonx.x`` runs python scripts from the command line. Various
|
The program ``pythonx.x`` runs python scripts from the command line.
|
||||||
compatibility aliases are also installed, including ``pythonwx.x`` which
|
Previously, various compatibility aliases were also installed, including
|
||||||
in early releases of Python on OS X was required to run GUI programs. In
|
``pythonwx.x`` which in early releases of Python on OS X was required to run
|
||||||
current releases, the ``pythonx.x`` and ``pythonwx.x`` commands are identical.
|
GUI programs. As of 3.4.0, the ``pythonwx.x`` aliases are no longer installed.
|
||||||
|
|
||||||
How do I create a binary distribution?
|
How do I create a binary distribution?
|
||||||
======================================
|
======================================
|
||||||
|
@ -308,7 +312,7 @@ The configure script sometimes emits warnings like the one below::
|
||||||
configure: WARNING: libintl.h: check for missing prerequisite headers?
|
configure: WARNING: libintl.h: check for missing prerequisite headers?
|
||||||
configure: WARNING: libintl.h: see the Autoconf documentation
|
configure: WARNING: libintl.h: see the Autoconf documentation
|
||||||
configure: WARNING: libintl.h: section "Present But Cannot Be Compiled"
|
configure: WARNING: libintl.h: section "Present But Cannot Be Compiled"
|
||||||
configure: WARNING: libintl.h: proceeding with the preprocessor's result
|
configure: WARNING: libintl.h: proceeding with the preprocessor's result
|
||||||
configure: WARNING: libintl.h: in the future, the compiler will take precedence
|
configure: WARNING: libintl.h: in the future, the compiler will take precedence
|
||||||
configure: WARNING: ## -------------------------------------- ##
|
configure: WARNING: ## -------------------------------------- ##
|
||||||
configure: WARNING: ## Report this to http://bugs.python.org/ ##
|
configure: WARNING: ## Report this to http://bugs.python.org/ ##
|
||||||
|
|
|
@ -1487,6 +1487,7 @@ TAGS::
|
||||||
|
|
||||||
# Touch generated files
|
# Touch generated files
|
||||||
touch:
|
touch:
|
||||||
|
cd $(srcdir); \
|
||||||
hg --config extensions.touch=Tools/hg/hgtouch.py touch -v
|
hg --config extensions.touch=Tools/hg/hgtouch.py touch -v
|
||||||
|
|
||||||
# Sanitation targets -- clean leaves libraries, executables and tags
|
# Sanitation targets -- clean leaves libraries, executables and tags
|
||||||
|
|
|
@ -24,6 +24,7 @@ Jim Ahlstrom
|
||||||
Farhan Ahmad
|
Farhan Ahmad
|
||||||
Matthew Ahrens
|
Matthew Ahrens
|
||||||
Nir Aides
|
Nir Aides
|
||||||
|
Akira
|
||||||
Yaniv Aknin
|
Yaniv Aknin
|
||||||
Jyrki Alakuijala
|
Jyrki Alakuijala
|
||||||
Steve Alexander
|
Steve Alexander
|
||||||
|
@ -672,6 +673,7 @@ Mads Kiilerich
|
||||||
Jason Killen
|
Jason Killen
|
||||||
Jan Kim
|
Jan Kim
|
||||||
Taek Joo Kim
|
Taek Joo Kim
|
||||||
|
Sam Kimbrel
|
||||||
W. Trevor King
|
W. Trevor King
|
||||||
Paul Kippes
|
Paul Kippes
|
||||||
Steve Kirsch
|
Steve Kirsch
|
||||||
|
|
52
Misc/NEWS
52
Misc/NEWS
|
@ -10,14 +10,56 @@ Release date: 2014-05-18
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #21418: Fix a crash in the builtin function super() when called without
|
||||||
|
argument and without current frame (ex: embedded Python).
|
||||||
|
|
||||||
|
- Issue #21425: Fix flushing of standard streams in the interactive
|
||||||
|
interpreter.
|
||||||
|
|
||||||
|
- Issue #21435: In rare cases, when running finalizers on objects in cyclic
|
||||||
|
trash a bad pointer dereference could occur due to a subtle flaw in
|
||||||
|
internal iteration logic.
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #10744: Fix PEP 3118 format strings on ctypes objects with a nontrivial
|
||||||
|
shape.
|
||||||
|
|
||||||
|
- Issue #20998: Fixed re.fullmatch() of repeated single character pattern
|
||||||
|
with ignore case. Original patch by Matthew Barnett.
|
||||||
|
|
||||||
|
- Issue #21075: fileinput.FileInput now reads bytes from standard stream if
|
||||||
|
binary mode is specified. Patch by Sam Kimbrel.
|
||||||
|
|
||||||
|
- Issue #21396: Fix TextIOWrapper(..., write_through=True) to not force a
|
||||||
|
flush() on the underlying binary stream. Patch by akira.
|
||||||
|
|
||||||
|
- Issue #21470: Do a better job seeding the random number generator by
|
||||||
|
using enough bytes to span the full state space of the Mersenne Twister.
|
||||||
|
|
||||||
|
- Issue #21398: Fix an unicode error in the pydoc pager when the documentation
|
||||||
|
contains characters not encodable to the stdout encoding.
|
||||||
|
|
||||||
|
Tests
|
||||||
|
-----
|
||||||
|
|
||||||
|
- Issue #17756: Fix test_code test when run from the installed location.
|
||||||
|
|
||||||
|
- Issue #17752: Fix distutils tests when run from the installed location.
|
||||||
|
|
||||||
|
IDLE
|
||||||
|
----
|
||||||
|
|
||||||
|
- Issue #18104: Add idlelib/idle_test/htest.py with a few sample tests to begin
|
||||||
|
consolidating and improving human-validated tests of Idle. Change other files
|
||||||
|
as needed to work with htest. Running the module as __main__ runs all tests.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.4.1rc1?
|
What's New in Python 3.4.1rc1?
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
Release date: TBA
|
Release date: 2014-05-05
|
||||||
|
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -54,6 +96,10 @@ Library
|
||||||
- Issue #21088: Bugfix for curses.window.addch() regression in 3.4.0.
|
- Issue #21088: Bugfix for curses.window.addch() regression in 3.4.0.
|
||||||
In porting to Argument Clinic, the first two arguments were reversed.
|
In porting to Argument Clinic, the first two arguments were reversed.
|
||||||
|
|
||||||
|
- Issue #21469: Reduced the risk of false positives in robotparser by
|
||||||
|
checking to make sure that robots.txt has been read or does not exist
|
||||||
|
prior to returning True in can_fetch().
|
||||||
|
|
||||||
- Issue #21321: itertools.islice() now releases the reference to the source
|
- Issue #21321: itertools.islice() now releases the reference to the source
|
||||||
iterator when the slice is exhausted. Patch by Anton Afanasyev.
|
iterator when the slice is exhausted. Patch by Anton Afanasyev.
|
||||||
|
|
||||||
|
@ -153,6 +199,8 @@ Library
|
||||||
|
|
||||||
- Issue #20884: Don't assume that __file__ is defined on importlib.__init__.
|
- Issue #20884: Don't assume that __file__ is defined on importlib.__init__.
|
||||||
|
|
||||||
|
- Issue #21499: Ignore __builtins__ in several test_importlib.test_api tests.
|
||||||
|
|
||||||
- Issue #20879: Delay the initialization of encoding and decoding tables for
|
- Issue #20879: Delay the initialization of encoding and decoding tables for
|
||||||
base32, ascii85 and base85 codecs in the base64 module, and delay the
|
base32, ascii85 and base85 codecs in the base64 module, and delay the
|
||||||
initialization of the unquote_to_bytes() table of the urllib.parse module, to
|
initialization of the unquote_to_bytes() table of the urllib.parse module, to
|
||||||
|
@ -219,6 +267,8 @@ Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd.
|
- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd.
|
||||||
|
- Issue #21226: Set up modules properly in PyImport_ExecCodeModuleObject
|
||||||
|
(and friends).
|
||||||
|
|
||||||
IDLE
|
IDLE
|
||||||
----
|
----
|
||||||
|
|
|
@ -288,6 +288,48 @@ _ctypes_alloc_format_string(const char *prefix, const char *suffix)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Allocate a memory block for a pep3118 format string, adding
|
||||||
|
the given prefix (if non-null), an additional shape prefix, and a suffix.
|
||||||
|
Returns NULL on failure, with the error indicator set. If called with
|
||||||
|
a suffix of NULL the error indicator must already be set.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
_ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
|
||||||
|
const char *prefix, const char *suffix)
|
||||||
|
{
|
||||||
|
char *new_prefix;
|
||||||
|
char *result;
|
||||||
|
char buf[32];
|
||||||
|
int prefix_len;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
prefix_len = 32 * ndim + 3;
|
||||||
|
if (prefix)
|
||||||
|
prefix_len += strlen(prefix);
|
||||||
|
new_prefix = PyMem_Malloc(prefix_len);
|
||||||
|
if (new_prefix == NULL)
|
||||||
|
return NULL;
|
||||||
|
new_prefix[0] = '\0';
|
||||||
|
if (prefix)
|
||||||
|
strcpy(new_prefix, prefix);
|
||||||
|
if (ndim > 0) {
|
||||||
|
/* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */
|
||||||
|
strcat(new_prefix, "(");
|
||||||
|
for (k = 0; k < ndim; ++k) {
|
||||||
|
if (k < ndim-1) {
|
||||||
|
sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]);
|
||||||
|
} else {
|
||||||
|
sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]);
|
||||||
|
}
|
||||||
|
strcat(new_prefix, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = _ctypes_alloc_format_string(new_prefix, suffix);
|
||||||
|
PyMem_Free(new_prefix);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PyCStructType_Type - a meta type/class. Creating a new class using this one as
|
PyCStructType_Type - a meta type/class. Creating a new class using this one as
|
||||||
__metaclass__ will call the contructor StructUnionType_new. It replaces the
|
__metaclass__ will call the contructor StructUnionType_new. It replaces the
|
||||||
|
@ -860,14 +902,21 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
|
|
||||||
if (proto) {
|
if (proto) {
|
||||||
StgDictObject *itemdict = PyType_stgdict(proto);
|
StgDictObject *itemdict = PyType_stgdict(proto);
|
||||||
|
const char *current_format;
|
||||||
assert(itemdict);
|
assert(itemdict);
|
||||||
/* If itemdict->format is NULL, then this is a pointer to an
|
/* If itemdict->format is NULL, then this is a pointer to an
|
||||||
incomplete type. We create a generic format string
|
incomplete type. We create a generic format string
|
||||||
'pointer to bytes' in this case. XXX Better would be to
|
'pointer to bytes' in this case. XXX Better would be to
|
||||||
fix the format string later...
|
fix the format string later...
|
||||||
*/
|
*/
|
||||||
stgdict->format = _ctypes_alloc_format_string("&",
|
current_format = itemdict->format ? itemdict->format : "B";
|
||||||
itemdict->format ? itemdict->format : "B");
|
if (itemdict->shape != NULL) {
|
||||||
|
/* pointer to an array: the shape needs to be prefixed */
|
||||||
|
stgdict->format = _ctypes_alloc_format_string_with_shape(
|
||||||
|
itemdict->ndim, itemdict->shape, "&", current_format);
|
||||||
|
} else {
|
||||||
|
stgdict->format = _ctypes_alloc_format_string("&", current_format);
|
||||||
|
}
|
||||||
if (stgdict->format == NULL) {
|
if (stgdict->format == NULL) {
|
||||||
Py_DECREF((PyObject *)stgdict);
|
Py_DECREF((PyObject *)stgdict);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1245,7 +1294,6 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
long length;
|
long length;
|
||||||
int overflow;
|
int overflow;
|
||||||
Py_ssize_t itemsize, itemalign;
|
Py_ssize_t itemsize, itemalign;
|
||||||
char buf[32];
|
|
||||||
|
|
||||||
/* create the new instance (which is a class,
|
/* create the new instance (which is a class,
|
||||||
since we are a metatype!) */
|
since we are a metatype!) */
|
||||||
|
@ -1295,13 +1343,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(itemdict->format);
|
assert(itemdict->format);
|
||||||
if (itemdict->format[0] == '(') {
|
stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format);
|
||||||
sprintf(buf, "(%ld,", length);
|
|
||||||
stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
|
|
||||||
} else {
|
|
||||||
sprintf(buf, "(%ld)", length);
|
|
||||||
stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
|
|
||||||
}
|
|
||||||
if (stgdict->format == NULL)
|
if (stgdict->format == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
stgdict->ndim = itemdict->ndim + 1;
|
stgdict->ndim = itemdict->ndim + 1;
|
||||||
|
|
|
@ -357,6 +357,9 @@ extern void _ctypes_add_traceback(char *, char *, int);
|
||||||
|
|
||||||
extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
|
extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
|
||||||
extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix);
|
extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix);
|
||||||
|
extern char *_ctypes_alloc_format_string_with_shape(int ndim,
|
||||||
|
const Py_ssize_t *shape,
|
||||||
|
const char *prefix, const char *suffix);
|
||||||
|
|
||||||
extern int _ctypes_simple_instance(PyObject *obj);
|
extern int _ctypes_simple_instance(PyObject *obj);
|
||||||
|
|
||||||
|
|
|
@ -505,7 +505,12 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
|
||||||
sprintf(buf, "%s:%s:", fieldfmt, fieldname);
|
sprintf(buf, "%s:%s:", fieldfmt, fieldname);
|
||||||
|
|
||||||
ptr = stgdict->format;
|
ptr = stgdict->format;
|
||||||
stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf);
|
if (dict->shape != NULL) {
|
||||||
|
stgdict->format = _ctypes_alloc_format_string_with_shape(
|
||||||
|
dict->ndim, dict->shape, stgdict->format, buf);
|
||||||
|
} else {
|
||||||
|
stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf);
|
||||||
|
}
|
||||||
PyMem_Free(ptr);
|
PyMem_Free(ptr);
|
||||||
PyMem_Free(buf);
|
PyMem_Free(buf);
|
||||||
|
|
||||||
|
|
|
@ -1297,7 +1297,7 @@ textiowrapper_write(textio *self, PyObject *args)
|
||||||
PyObject *b;
|
PyObject *b;
|
||||||
Py_ssize_t textlen;
|
Py_ssize_t textlen;
|
||||||
int haslf = 0;
|
int haslf = 0;
|
||||||
int needflush = 0;
|
int needflush = 0, text_needflush = 0;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_INITIALIZED(self);
|
||||||
|
|
||||||
|
@ -1331,8 +1331,8 @@ textiowrapper_write(textio *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->write_through)
|
if (self->write_through)
|
||||||
needflush = 1;
|
text_needflush = 1;
|
||||||
else if (self->line_buffering &&
|
if (self->line_buffering &&
|
||||||
(haslf ||
|
(haslf ||
|
||||||
PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
|
PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
|
||||||
needflush = 1;
|
needflush = 1;
|
||||||
|
@ -1363,7 +1363,8 @@ textiowrapper_write(textio *self, PyObject *args)
|
||||||
}
|
}
|
||||||
self->pending_bytes_count += PyBytes_GET_SIZE(b);
|
self->pending_bytes_count += PyBytes_GET_SIZE(b);
|
||||||
Py_DECREF(b);
|
Py_DECREF(b);
|
||||||
if (self->pending_bytes_count > self->chunk_size || needflush) {
|
if (self->pending_bytes_count > self->chunk_size || needflush ||
|
||||||
|
text_needflush) {
|
||||||
if (_textiowrapper_writeflush(self) < 0)
|
if (_textiowrapper_writeflush(self) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,7 @@ compare_digest(PyObject *self, PyObject *args)
|
||||||
Py_buffer view_a;
|
Py_buffer view_a;
|
||||||
Py_buffer view_b;
|
Py_buffer view_b;
|
||||||
|
|
||||||
if ((PyObject_CheckBuffer(a) == 0) & (PyObject_CheckBuffer(b) == 0)) {
|
if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"unsupported operand types(s) or combination of types: "
|
"unsupported operand types(s) or combination of types: "
|
||||||
"'%.100s' and '%.100s'",
|
"'%.100s' and '%.100s'",
|
||||||
|
|
|
@ -505,14 +505,14 @@ pattern_dealloc(PatternObject* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
sre_match(SRE_STATE* state, SRE_CODE* pattern)
|
sre_match(SRE_STATE* state, SRE_CODE* pattern, int match_all)
|
||||||
{
|
{
|
||||||
if (state->charsize == 1)
|
if (state->charsize == 1)
|
||||||
return sre_ucs1_match(state, pattern);
|
return sre_ucs1_match(state, pattern, match_all);
|
||||||
if (state->charsize == 2)
|
if (state->charsize == 2)
|
||||||
return sre_ucs2_match(state, pattern);
|
return sre_ucs2_match(state, pattern, match_all);
|
||||||
assert(state->charsize == 4);
|
assert(state->charsize == 4);
|
||||||
return sre_ucs4_match(state, pattern);
|
return sre_ucs4_match(state, pattern, match_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
|
@ -576,7 +576,7 @@ pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
|
||||||
TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
|
||||||
|
|
||||||
status = sre_match(&state, PatternObject_GetCode(self));
|
status = sre_match(&state, PatternObject_GetCode(self), 0);
|
||||||
|
|
||||||
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
|
@ -609,12 +609,11 @@ pattern_fullmatch(PatternObject* self, PyObject* args, PyObject* kw)
|
||||||
if (!string)
|
if (!string)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
state.match_all = 1;
|
|
||||||
state.ptr = state.start;
|
state.ptr = state.start;
|
||||||
|
|
||||||
TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr));
|
||||||
|
|
||||||
status = sre_match(&state, PatternObject_GetCode(self));
|
status = sre_match(&state, PatternObject_GetCode(self), 1);
|
||||||
|
|
||||||
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
|
@ -2572,7 +2571,7 @@ scanner_match(ScannerObject* self, PyObject *unused)
|
||||||
|
|
||||||
state->ptr = state->start;
|
state->ptr = state->start;
|
||||||
|
|
||||||
status = sre_match(state, PatternObject_GetCode(self->pattern));
|
status = sre_match(state, PatternObject_GetCode(self->pattern), 0);
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,10 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
|
||||||
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
|
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (file == Py_None) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _PyObject_CallMethodId(file, &PyId_fileno, "");
|
result = _PyObject_CallMethodId(file, &PyId_fileno, "");
|
||||||
|
|
|
@ -776,28 +776,40 @@ handle_legacy_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Run first-time finalizers (if any) on all the objects in collectable.
|
||||||
|
* Note that this may remove some (or even all) of the objects from the
|
||||||
|
* list, due to refcounts falling to 0.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
finalize_garbage(PyGC_Head *collectable, PyGC_Head *old)
|
finalize_garbage(PyGC_Head *collectable)
|
||||||
{
|
{
|
||||||
destructor finalize;
|
destructor finalize;
|
||||||
PyGC_Head *gc = collectable->gc.gc_next;
|
PyGC_Head seen;
|
||||||
|
|
||||||
for (; gc != collectable; gc = gc->gc.gc_next) {
|
/* While we're going through the loop, `finalize(op)` may cause op, or
|
||||||
|
* other objects, to be reclaimed via refcounts falling to zero. So
|
||||||
|
* there's little we can rely on about the structure of the input
|
||||||
|
* `collectable` list across iterations. For safety, we always take the
|
||||||
|
* first object in that list and move it to a temporary `seen` list.
|
||||||
|
* If objects vanish from the `collectable` and `seen` lists we don't
|
||||||
|
* care.
|
||||||
|
*/
|
||||||
|
gc_list_init(&seen);
|
||||||
|
|
||||||
|
while (!gc_list_is_empty(collectable)) {
|
||||||
|
PyGC_Head *gc = collectable->gc.gc_next;
|
||||||
PyObject *op = FROM_GC(gc);
|
PyObject *op = FROM_GC(gc);
|
||||||
|
gc_list_move(gc, &seen);
|
||||||
if (!_PyGCHead_FINALIZED(gc) &&
|
if (!_PyGCHead_FINALIZED(gc) &&
|
||||||
PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) &&
|
PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) &&
|
||||||
(finalize = Py_TYPE(op)->tp_finalize) != NULL) {
|
(finalize = Py_TYPE(op)->tp_finalize) != NULL) {
|
||||||
_PyGCHead_SET_FINALIZED(gc, 1);
|
_PyGCHead_SET_FINALIZED(gc, 1);
|
||||||
Py_INCREF(op);
|
Py_INCREF(op);
|
||||||
finalize(op);
|
finalize(op);
|
||||||
if (Py_REFCNT(op) == 1) {
|
|
||||||
/* op will be destroyed */
|
|
||||||
gc = gc->gc.gc_prev;
|
|
||||||
}
|
|
||||||
Py_DECREF(op);
|
Py_DECREF(op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gc_list_merge(&seen, collectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walk the collectable list and check that they are really unreachable
|
/* Walk the collectable list and check that they are really unreachable
|
||||||
|
@ -1006,7 +1018,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
|
||||||
m += handle_weakrefs(&unreachable, old);
|
m += handle_weakrefs(&unreachable, old);
|
||||||
|
|
||||||
/* Call tp_finalize on objects which have one. */
|
/* Call tp_finalize on objects which have one. */
|
||||||
finalize_garbage(&unreachable, old);
|
finalize_garbage(&unreachable);
|
||||||
|
|
||||||
if (check_garbage(&unreachable)) {
|
if (check_garbage(&unreachable)) {
|
||||||
revive_garbage(&unreachable);
|
revive_garbage(&unreachable);
|
||||||
|
|
|
@ -86,7 +86,6 @@ typedef struct {
|
||||||
SRE_REPEAT *repeat;
|
SRE_REPEAT *repeat;
|
||||||
/* hooks */
|
/* hooks */
|
||||||
SRE_TOLOWER_HOOK lower;
|
SRE_TOLOWER_HOOK lower;
|
||||||
int match_all;
|
|
||||||
} SRE_STATE;
|
} SRE_STATE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -173,7 +173,7 @@ SRE(charset)(SRE_CODE* set, SRE_CODE ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern);
|
LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all);
|
||||||
|
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
|
SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
|
||||||
|
@ -259,7 +259,7 @@ SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
|
||||||
/* repeated single character pattern */
|
/* repeated single character pattern */
|
||||||
TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
|
TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
|
||||||
while ((SRE_CHAR*) state->ptr < end) {
|
while ((SRE_CHAR*) state->ptr < end) {
|
||||||
i = SRE(match)(state, pattern);
|
i = SRE(match)(state, pattern, 0);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return i;
|
return i;
|
||||||
if (!i)
|
if (!i)
|
||||||
|
@ -490,7 +490,7 @@ typedef struct {
|
||||||
/* check if string matches the given pattern. returns <0 for
|
/* check if string matches the given pattern. returns <0 for
|
||||||
error, 0 for failure, and 1 for success */
|
error, 0 for failure, and 1 for success */
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
SRE(match)(SRE_STATE* state, SRE_CODE* pattern)
|
SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all)
|
||||||
{
|
{
|
||||||
SRE_CHAR* end = (SRE_CHAR *)state->end;
|
SRE_CHAR* end = (SRE_CHAR *)state->end;
|
||||||
Py_ssize_t alloc_pos, ctx_pos = -1;
|
Py_ssize_t alloc_pos, ctx_pos = -1;
|
||||||
|
@ -507,7 +507,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
ctx->last_ctx_pos = -1;
|
ctx->last_ctx_pos = -1;
|
||||||
ctx->jump = JUMP_NONE;
|
ctx->jump = JUMP_NONE;
|
||||||
ctx->pattern = pattern;
|
ctx->pattern = pattern;
|
||||||
ctx->match_all = state->match_all;
|
ctx->match_all = match_all;
|
||||||
ctx_pos = alloc_pos;
|
ctx_pos = alloc_pos;
|
||||||
|
|
||||||
entrance:
|
entrance:
|
||||||
|
@ -739,7 +739,7 @@ entrance:
|
||||||
RETURN_FAILURE;
|
RETURN_FAILURE;
|
||||||
|
|
||||||
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
||||||
(!ctx->match_all || ctx->ptr == state->end)) {
|
ctx->ptr == state->end) {
|
||||||
/* tail is empty. we're finished */
|
/* tail is empty. we're finished */
|
||||||
state->ptr = ctx->ptr;
|
state->ptr = ctx->ptr;
|
||||||
RETURN_SUCCESS;
|
RETURN_SUCCESS;
|
||||||
|
@ -824,7 +824,7 @@ entrance:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
||||||
(!ctx->match_all || ctx->ptr == state->end)) {
|
(!match_all || ctx->ptr == state->end)) {
|
||||||
/* tail is empty. we're finished */
|
/* tail is empty. we're finished */
|
||||||
state->ptr = ctx->ptr;
|
state->ptr = ctx->ptr;
|
||||||
RETURN_SUCCESS;
|
RETURN_SUCCESS;
|
||||||
|
@ -1269,7 +1269,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
state->ptr = ptr - (prefix_len - prefix_skip - 1);
|
state->ptr = ptr - (prefix_len - prefix_skip - 1);
|
||||||
if (flags & SRE_INFO_LITERAL)
|
if (flags & SRE_INFO_LITERAL)
|
||||||
return 1; /* we got all of it */
|
return 1; /* we got all of it */
|
||||||
status = SRE(match)(state, pattern + 2*prefix_skip);
|
status = SRE(match)(state, pattern + 2*prefix_skip, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
/* close but no cigar -- try again */
|
/* close but no cigar -- try again */
|
||||||
|
@ -1302,7 +1302,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
state->ptr = ++ptr;
|
state->ptr = ++ptr;
|
||||||
if (flags & SRE_INFO_LITERAL)
|
if (flags & SRE_INFO_LITERAL)
|
||||||
return 1; /* we got all of it */
|
return 1; /* we got all of it */
|
||||||
status = SRE(match)(state, pattern + 2);
|
status = SRE(match)(state, pattern + 2, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1317,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
|
TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
|
||||||
state->start = ptr;
|
state->start = ptr;
|
||||||
state->ptr = ptr;
|
state->ptr = ptr;
|
||||||
status = SRE(match)(state, pattern);
|
status = SRE(match)(state, pattern, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -1327,7 +1327,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
while (ptr <= end) {
|
while (ptr <= end) {
|
||||||
TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
|
TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
|
||||||
state->start = state->ptr = ptr++;
|
state->start = state->ptr = ptr++;
|
||||||
status = SRE(match)(state, pattern);
|
status = SRE(match)(state, pattern, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6919,9 +6919,16 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
/* Call super(), without args -- fill in from __class__
|
/* Call super(), without args -- fill in from __class__
|
||||||
and first local variable on the stack. */
|
and first local variable on the stack. */
|
||||||
PyFrameObject *f = PyThreadState_GET()->frame;
|
PyFrameObject *f;
|
||||||
PyCodeObject *co = f->f_code;
|
PyCodeObject *co;
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
|
f = PyThreadState_GET()->frame;
|
||||||
|
if (f == NULL) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"super(): no current frame");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
co = f->f_code;
|
||||||
if (co == NULL) {
|
if (co == NULL) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"super(): no code object");
|
"super(): no code object");
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
# python.exe build_ssl.py Release Win32
|
# python.exe build_ssl.py Release Win32
|
||||||
|
|
||||||
import os, sys, re, shutil
|
import os, sys, re, shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# Find all "foo.exe" files on the PATH.
|
# Find all "foo.exe" files on the PATH.
|
||||||
def find_all_on_path(filename, extras = None):
|
def find_all_on_path(filename, extras = None):
|
||||||
|
@ -46,22 +47,21 @@ def find_all_on_path(filename, extras = None):
|
||||||
# is available.
|
# is available.
|
||||||
def find_working_perl(perls):
|
def find_working_perl(perls):
|
||||||
for perl in perls:
|
for perl in perls:
|
||||||
fh = os.popen('"%s" -e "use Win32;"' % perl)
|
try:
|
||||||
fh.read()
|
subprocess.check_output([perl, "-e", "use Win32;"])
|
||||||
rc = fh.close()
|
except subprocess.CalledProcessError:
|
||||||
if rc:
|
|
||||||
continue
|
continue
|
||||||
return perl
|
else:
|
||||||
print("Can not find a suitable PERL:")
|
return perl
|
||||||
|
|
||||||
if perls:
|
if perls:
|
||||||
print(" the following perl interpreters were found:")
|
print("The following perl interpreters were found:")
|
||||||
for p in perls:
|
for p in perls:
|
||||||
print(" ", p)
|
print(" ", p)
|
||||||
print(" None of these versions appear suitable for building OpenSSL")
|
print(" None of these versions appear suitable for building OpenSSL")
|
||||||
else:
|
else:
|
||||||
print(" NO perl interpreters were found on this machine at all!")
|
print("NO perl interpreters were found on this machine at all!")
|
||||||
print(" Please install ActivePerl and ensure it appears on your path")
|
print(" Please install ActivePerl and ensure it appears on your path")
|
||||||
return None
|
|
||||||
|
|
||||||
# Fetch SSL directory from VC properties
|
# Fetch SSL directory from VC properties
|
||||||
def get_ssl_dir():
|
def get_ssl_dir():
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<PreLinkEvent>
|
<PreLinkEvent>
|
||||||
<Message>Generate build information...</Message>
|
<Message>Generate build information...</Message>
|
||||||
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)"</Command>
|
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
|
||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -209,7 +209,7 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<PreLinkEvent>
|
<PreLinkEvent>
|
||||||
<Message>Generate build information...</Message>
|
<Message>Generate build information...</Message>
|
||||||
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)"</Command>
|
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
|
||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -314,7 +314,7 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<PreLinkEvent>
|
<PreLinkEvent>
|
||||||
<Message>Generate build information...</Message>
|
<Message>Generate build information...</Message>
|
||||||
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)"</Command>
|
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
|
||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -350,7 +350,7 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<PreLinkEvent>
|
<PreLinkEvent>
|
||||||
<Message>Generate build information...</Message>
|
<Message>Generate build information...</Message>
|
||||||
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)"</Command>
|
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
|
||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -383,7 +383,7 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<PreLinkEvent>
|
<PreLinkEvent>
|
||||||
<Message>Generate build information...</Message>
|
<Message>Generate build information...</Message>
|
||||||
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)"</Command>
|
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
|
||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -419,7 +419,7 @@ IF %ERRORLEVEL% NEQ 0 (
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<PreLinkEvent>
|
<PreLinkEvent>
|
||||||
<Message>Generate build information...</Message>
|
<Message>Generate build information...</Message>
|
||||||
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)"</Command>
|
<Command>"$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)\"</Command>
|
||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(IntDir)getbuildinfo.o;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define PyCOND_ADD_MICROSECONDS(tv, interval) \
|
#define PyCOND_ADD_MICROSECONDS(tv, interval) \
|
||||||
do { \
|
do { /* TODO: add overflow and truncation checks */ \
|
||||||
tv.tv_usec += (long) interval; \
|
tv.tv_usec += (long) interval; \
|
||||||
tv.tv_sec += tv.tv_usec / 1000000; \
|
tv.tv_sec += tv.tv_usec / 1000000; \
|
||||||
tv.tv_usec %= 1000000; \
|
tv.tv_usec %= 1000000; \
|
||||||
|
@ -89,7 +89,7 @@ do { \
|
||||||
|
|
||||||
/* return 0 for success, 1 on timeout, -1 on error */
|
/* return 0 for success, 1 on timeout, -1 on error */
|
||||||
Py_LOCAL_INLINE(int)
|
Py_LOCAL_INLINE(int)
|
||||||
PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long us)
|
PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, PY_LONG_LONG us)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
@ -270,9 +270,9 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_LOCAL_INLINE(int)
|
Py_LOCAL_INLINE(int)
|
||||||
PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us)
|
PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, PY_LONG_LONG us)
|
||||||
{
|
{
|
||||||
return _PyCOND_WAIT_MS(cv, cs, us/1000);
|
return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_LOCAL_INLINE(int)
|
Py_LOCAL_INLINE(int)
|
||||||
|
@ -363,9 +363,9 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs)
|
||||||
* 2 to indicate that we don't know.
|
* 2 to indicate that we don't know.
|
||||||
*/
|
*/
|
||||||
Py_LOCAL_INLINE(int)
|
Py_LOCAL_INLINE(int)
|
||||||
PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us)
|
PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, PY_LONG_LONG us)
|
||||||
{
|
{
|
||||||
return SleepConditionVariableSRW(cv, cs, us/1000, 0) ? 2 : -1;
|
return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_LOCAL_INLINE(int)
|
Py_LOCAL_INLINE(int)
|
||||||
|
|
|
@ -856,7 +856,7 @@ module_dict_for_exec(PyObject *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return d;
|
return d; /* Return a borrowed reference. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -888,33 +888,25 @@ PyObject*
|
||||||
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
|
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
|
||||||
PyObject *cpathname)
|
PyObject *cpathname)
|
||||||
{
|
{
|
||||||
PyObject *d, *v;
|
PyObject *d, *res;
|
||||||
|
PyInterpreterState *interp = PyThreadState_GET()->interp;
|
||||||
|
_Py_IDENTIFIER(_fix_up_module);
|
||||||
|
|
||||||
d = module_dict_for_exec(name);
|
d = module_dict_for_exec(name);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathname != NULL) {
|
if (pathname == NULL) {
|
||||||
v = pathname;
|
pathname = ((PyCodeObject *)co)->co_filename;
|
||||||
}
|
}
|
||||||
else {
|
res = _PyObject_CallMethodIdObjArgs(interp->importlib,
|
||||||
v = ((PyCodeObject *)co)->co_filename;
|
&PyId__fix_up_module,
|
||||||
|
d, name, pathname, cpathname, NULL);
|
||||||
|
if (res != NULL) {
|
||||||
|
res = exec_code_in_module(name, d, co);
|
||||||
}
|
}
|
||||||
Py_INCREF(v);
|
return res;
|
||||||
if (PyDict_SetItemString(d, "__file__", v) != 0)
|
|
||||||
PyErr_Clear(); /* Not important enough to report */
|
|
||||||
Py_DECREF(v);
|
|
||||||
|
|
||||||
/* Remember the pyc path name as the __cached__ attribute. */
|
|
||||||
if (cpathname != NULL)
|
|
||||||
v = cpathname;
|
|
||||||
else
|
|
||||||
v = Py_None;
|
|
||||||
if (PyDict_SetItemString(d, "__cached__", v) != 0)
|
|
||||||
PyErr_Clear(); /* Not important enough to report */
|
|
||||||
|
|
||||||
return exec_code_in_module(name, d, co);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
8547
Python/importlib.h
8547
Python/importlib.h
File diff suppressed because it is too large
Load Diff
|
@ -1444,12 +1444,13 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
|
||||||
d = PyModule_GetDict(m);
|
d = PyModule_GetDict(m);
|
||||||
v = run_mod(mod, filename, d, d, flags, arena);
|
v = run_mod(mod, filename, d, d, flags, arena);
|
||||||
PyArena_Free(arena);
|
PyArena_Free(arena);
|
||||||
flush_io();
|
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
flush_io();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
flush_io();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
|
||||||
/* wait at least until the target */
|
/* wait at least until the target */
|
||||||
DWORD now, target = GetTickCount() + milliseconds;
|
DWORD now, target = GetTickCount() + milliseconds;
|
||||||
while (mutex->locked) {
|
while (mutex->locked) {
|
||||||
if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, milliseconds*1000) < 0) {
|
if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, (PY_LONG_LONG)milliseconds*1000) < 0) {
|
||||||
result = WAIT_FAILED;
|
result = WAIT_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5605,7 +5605,7 @@ $as_echo_n "checking LDLIBRARY... " >&6; }
|
||||||
if test "$enable_framework"
|
if test "$enable_framework"
|
||||||
then
|
then
|
||||||
LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
|
LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
|
||||||
RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
|
RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}}
|
||||||
BLDLIBRARY=''
|
BLDLIBRARY=''
|
||||||
else
|
else
|
||||||
BLDLIBRARY='$(LDLIBRARY)'
|
BLDLIBRARY='$(LDLIBRARY)'
|
||||||
|
@ -5625,7 +5625,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
|
||||||
SunOS*)
|
SunOS*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).so'
|
LDLIBRARY='libpython$(LDVERSION).so'
|
||||||
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
|
RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
|
||||||
INSTSONAME="$LDLIBRARY".$SOVERSION
|
INSTSONAME="$LDLIBRARY".$SOVERSION
|
||||||
if test "$with_pydebug" != yes
|
if test "$with_pydebug" != yes
|
||||||
then
|
then
|
||||||
|
@ -5635,7 +5635,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
|
||||||
Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
|
Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).so'
|
LDLIBRARY='libpython$(LDVERSION).so'
|
||||||
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
|
RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
|
||||||
case $ac_sys_system in
|
case $ac_sys_system in
|
||||||
FreeBSD*)
|
FreeBSD*)
|
||||||
SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
|
SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
|
||||||
|
@ -5657,16 +5657,16 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
|
RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}}
|
||||||
;;
|
;;
|
||||||
Darwin*)
|
Darwin*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).dylib'
|
LDLIBRARY='libpython$(LDVERSION).dylib'
|
||||||
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
|
RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}
|
||||||
;;
|
;;
|
||||||
AIX*)
|
AIX*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).so'
|
LDLIBRARY='libpython$(LDVERSION).so'
|
||||||
RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
|
RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
12
configure.ac
12
configure.ac
|
@ -928,7 +928,7 @@ AC_MSG_CHECKING(LDLIBRARY)
|
||||||
if test "$enable_framework"
|
if test "$enable_framework"
|
||||||
then
|
then
|
||||||
LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
|
LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
|
||||||
RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
|
RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}}
|
||||||
BLDLIBRARY=''
|
BLDLIBRARY=''
|
||||||
else
|
else
|
||||||
BLDLIBRARY='$(LDLIBRARY)'
|
BLDLIBRARY='$(LDLIBRARY)'
|
||||||
|
@ -946,7 +946,7 @@ if test $enable_shared = "yes"; then
|
||||||
SunOS*)
|
SunOS*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).so'
|
LDLIBRARY='libpython$(LDVERSION).so'
|
||||||
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
|
RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
|
||||||
INSTSONAME="$LDLIBRARY".$SOVERSION
|
INSTSONAME="$LDLIBRARY".$SOVERSION
|
||||||
if test "$with_pydebug" != yes
|
if test "$with_pydebug" != yes
|
||||||
then
|
then
|
||||||
|
@ -956,7 +956,7 @@ if test $enable_shared = "yes"; then
|
||||||
Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
|
Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).so'
|
LDLIBRARY='libpython$(LDVERSION).so'
|
||||||
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
|
RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
|
||||||
case $ac_sys_system in
|
case $ac_sys_system in
|
||||||
FreeBSD*)
|
FreeBSD*)
|
||||||
SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
|
SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
|
||||||
|
@ -978,16 +978,16 @@ if test $enable_shared = "yes"; then
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
|
RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}}
|
||||||
;;
|
;;
|
||||||
Darwin*)
|
Darwin*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).dylib'
|
LDLIBRARY='libpython$(LDVERSION).dylib'
|
||||||
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
||||||
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
|
RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}
|
||||||
;;
|
;;
|
||||||
AIX*)
|
AIX*)
|
||||||
LDLIBRARY='libpython$(LDVERSION).so'
|
LDLIBRARY='libpython$(LDVERSION).so'
|
||||||
RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
|
RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
Loading…
Reference in New Issue