mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
merge heads
This commit is contained in:
commit
1f7df8f207
55 changed files with 768 additions and 220 deletions
|
@ -469,6 +469,10 @@ In the unlikely case that you care about Python versions older than 2.0, use
|
||||||
apply(g, (x,)+args, kwargs)
|
apply(g, (x,)+args, kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
single: argument; difference from parameter
|
||||||
|
single: parameter; difference from argument
|
||||||
|
|
||||||
.. _faq-argument-vs-parameter:
|
.. _faq-argument-vs-parameter:
|
||||||
|
|
||||||
What is the difference between arguments and parameters?
|
What is the difference between arguments and parameters?
|
||||||
|
|
|
@ -245,8 +245,9 @@ Glossary
|
||||||
|
|
||||||
function
|
function
|
||||||
A series of statements which returns some value to a caller. It can also
|
A series of statements which returns some value to a caller. It can also
|
||||||
be passed zero or more arguments which may be used in the execution of
|
be passed zero or more :term:`arguments <argument>` which may be used in
|
||||||
the body. See also :term:`argument` and :term:`method`.
|
the execution of the body. See also :term:`parameter`, :term:`method`,
|
||||||
|
and the :ref:`function` section.
|
||||||
|
|
||||||
__future__
|
__future__
|
||||||
A pseudo-module which programmers can use to enable new language features
|
A pseudo-module which programmers can use to enable new language features
|
||||||
|
|
|
@ -359,9 +359,9 @@ for a complete listing.
|
||||||
+------------------+-----------------------------------------------+
|
+------------------+-----------------------------------------------+
|
||||||
|
|
||||||
:meth:`match` and :meth:`search` return ``None`` if no match can be found. If
|
:meth:`match` and :meth:`search` return ``None`` if no match can be found. If
|
||||||
they're successful, a ``MatchObject`` instance is returned, containing
|
they're successful, a :ref:`match object <match-objects>` instance is returned,
|
||||||
information about the match: where it starts and ends, the substring it matched,
|
containing information about the match: where it starts and ends, the substring
|
||||||
and more.
|
it matched, and more.
|
||||||
|
|
||||||
You can learn about this by interactively experimenting with the :mod:`re`
|
You can learn about this by interactively experimenting with the :mod:`re`
|
||||||
module. If you have Tkinter available, you may also want to look at
|
module. If you have Tkinter available, you may also want to look at
|
||||||
|
@ -392,16 +392,16 @@ interpreter to print no output. You can explicitly print the result of
|
||||||
None
|
None
|
||||||
|
|
||||||
Now, let's try it on a string that it should match, such as ``tempo``. In this
|
Now, let's try it on a string that it should match, such as ``tempo``. In this
|
||||||
case, :meth:`match` will return a :class:`MatchObject`, so you should store the
|
case, :meth:`match` will return a :ref:`match object <match-objects>`, so you
|
||||||
result in a variable for later use. ::
|
should store the result in a variable for later use. ::
|
||||||
|
|
||||||
>>> m = p.match('tempo')
|
>>> m = p.match('tempo')
|
||||||
>>> m #doctest: +ELLIPSIS
|
>>> m #doctest: +ELLIPSIS
|
||||||
<_sre.SRE_Match object at 0x...>
|
<_sre.SRE_Match object at 0x...>
|
||||||
|
|
||||||
Now you can query the :class:`MatchObject` for information about the matching
|
Now you can query the :ref:`match object <match-objects>` for information
|
||||||
string. :class:`MatchObject` instances also have several methods and
|
about the matching string. :ref:`match object <match-objects>` instances
|
||||||
attributes; the most important ones are:
|
also have several methods and attributes; the most important ones are:
|
||||||
|
|
||||||
+------------------+--------------------------------------------+
|
+------------------+--------------------------------------------+
|
||||||
| Method/Attribute | Purpose |
|
| Method/Attribute | Purpose |
|
||||||
|
@ -442,8 +442,9 @@ case. ::
|
||||||
>>> m.span()
|
>>> m.span()
|
||||||
(4, 11)
|
(4, 11)
|
||||||
|
|
||||||
In actual programs, the most common style is to store the :class:`MatchObject`
|
In actual programs, the most common style is to store the
|
||||||
in a variable, and then check if it was ``None``. This usually looks like::
|
:ref:`match object <match-objects>` in a variable, and then check if it was
|
||||||
|
``None``. This usually looks like::
|
||||||
|
|
||||||
p = re.compile( ... )
|
p = re.compile( ... )
|
||||||
m = p.match( 'string goes here' )
|
m = p.match( 'string goes here' )
|
||||||
|
@ -460,8 +461,8 @@ Two pattern methods return all of the matches for a pattern.
|
||||||
['12', '11', '10']
|
['12', '11', '10']
|
||||||
|
|
||||||
:meth:`findall` has to create the entire list before it can be returned as the
|
:meth:`findall` has to create the entire list before it can be returned as the
|
||||||
result. The :meth:`finditer` method returns a sequence of :class:`MatchObject`
|
result. The :meth:`finditer` method returns a sequence of
|
||||||
instances as an :term:`iterator`. [#]_ ::
|
:ref:`match object <match-objects>` instances as an :term:`iterator`. [#]_ ::
|
||||||
|
|
||||||
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
|
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
|
||||||
>>> iterator #doctest: +ELLIPSIS
|
>>> iterator #doctest: +ELLIPSIS
|
||||||
|
@ -482,7 +483,7 @@ You don't have to create a pattern object and call its methods; the
|
||||||
:func:`search`, :func:`findall`, :func:`sub`, and so forth. These functions
|
:func:`search`, :func:`findall`, :func:`sub`, and so forth. These functions
|
||||||
take the same arguments as the corresponding pattern method, with
|
take the same arguments as the corresponding pattern method, with
|
||||||
the RE string added as the first argument, and still return either ``None`` or a
|
the RE string added as the first argument, and still return either ``None`` or a
|
||||||
:class:`MatchObject` instance. ::
|
:ref:`match object <match-objects>` instance. ::
|
||||||
|
|
||||||
>>> print re.match(r'From\s+', 'Fromage amk')
|
>>> print re.match(r'From\s+', 'Fromage amk')
|
||||||
None
|
None
|
||||||
|
@ -791,9 +792,9 @@ Groups indicated with ``'('``, ``')'`` also capture the starting and ending
|
||||||
index of the text that they match; this can be retrieved by passing an argument
|
index of the text that they match; this can be retrieved by passing an argument
|
||||||
to :meth:`group`, :meth:`start`, :meth:`end`, and :meth:`span`. Groups are
|
to :meth:`group`, :meth:`start`, :meth:`end`, and :meth:`span`. Groups are
|
||||||
numbered starting with 0. Group 0 is always present; it's the whole RE, so
|
numbered starting with 0. Group 0 is always present; it's the whole RE, so
|
||||||
:class:`MatchObject` methods all have group 0 as their default argument. Later
|
:ref:`match object <match-objects>` methods all have group 0 as their default
|
||||||
we'll see how to express groups that don't capture the span of text that they
|
argument. Later we'll see how to express groups that don't capture the span
|
||||||
match. ::
|
of text that they match. ::
|
||||||
|
|
||||||
>>> p = re.compile('(a)b')
|
>>> p = re.compile('(a)b')
|
||||||
>>> m = p.match('ab')
|
>>> m = p.match('ab')
|
||||||
|
@ -913,10 +914,10 @@ numbers, groups can be referenced by a name.
|
||||||
The syntax for a named group is one of the Python-specific extensions:
|
The syntax for a named group is one of the Python-specific extensions:
|
||||||
``(?P<name>...)``. *name* is, obviously, the name of the group. Named groups
|
``(?P<name>...)``. *name* is, obviously, the name of the group. Named groups
|
||||||
also behave exactly like capturing groups, and additionally associate a name
|
also behave exactly like capturing groups, and additionally associate a name
|
||||||
with a group. The :class:`MatchObject` methods that deal with capturing groups
|
with a group. The :ref:`match object <match-objects>` methods that deal with
|
||||||
all accept either integers that refer to the group by number or strings that
|
capturing groups all accept either integers that refer to the group by number
|
||||||
contain the desired group's name. Named groups are still given numbers, so you
|
or strings that contain the desired group's name. Named groups are still
|
||||||
can retrieve information about a group in two ways::
|
given numbers, so you can retrieve information about a group in two ways::
|
||||||
|
|
||||||
>>> p = re.compile(r'(?P<word>\b\w+\b)')
|
>>> p = re.compile(r'(?P<word>\b\w+\b)')
|
||||||
>>> m = p.search( '(((( Lots of punctuation )))' )
|
>>> m = p.search( '(((( Lots of punctuation )))' )
|
||||||
|
@ -1181,8 +1182,8 @@ three variations of the replacement string. ::
|
||||||
*replacement* can also be a function, which gives you even more control. If
|
*replacement* can also be a function, which gives you even more control. If
|
||||||
*replacement* is a function, the function is called for every non-overlapping
|
*replacement* is a function, the function is called for every non-overlapping
|
||||||
occurrence of *pattern*. On each call, the function is passed a
|
occurrence of *pattern*. On each call, the function is passed a
|
||||||
:class:`MatchObject` argument for the match and can use this information to
|
:ref:`match object <match-objects>` argument for the match and can use this
|
||||||
compute the desired replacement string and return it.
|
information to compute the desired replacement string and return it.
|
||||||
|
|
||||||
In the following example, the replacement function translates decimals into
|
In the following example, the replacement function translates decimals into
|
||||||
hexadecimal::
|
hexadecimal::
|
||||||
|
|
|
@ -1439,7 +1439,7 @@ Sub-commands
|
||||||
different functions which require different kinds of command-line arguments.
|
different functions which require different kinds of command-line arguments.
|
||||||
:class:`ArgumentParser` supports the creation of such sub-commands with the
|
:class:`ArgumentParser` supports the creation of such sub-commands with the
|
||||||
:meth:`add_subparsers` method. The :meth:`add_subparsers` method is normally
|
:meth:`add_subparsers` method. The :meth:`add_subparsers` method is normally
|
||||||
called with no arguments and returns an special action object. This object
|
called with no arguments and returns a special action object. This object
|
||||||
has a single method, :meth:`~ArgumentParser.add_parser`, which takes a
|
has a single method, :meth:`~ArgumentParser.add_parser`, which takes a
|
||||||
command name and any :class:`ArgumentParser` constructor arguments, and
|
command name and any :class:`ArgumentParser` constructor arguments, and
|
||||||
returns an :class:`ArgumentParser` object that can be modified as usual.
|
returns an :class:`ArgumentParser` object that can be modified as usual.
|
||||||
|
|
|
@ -370,10 +370,10 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
|
||||||
.. method:: FTP.close()
|
.. method:: FTP.close()
|
||||||
|
|
||||||
Close the connection unilaterally. This should not be applied to an already
|
Close the connection unilaterally. This should not be applied to an already
|
||||||
closed connection such as after a successful call to :meth:`quit`. After this
|
closed connection such as after a successful call to :meth:`~FTP.quit`.
|
||||||
call the :class:`FTP` instance should not be used any more (after a call to
|
After this call the :class:`FTP` instance should not be used any more (after
|
||||||
:meth:`close` or :meth:`quit` you cannot reopen the connection by issuing
|
a call to :meth:`close` or :meth:`~FTP.quit` you cannot reopen the
|
||||||
another :meth:`login` method).
|
connection by issuing another :meth:`login` method).
|
||||||
|
|
||||||
|
|
||||||
FTP_TLS Objects
|
FTP_TLS Objects
|
||||||
|
|
|
@ -106,9 +106,8 @@ loops that truncate the stream.
|
||||||
.. classmethod:: chain.from_iterable(iterable)
|
.. classmethod:: chain.from_iterable(iterable)
|
||||||
|
|
||||||
Alternate constructor for :func:`chain`. Gets chained inputs from a
|
Alternate constructor for :func:`chain`. Gets chained inputs from a
|
||||||
single iterable argument that is evaluated lazily. Equivalent to::
|
single iterable argument that is evaluated lazily. Roughly equivalent to::
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_iterable(iterables):
|
def from_iterable(iterables):
|
||||||
# chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
|
# chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
|
||||||
for it in iterables:
|
for it in iterables:
|
||||||
|
|
|
@ -102,7 +102,7 @@ An :class:`POP3` instance has the following methods:
|
||||||
.. method:: POP3.pass_(password)
|
.. method:: POP3.pass_(password)
|
||||||
|
|
||||||
Send password, response includes message count and mailbox size. Note: the
|
Send password, response includes message count and mailbox size. Note: the
|
||||||
mailbox on the server is locked until :meth:`quit` is called.
|
mailbox on the server is locked until :meth:`~poplib.quit` is called.
|
||||||
|
|
||||||
|
|
||||||
.. method:: POP3.apop(user, secret)
|
.. method:: POP3.apop(user, secret)
|
||||||
|
|
|
@ -32,7 +32,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
|
||||||
setting will be used).
|
setting will be used).
|
||||||
|
|
||||||
For normal use, you should only require the initialization/connect,
|
For normal use, you should only require the initialization/connect,
|
||||||
:meth:`sendmail`, and :meth:`quit` methods. An example is included below.
|
:meth:`sendmail`, and :meth:`~smtplib.quit` methods.
|
||||||
|
An example is included below.
|
||||||
|
|
||||||
.. versionchanged:: 2.6
|
.. versionchanged:: 2.6
|
||||||
*timeout* was added.
|
*timeout* was added.
|
||||||
|
|
|
@ -230,7 +230,7 @@ The module :mod:`socket` exports the following constants and functions:
|
||||||
*source_address* was added.
|
*source_address* was added.
|
||||||
|
|
||||||
|
|
||||||
.. function:: getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0)
|
.. function:: getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])
|
||||||
|
|
||||||
Translate the *host*/*port* argument into a sequence of 5-tuples that contain
|
Translate the *host*/*port* argument into a sequence of 5-tuples that contain
|
||||||
all the necessary arguments for creating a socket connected to that service.
|
all the necessary arguments for creating a socket connected to that service.
|
||||||
|
@ -240,12 +240,12 @@ The module :mod:`socket` exports the following constants and functions:
|
||||||
and *port*, you can pass ``NULL`` to the underlying C API.
|
and *port*, you can pass ``NULL`` to the underlying C API.
|
||||||
|
|
||||||
The *family*, *socktype* and *proto* arguments can be optionally specified
|
The *family*, *socktype* and *proto* arguments can be optionally specified
|
||||||
in order to narrow the list of addresses returned. Passing zero as a
|
in order to narrow the list of addresses returned. By default, their value
|
||||||
value for each of these arguments selects the full range of results.
|
is ``0``, meaning that the full range of results is selected.
|
||||||
The *flags* argument can be one or several of the ``AI_*`` constants,
|
The *flags* argument can be one or several of the ``AI_*`` constants,
|
||||||
and will influence how results are computed and returned.
|
and will influence how results are computed and returned. Its default value
|
||||||
For example, :const:`AI_NUMERICHOST` will disable domain name resolution
|
is ``0``. For example, :const:`AI_NUMERICHOST` will disable domain name
|
||||||
and will raise an error if *host* is a domain name.
|
resolution and will raise an error if *host* is a domain name.
|
||||||
|
|
||||||
The function returns a list of 5-tuples with the following structure:
|
The function returns a list of 5-tuples with the following structure:
|
||||||
|
|
||||||
|
|
|
@ -306,8 +306,8 @@ request.
|
||||||
.. method:: RequestHandler.finish()
|
.. method:: RequestHandler.finish()
|
||||||
|
|
||||||
Called after the :meth:`handle` method to perform any clean-up actions
|
Called after the :meth:`handle` method to perform any clean-up actions
|
||||||
required. The default implementation does nothing. If :meth:`setup` or
|
required. The default implementation does nothing. If :meth:`setup`
|
||||||
:meth:`handle` raise an exception, this function will not be called.
|
raises an exception, this function will not be called.
|
||||||
|
|
||||||
|
|
||||||
.. method:: RequestHandler.handle()
|
.. method:: RequestHandler.handle()
|
||||||
|
|
|
@ -407,6 +407,9 @@ is equivalent to ::
|
||||||
statement.
|
statement.
|
||||||
|
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
single: parameter; function definition
|
||||||
|
|
||||||
.. _function:
|
.. _function:
|
||||||
.. _def:
|
.. _def:
|
||||||
|
|
||||||
|
@ -467,12 +470,15 @@ is equivalent to::
|
||||||
def func(): pass
|
def func(): pass
|
||||||
func = f1(arg)(f2(func))
|
func = f1(arg)(f2(func))
|
||||||
|
|
||||||
.. index:: triple: default; parameter; value
|
.. index::
|
||||||
|
triple: default; parameter; value
|
||||||
|
single: argument; function definition
|
||||||
|
|
||||||
When one or more top-level parameters have the form *parameter* ``=``
|
When one or more top-level :term:`parameters <parameter>` have the form
|
||||||
*expression*, the function is said to have "default parameter values." For a
|
*parameter* ``=`` *expression*, the function is said to have "default parameter
|
||||||
parameter with a default value, the corresponding argument may be omitted from a
|
values." For a parameter with a default value, the corresponding
|
||||||
call, in which case the parameter's default value is substituted. If a
|
:term:`argument` may be omitted from a call, in which
|
||||||
|
case the parameter's default value is substituted. If a
|
||||||
parameter has a default value, all following parameters must also have a default
|
parameter has a default value, all following parameters must also have a default
|
||||||
value --- this is a syntactic restriction that is not expressed by the grammar.
|
value --- this is a syntactic restriction that is not expressed by the grammar.
|
||||||
|
|
||||||
|
|
|
@ -667,17 +667,18 @@ upper bound and stride, respectively, substituting ``None`` for missing
|
||||||
expressions.
|
expressions.
|
||||||
|
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
object: callable
|
||||||
|
single: call
|
||||||
|
single: argument; call semantics
|
||||||
|
|
||||||
.. _calls:
|
.. _calls:
|
||||||
|
|
||||||
Calls
|
Calls
|
||||||
-----
|
-----
|
||||||
|
|
||||||
.. index:: single: call
|
A call calls a callable object (e.g., a :term:`function`) with a possibly empty
|
||||||
|
series of :term:`arguments <argument>`:
|
||||||
.. index:: object: callable
|
|
||||||
|
|
||||||
A call calls a callable object (e.g., a function) with a possibly empty series
|
|
||||||
of arguments:
|
|
||||||
|
|
||||||
.. productionlist::
|
.. productionlist::
|
||||||
call: `primary` "(" [`argument_list` [","]
|
call: `primary` "(" [`argument_list` [","]
|
||||||
|
@ -696,12 +697,15 @@ of arguments:
|
||||||
A trailing comma may be present after the positional and keyword arguments but
|
A trailing comma may be present after the positional and keyword arguments but
|
||||||
does not affect the semantics.
|
does not affect the semantics.
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
single: parameter; call semantics
|
||||||
|
|
||||||
The primary must evaluate to a callable object (user-defined functions, built-in
|
The primary must evaluate to a callable object (user-defined functions, built-in
|
||||||
functions, methods of built-in objects, class objects, methods of class
|
functions, methods of built-in objects, class objects, methods of class
|
||||||
instances, and certain class instances themselves are callable; extensions may
|
instances, and certain class instances themselves are callable; extensions may
|
||||||
define additional callable object types). All argument expressions are
|
define additional callable object types). All argument expressions are
|
||||||
evaluated before the call is attempted. Please refer to section :ref:`function`
|
evaluated before the call is attempted. Please refer to section :ref:`function`
|
||||||
for the syntax of formal parameter lists.
|
for the syntax of formal :term:`parameter` lists.
|
||||||
|
|
||||||
If keyword arguments are present, they are first converted to positional
|
If keyword arguments are present, they are first converted to positional
|
||||||
arguments, as follows. First, a list of unfilled slots is created for the
|
arguments, as follows. First, a list of unfilled slots is created for the
|
||||||
|
@ -1339,8 +1343,8 @@ their suffixes::
|
||||||
|
|
||||||
.. _operator-summary:
|
.. _operator-summary:
|
||||||
|
|
||||||
Summary
|
Operator precedence
|
||||||
=======
|
===================
|
||||||
|
|
||||||
.. index:: pair: operator; precedence
|
.. index:: pair: operator; precedence
|
||||||
|
|
||||||
|
@ -1363,9 +1367,9 @@ groups from right to left).
|
||||||
+-----------------------------------------------+-------------------------------------+
|
+-----------------------------------------------+-------------------------------------+
|
||||||
| :keyword:`and` | Boolean AND |
|
| :keyword:`and` | Boolean AND |
|
||||||
+-----------------------------------------------+-------------------------------------+
|
+-----------------------------------------------+-------------------------------------+
|
||||||
| :keyword:`not` *x* | Boolean NOT |
|
| :keyword:`not` ``x`` | Boolean NOT |
|
||||||
+-----------------------------------------------+-------------------------------------+
|
+-----------------------------------------------+-------------------------------------+
|
||||||
| :keyword:`in`, :keyword:`not` :keyword:`in`, | Comparisons, including membership |
|
| :keyword:`in`, :keyword:`not in`, | Comparisons, including membership |
|
||||||
| :keyword:`is`, :keyword:`is not`, ``<``, | tests and identity tests, |
|
| :keyword:`is`, :keyword:`is not`, ``<``, | tests and identity tests, |
|
||||||
| ``<=``, ``>``, ``>=``, ``<>``, ``!=``, ``==`` | |
|
| ``<=``, ``>``, ``>=``, ``<>``, ``!=``, ``==`` | |
|
||||||
+-----------------------------------------------+-------------------------------------+
|
+-----------------------------------------------+-------------------------------------+
|
||||||
|
@ -1391,7 +1395,7 @@ groups from right to left).
|
||||||
+-----------------------------------------------+-------------------------------------+
|
+-----------------------------------------------+-------------------------------------+
|
||||||
| ``(expressions...)``, | Binding or tuple display, |
|
| ``(expressions...)``, | Binding or tuple display, |
|
||||||
| ``[expressions...]``, | list display, |
|
| ``[expressions...]``, | list display, |
|
||||||
| ``{key:datum...}``, | dictionary display, |
|
| ``{key: value...}``, | dictionary display, |
|
||||||
| ```expressions...``` | string conversion |
|
| ```expressions...``` | string conversion |
|
||||||
+-----------------------------------------------+-------------------------------------+
|
+-----------------------------------------------+-------------------------------------+
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ In order to run Python flawlessly, you might have to change certain environment
|
||||||
settings in Windows.
|
settings in Windows.
|
||||||
|
|
||||||
|
|
||||||
|
.. _setting-envvars:
|
||||||
|
|
||||||
Excursus: Setting environment variables
|
Excursus: Setting environment variables
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -701,7 +701,12 @@ class StreamRequestHandler(BaseRequestHandler):
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
if not self.wfile.closed:
|
if not self.wfile.closed:
|
||||||
|
try:
|
||||||
self.wfile.flush()
|
self.wfile.flush()
|
||||||
|
except socket.error:
|
||||||
|
# An final socket error may have occurred here, such as
|
||||||
|
# the local error ECONNABORTED.
|
||||||
|
pass
|
||||||
self.wfile.close()
|
self.wfile.close()
|
||||||
self.rfile.close()
|
self.rfile.close()
|
||||||
|
|
||||||
|
|
|
@ -732,6 +732,9 @@ class Aifc_write:
|
||||||
self._patchheader()
|
self._patchheader()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
if self._file is None:
|
||||||
|
return
|
||||||
|
try:
|
||||||
self._ensure_header_written(0)
|
self._ensure_header_written(0)
|
||||||
if self._datawritten & 1:
|
if self._datawritten & 1:
|
||||||
# quick pad to even size
|
# quick pad to even size
|
||||||
|
@ -745,9 +748,12 @@ class Aifc_write:
|
||||||
if self._comp:
|
if self._comp:
|
||||||
self._comp.CloseCompressor()
|
self._comp.CloseCompressor()
|
||||||
self._comp = None
|
self._comp = None
|
||||||
|
finally:
|
||||||
# Prevent ref cycles
|
# Prevent ref cycles
|
||||||
self._convert = None
|
self._convert = None
|
||||||
self._file.close()
|
f = self._file
|
||||||
|
self._file = None
|
||||||
|
f.close()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Internal methods.
|
# Internal methods.
|
||||||
|
|
|
@ -37,7 +37,6 @@ __version__ = "2.6"
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import urllib
|
|
||||||
import UserDict
|
import UserDict
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
|
|
|
@ -246,9 +246,9 @@ class BitFieldTest(unittest.TestCase):
|
||||||
_fields_ = [("a", c_uint32, 32)]
|
_fields_ = [("a", c_uint32, 32)]
|
||||||
x = X()
|
x = X()
|
||||||
x.a = 10
|
x.a = 10
|
||||||
self.assertEquals(x.a, 10)
|
self.assertEqual(x.a, 10)
|
||||||
x.a = 0xFDCBA987
|
x.a = 0xFDCBA987
|
||||||
self.assertEquals(x.a, 0xFDCBA987)
|
self.assertEqual(x.a, 0xFDCBA987)
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required")
|
@unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required")
|
||||||
def test_uint64(self):
|
def test_uint64(self):
|
||||||
|
@ -256,9 +256,9 @@ class BitFieldTest(unittest.TestCase):
|
||||||
_fields_ = [("a", c_uint64, 64)]
|
_fields_ = [("a", c_uint64, 64)]
|
||||||
x = X()
|
x = X()
|
||||||
x.a = 10
|
x.a = 10
|
||||||
self.assertEquals(x.a, 10)
|
self.assertEqual(x.a, 10)
|
||||||
x.a = 0xFEDCBA9876543211
|
x.a = 0xFEDCBA9876543211
|
||||||
self.assertEquals(x.a, 0xFEDCBA9876543211)
|
self.assertEqual(x.a, 0xFEDCBA9876543211)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -5,7 +5,7 @@ the package, and perhaps a particular module inside it.
|
||||||
|
|
||||||
import curses
|
import curses
|
||||||
from curses import textpad
|
from curses import textpad
|
||||||
curses.initwin()
|
curses.initscr()
|
||||||
...
|
...
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -20,10 +20,11 @@ def make_pat():
|
||||||
# 1st 'file' colorized normal, 2nd as builtin, 3rd as string
|
# 1st 'file' colorized normal, 2nd as builtin, 3rd as string
|
||||||
builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
|
builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
|
||||||
comment = any("COMMENT", [r"#[^\n]*"])
|
comment = any("COMMENT", [r"#[^\n]*"])
|
||||||
sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
|
stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR)?"
|
||||||
dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
|
sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?"
|
||||||
sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
|
dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?'
|
||||||
dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
|
sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
|
||||||
|
dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
|
||||||
string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
|
string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
|
||||||
return kw + "|" + builtin + "|" + comment + "|" + string +\
|
return kw + "|" + builtin + "|" + comment + "|" + string +\
|
||||||
"|" + any("SYNC", [r"\n"])
|
"|" + any("SYNC", [r"\n"])
|
||||||
|
|
|
@ -172,13 +172,13 @@ class EditorWindow(object):
|
||||||
'recent-files.lst')
|
'recent-files.lst')
|
||||||
self.text_frame = text_frame = Frame(top)
|
self.text_frame = text_frame = Frame(top)
|
||||||
self.vbar = vbar = Scrollbar(text_frame, name='vbar')
|
self.vbar = vbar = Scrollbar(text_frame, name='vbar')
|
||||||
self.width = idleConf.GetOption('main','EditorWindow','width')
|
self.width = idleConf.GetOption('main','EditorWindow','width', type='int')
|
||||||
text_options = {
|
text_options = {
|
||||||
'name': 'text',
|
'name': 'text',
|
||||||
'padx': 5,
|
'padx': 5,
|
||||||
'wrap': 'none',
|
'wrap': 'none',
|
||||||
'width': self.width,
|
'width': self.width,
|
||||||
'height': idleConf.GetOption('main', 'EditorWindow', 'height')}
|
'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')}
|
||||||
if TkVersion >= 8.5:
|
if TkVersion >= 8.5:
|
||||||
# Starting with tk 8.5 we have to set the new tabstyle option
|
# Starting with tk 8.5 we have to set the new tabstyle option
|
||||||
# to 'wordprocessor' to achieve the same display of tabs as in
|
# to 'wordprocessor' to achieve the same display of tabs as in
|
||||||
|
@ -255,7 +255,8 @@ class EditorWindow(object):
|
||||||
if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
|
if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
|
||||||
fontWeight='bold'
|
fontWeight='bold'
|
||||||
text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
|
text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
|
||||||
idleConf.GetOption('main', 'EditorWindow', 'font-size'),
|
idleConf.GetOption('main', 'EditorWindow',
|
||||||
|
'font-size', type='int'),
|
||||||
fontWeight))
|
fontWeight))
|
||||||
text_frame.pack(side=LEFT, fill=BOTH, expand=1)
|
text_frame.pack(side=LEFT, fill=BOTH, expand=1)
|
||||||
text.pack(side=TOP, fill=BOTH, expand=1)
|
text.pack(side=TOP, fill=BOTH, expand=1)
|
||||||
|
@ -763,7 +764,8 @@ class EditorWindow(object):
|
||||||
if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
|
if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
|
||||||
fontWeight='bold'
|
fontWeight='bold'
|
||||||
self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'),
|
self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'),
|
||||||
idleConf.GetOption('main','EditorWindow','font-size'),
|
idleConf.GetOption('main','EditorWindow','font-size',
|
||||||
|
type='int'),
|
||||||
fontWeight))
|
fontWeight))
|
||||||
|
|
||||||
def RemoveKeybindings(self):
|
def RemoveKeybindings(self):
|
||||||
|
@ -1609,7 +1611,7 @@ class IndentSearcher(object):
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
_tokenize.tokenize(self.readline, self.tokeneater)
|
_tokenize.tokenize(self.readline, self.tokeneater)
|
||||||
except _tokenize.TokenError:
|
except (_tokenize.TokenError, SyntaxError):
|
||||||
# since we cut off the tokenizer early, we can trigger
|
# since we cut off the tokenizer early, we can trigger
|
||||||
# spurious errors
|
# spurious errors
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -32,7 +32,8 @@ class FormatParagraph:
|
||||||
self.editwin = None
|
self.editwin = None
|
||||||
|
|
||||||
def format_paragraph_event(self, event):
|
def format_paragraph_event(self, event):
|
||||||
maxformatwidth = int(idleConf.GetOption('main','FormatParagraph','paragraph'))
|
maxformatwidth = int(idleConf.GetOption('main','FormatParagraph',
|
||||||
|
'paragraph', type='int'))
|
||||||
text = self.editwin.text
|
text = self.editwin.text
|
||||||
first, last = self.editwin.get_selection_indices()
|
first, last = self.editwin.get_selection_indices()
|
||||||
if first and last:
|
if first and last:
|
||||||
|
|
|
@ -947,7 +947,7 @@ class ConfigDialog(Toplevel):
|
||||||
self.listFontName.select_anchor(currentFontIndex)
|
self.listFontName.select_anchor(currentFontIndex)
|
||||||
##font size dropdown
|
##font size dropdown
|
||||||
fontSize=idleConf.GetOption('main','EditorWindow','font-size',
|
fontSize=idleConf.GetOption('main','EditorWindow','font-size',
|
||||||
default='10')
|
type='int', default='10')
|
||||||
self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
|
self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
|
||||||
'16','18','20','22'),fontSize )
|
'16','18','20','22'),fontSize )
|
||||||
##fontWeight
|
##fontWeight
|
||||||
|
@ -1033,10 +1033,13 @@ class ConfigDialog(Toplevel):
|
||||||
self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave',
|
self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave',
|
||||||
default=0, type='bool'))
|
default=0, type='bool'))
|
||||||
#initial window size
|
#initial window size
|
||||||
self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
|
self.winWidth.set(idleConf.GetOption('main','EditorWindow','width',
|
||||||
self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
|
type='int'))
|
||||||
|
self.winHeight.set(idleConf.GetOption('main','EditorWindow','height',
|
||||||
|
type='int'))
|
||||||
#initial paragraph reformat size
|
#initial paragraph reformat size
|
||||||
self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph'))
|
self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph',
|
||||||
|
type='int'))
|
||||||
# default source encoding
|
# default source encoding
|
||||||
self.encoding.set(idleConf.GetOption('main', 'EditorWindow',
|
self.encoding.set(idleConf.GetOption('main', 'EditorWindow',
|
||||||
'encoding', default='none'))
|
'encoding', default='none'))
|
||||||
|
|
|
@ -237,13 +237,28 @@ class IdleConf:
|
||||||
printed to stderr.
|
printed to stderr.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
if self.userCfg[configType].has_option(section,option):
|
if self.userCfg[configType].has_option(section,option):
|
||||||
return self.userCfg[configType].Get(section, option,
|
return self.userCfg[configType].Get(section, option,
|
||||||
type=type, raw=raw)
|
type=type, raw=raw)
|
||||||
elif self.defaultCfg[configType].has_option(section,option):
|
except ValueError:
|
||||||
|
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
|
||||||
|
' invalid %r value for configuration option %r\n'
|
||||||
|
' from section %r: %r\n' %
|
||||||
|
(type, option, section,
|
||||||
|
self.userCfg[configType].Get(section, option,
|
||||||
|
raw=raw)))
|
||||||
|
try:
|
||||||
|
sys.stderr.write(warning)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
if self.defaultCfg[configType].has_option(section,option):
|
||||||
return self.defaultCfg[configType].Get(section, option,
|
return self.defaultCfg[configType].Get(section, option,
|
||||||
type=type, raw=raw)
|
type=type, raw=raw)
|
||||||
else: #returning default, print warning
|
except ValueError:
|
||||||
|
pass
|
||||||
|
#returning default, print warning
|
||||||
if warn_on_default:
|
if warn_on_default:
|
||||||
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
|
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
|
||||||
' problem retrieving configuration option %r\n'
|
' problem retrieving configuration option %r\n'
|
||||||
|
|
|
@ -200,6 +200,27 @@ if sys.platform != 'win32':
|
||||||
return c1, c2
|
return c1, c2
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
if hasattr(select, 'poll'):
|
||||||
|
def _poll(fds, timeout):
|
||||||
|
if timeout is not None:
|
||||||
|
timeout = int(timeout) * 1000 # timeout is in milliseconds
|
||||||
|
fd_map = {}
|
||||||
|
pollster = select.poll()
|
||||||
|
for fd in fds:
|
||||||
|
pollster.register(fd, select.POLLIN)
|
||||||
|
if hasattr(fd, 'fileno'):
|
||||||
|
fd_map[fd.fileno()] = fd
|
||||||
|
else:
|
||||||
|
fd_map[fd] = fd
|
||||||
|
ls = []
|
||||||
|
for fd, event in pollster.poll(timeout):
|
||||||
|
if event & select.POLLNVAL:
|
||||||
|
raise ValueError('invalid file descriptor %i' % fd)
|
||||||
|
ls.append(fd_map[fd])
|
||||||
|
return ls
|
||||||
|
else:
|
||||||
|
def _poll(fds, timeout):
|
||||||
|
return select.select(fds, [], [], timeout)[0]
|
||||||
|
|
||||||
from _multiprocessing import win32
|
from _multiprocessing import win32
|
||||||
|
|
||||||
|
|
|
@ -319,8 +319,8 @@ class _fileobject(object):
|
||||||
self._wbuf.append(data)
|
self._wbuf.append(data)
|
||||||
self._wbuf_len += len(data)
|
self._wbuf_len += len(data)
|
||||||
if (self._wbufsize == 0 or
|
if (self._wbufsize == 0 or
|
||||||
self._wbufsize == 1 and '\n' in data or
|
(self._wbufsize == 1 and '\n' in data) or
|
||||||
self._wbuf_len >= self._wbufsize):
|
(self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)):
|
||||||
self.flush()
|
self.flush()
|
||||||
|
|
||||||
def writelines(self, list):
|
def writelines(self, list):
|
||||||
|
|
16
Lib/ssl.py
16
Lib/ssl.py
|
@ -313,17 +313,19 @@ class SSLSocket(socket):
|
||||||
self.cert_reqs, self.ssl_version,
|
self.cert_reqs, self.ssl_version,
|
||||||
self.ca_certs, self.ciphers)
|
self.ca_certs, self.ciphers)
|
||||||
try:
|
try:
|
||||||
|
if return_errno:
|
||||||
|
rc = socket.connect_ex(self, addr)
|
||||||
|
else:
|
||||||
|
rc = None
|
||||||
socket.connect(self, addr)
|
socket.connect(self, addr)
|
||||||
|
if not rc:
|
||||||
if self.do_handshake_on_connect:
|
if self.do_handshake_on_connect:
|
||||||
self.do_handshake()
|
self.do_handshake()
|
||||||
except socket_error as e:
|
|
||||||
if return_errno:
|
|
||||||
return e.errno
|
|
||||||
else:
|
|
||||||
self._sslobj = None
|
|
||||||
raise e
|
|
||||||
self._connected = True
|
self._connected = True
|
||||||
return 0
|
return rc
|
||||||
|
except socket_error:
|
||||||
|
self._sslobj = None
|
||||||
|
raise
|
||||||
|
|
||||||
def connect(self, addr):
|
def connect(self, addr):
|
||||||
"""Connects to remote ADDR, and then wraps the connection in
|
"""Connects to remote ADDR, and then wraps the connection in
|
||||||
|
|
|
@ -1292,7 +1292,7 @@ class Popen(object):
|
||||||
|
|
||||||
|
|
||||||
def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,
|
def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,
|
||||||
_WNOHANG=os.WNOHANG, _os_error=os.error):
|
_WNOHANG=os.WNOHANG, _os_error=os.error, _ECHILD=errno.ECHILD):
|
||||||
"""Check if child process has terminated. Returns returncode
|
"""Check if child process has terminated. Returns returncode
|
||||||
attribute.
|
attribute.
|
||||||
|
|
||||||
|
@ -1308,7 +1308,7 @@ class Popen(object):
|
||||||
except _os_error as e:
|
except _os_error as e:
|
||||||
if _deadstate is not None:
|
if _deadstate is not None:
|
||||||
self.returncode = _deadstate
|
self.returncode = _deadstate
|
||||||
if e.errno == errno.ECHILD:
|
if e.errno == _ECHILD:
|
||||||
# This happens if SIGCLD is set to be ignored or
|
# This happens if SIGCLD is set to be ignored or
|
||||||
# waiting for child processes has otherwise been
|
# waiting for child processes has otherwise been
|
||||||
# disabled for our process. This child is dead, we
|
# disabled for our process. This child is dead, we
|
||||||
|
|
|
@ -32,7 +32,7 @@ Verbosity
|
||||||
|
|
||||||
Selecting tests
|
Selecting tests
|
||||||
|
|
||||||
-r/--random -- randomize test execution order (see below)
|
-r/--randomize -- randomize test execution order (see below)
|
||||||
--randseed -- pass a random seed to reproduce a previous random run
|
--randseed -- pass a random seed to reproduce a previous random run
|
||||||
-f/--fromfile -- read names of tests to run from a file (see below)
|
-f/--fromfile -- read names of tests to run from a file (see below)
|
||||||
-x/--exclude -- arguments are tests to *exclude*
|
-x/--exclude -- arguments are tests to *exclude*
|
||||||
|
@ -258,7 +258,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:',
|
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:',
|
||||||
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
|
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
|
||||||
'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks',
|
'exclude', 'single', 'slow', 'randomize', 'fromfile=', 'findleaks',
|
||||||
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
|
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
|
||||||
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
|
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
|
||||||
'multiprocess=', 'slaveargs=', 'forever', 'header'])
|
'multiprocess=', 'slaveargs=', 'forever', 'header'])
|
||||||
|
|
|
@ -106,6 +106,13 @@ class AIFCTest(unittest.TestCase):
|
||||||
self.assertEqual(testfile.closed, False)
|
self.assertEqual(testfile.closed, False)
|
||||||
f.close()
|
f.close()
|
||||||
self.assertEqual(testfile.closed, True)
|
self.assertEqual(testfile.closed, True)
|
||||||
|
testfile = open(TESTFN, 'wb')
|
||||||
|
fout = aifc.open(testfile, 'wb')
|
||||||
|
self.assertFalse(testfile.closed)
|
||||||
|
with self.assertRaises(aifc.Error):
|
||||||
|
fout.close()
|
||||||
|
self.assertTrue(testfile.closed)
|
||||||
|
fout.close() # do nothing
|
||||||
|
|
||||||
|
|
||||||
class AIFCLowLevelTest(unittest.TestCase):
|
class AIFCLowLevelTest(unittest.TestCase):
|
||||||
|
|
|
@ -680,6 +680,8 @@ class BuiltinTest(unittest.TestCase):
|
||||||
|
|
||||||
# Test input() later, together with raw_input
|
# Test input() later, together with raw_input
|
||||||
|
|
||||||
|
# test_int(): see test_int.py for int() tests.
|
||||||
|
|
||||||
def test_intern(self):
|
def test_intern(self):
|
||||||
self.assertRaises(TypeError, intern)
|
self.assertRaises(TypeError, intern)
|
||||||
# This fails if the test is run twice with a constant string,
|
# This fails if the test is run twice with a constant string,
|
||||||
|
|
|
@ -261,7 +261,7 @@ class CalendarTestCase(unittest.TestCase):
|
||||||
return
|
return
|
||||||
calendar.LocaleHTMLCalendar(locale='').formatmonthname(2010, 10)
|
calendar.LocaleHTMLCalendar(locale='').formatmonthname(2010, 10)
|
||||||
new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
|
new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
|
||||||
self.assertEquals(old_october, new_october)
|
self.assertEqual(old_october, new_october)
|
||||||
|
|
||||||
def test_itermonthdates(self):
|
def test_itermonthdates(self):
|
||||||
# ensure itermonthdates doesn't overflow after datetime.MAXYEAR
|
# ensure itermonthdates doesn't overflow after datetime.MAXYEAR
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import unittest
|
|
||||||
from test.test_support import run_unittest, TESTFN
|
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from test.test_support import run_unittest, TESTFN
|
||||||
|
|
||||||
|
|
||||||
|
def fsdecode(s):
|
||||||
|
return unicode(s, sys.getfilesystemencoding())
|
||||||
|
|
||||||
|
|
||||||
class GlobTests(unittest.TestCase):
|
class GlobTests(unittest.TestCase):
|
||||||
|
@ -31,7 +36,8 @@ class GlobTests(unittest.TestCase):
|
||||||
self.mktemp('a', 'bcd', 'efg', 'ha')
|
self.mktemp('a', 'bcd', 'efg', 'ha')
|
||||||
if hasattr(os, 'symlink'):
|
if hasattr(os, 'symlink'):
|
||||||
os.symlink(self.norm('broken'), self.norm('sym1'))
|
os.symlink(self.norm('broken'), self.norm('sym1'))
|
||||||
os.symlink(self.norm('broken'), self.norm('sym2'))
|
os.symlink('broken', self.norm('sym2'))
|
||||||
|
os.symlink(os.path.join('a', 'bcd'), self.norm('sym3'))
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
shutil.rmtree(self.tempdir)
|
shutil.rmtree(self.tempdir)
|
||||||
|
@ -44,10 +50,16 @@ class GlobTests(unittest.TestCase):
|
||||||
p = os.path.join(self.tempdir, pattern)
|
p = os.path.join(self.tempdir, pattern)
|
||||||
res = glob.glob(p)
|
res = glob.glob(p)
|
||||||
self.assertEqual(list(glob.iglob(p)), res)
|
self.assertEqual(list(glob.iglob(p)), res)
|
||||||
|
ures = [fsdecode(x) for x in res]
|
||||||
|
self.assertEqual(glob.glob(fsdecode(p)), ures)
|
||||||
|
self.assertEqual(list(glob.iglob(fsdecode(p))), ures)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def assertSequencesEqual_noorder(self, l1, l2):
|
def assertSequencesEqual_noorder(self, l1, l2):
|
||||||
|
l1 = list(l1)
|
||||||
|
l2 = list(l2)
|
||||||
self.assertEqual(set(l1), set(l2))
|
self.assertEqual(set(l1), set(l2))
|
||||||
|
self.assertEqual(sorted(l1), sorted(l2))
|
||||||
|
|
||||||
def test_glob_literal(self):
|
def test_glob_literal(self):
|
||||||
eq = self.assertSequencesEqual_noorder
|
eq = self.assertSequencesEqual_noorder
|
||||||
|
@ -56,15 +68,19 @@ class GlobTests(unittest.TestCase):
|
||||||
eq(self.glob('aab'), [self.norm('aab')])
|
eq(self.glob('aab'), [self.norm('aab')])
|
||||||
eq(self.glob('zymurgy'), [])
|
eq(self.glob('zymurgy'), [])
|
||||||
|
|
||||||
|
res = glob.glob('*')
|
||||||
|
self.assertEqual({type(r) for r in res}, {str})
|
||||||
|
res = glob.glob(os.path.join(os.curdir, '*'))
|
||||||
|
self.assertEqual({type(r) for r in res}, {str})
|
||||||
|
|
||||||
# test return types are unicode, but only if os.listdir
|
# test return types are unicode, but only if os.listdir
|
||||||
# returns unicode filenames
|
# returns unicode filenames
|
||||||
uniset = set([unicode])
|
tmp = os.listdir(fsdecode(os.curdir))
|
||||||
tmp = os.listdir(u'.')
|
if {type(x) for x in tmp} == {unicode}:
|
||||||
if set(type(x) for x in tmp) == uniset:
|
res = glob.glob(u'*')
|
||||||
u1 = glob.glob(u'*')
|
self.assertEqual({type(r) for r in res}, {unicode})
|
||||||
u2 = glob.glob(u'./*')
|
res = glob.glob(os.path.join(fsdecode(os.curdir), u'*'))
|
||||||
self.assertEqual(set(type(r) for r in u1), uniset)
|
self.assertEqual({type(r) for r in res}, {unicode})
|
||||||
self.assertEqual(set(type(r) for r in u2), uniset)
|
|
||||||
|
|
||||||
def test_glob_one_directory(self):
|
def test_glob_one_directory(self):
|
||||||
eq = self.assertSequencesEqual_noorder
|
eq = self.assertSequencesEqual_noorder
|
||||||
|
@ -93,21 +109,58 @@ class GlobTests(unittest.TestCase):
|
||||||
eq(self.glob('*', '*a'), [])
|
eq(self.glob('*', '*a'), [])
|
||||||
eq(self.glob('a', '*', '*', '*a'),
|
eq(self.glob('a', '*', '*', '*a'),
|
||||||
[self.norm('a', 'bcd', 'efg', 'ha')])
|
[self.norm('a', 'bcd', 'efg', 'ha')])
|
||||||
eq(self.glob('?a?', '*F'), map(self.norm, [os.path.join('aaa', 'zzzF'),
|
eq(self.glob('?a?', '*F'), [self.norm('aaa', 'zzzF'),
|
||||||
os.path.join('aab', 'F')]))
|
self.norm('aab', 'F')])
|
||||||
|
|
||||||
def test_glob_directory_with_trailing_slash(self):
|
def test_glob_directory_with_trailing_slash(self):
|
||||||
# We are verifying that when there is wildcard pattern which
|
# Patterns ending with a slash shouldn't match non-dirs
|
||||||
# ends with os.sep doesn't blow up.
|
res = glob.glob(self.norm('Z*Z') + os.sep)
|
||||||
res = glob.glob(self.tempdir + '*' + os.sep)
|
self.assertEqual(res, [])
|
||||||
self.assertEqual(len(res), 1)
|
res = glob.glob(self.norm('ZZZ') + os.sep)
|
||||||
# either of these results are reasonable
|
self.assertEqual(res, [])
|
||||||
self.assertIn(res[0], [self.tempdir, self.tempdir + os.sep])
|
# When there is a wildcard pattern which ends with os.sep, glob()
|
||||||
|
# doesn't blow up.
|
||||||
|
res = glob.glob(self.norm('aa*') + os.sep)
|
||||||
|
self.assertEqual(len(res), 2)
|
||||||
|
# either of these results is reasonable
|
||||||
|
self.assertIn(set(res), [
|
||||||
|
{self.norm('aaa'), self.norm('aab')},
|
||||||
|
{self.norm('aaa') + os.sep, self.norm('aab') + os.sep},
|
||||||
|
])
|
||||||
|
|
||||||
def test_glob_broken_symlinks(self):
|
def test_glob_unicode_directory_with_trailing_slash(self):
|
||||||
if hasattr(os, 'symlink'):
|
# Same as test_glob_directory_with_trailing_slash, but with an
|
||||||
|
# unicode argument.
|
||||||
|
res = glob.glob(fsdecode(self.norm('Z*Z') + os.sep))
|
||||||
|
self.assertEqual(res, [])
|
||||||
|
res = glob.glob(fsdecode(self.norm('ZZZ') + os.sep))
|
||||||
|
self.assertEqual(res, [])
|
||||||
|
res = glob.glob(fsdecode(self.norm('aa*') + os.sep))
|
||||||
|
self.assertEqual(len(res), 2)
|
||||||
|
# either of these results is reasonable
|
||||||
|
self.assertIn(set(res), [
|
||||||
|
{fsdecode(self.norm('aaa')), fsdecode(self.norm('aab'))},
|
||||||
|
{fsdecode(self.norm('aaa') + os.sep),
|
||||||
|
fsdecode(self.norm('aab') + os.sep)},
|
||||||
|
])
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(os, 'symlink'), "Requires symlink support")
|
||||||
|
def test_glob_symlinks(self):
|
||||||
eq = self.assertSequencesEqual_noorder
|
eq = self.assertSequencesEqual_noorder
|
||||||
eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2')])
|
eq(self.glob('sym3'), [self.norm('sym3')])
|
||||||
|
eq(self.glob('sym3', '*'), [self.norm('sym3', 'EF'),
|
||||||
|
self.norm('sym3', 'efg')])
|
||||||
|
self.assertIn(self.glob('sym3' + os.sep),
|
||||||
|
[[self.norm('sym3')], [self.norm('sym3') + os.sep]])
|
||||||
|
eq(self.glob('*', '*F'),
|
||||||
|
[self.norm('aaa', 'zzzF'), self.norm('aab', 'F'),
|
||||||
|
self.norm('sym3', 'EF')])
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(os, 'symlink'), "Requires symlink support")
|
||||||
|
def test_glob_broken_symlinks(self):
|
||||||
|
eq = self.assertSequencesEqual_noorder
|
||||||
|
eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2'),
|
||||||
|
self.norm('sym3')])
|
||||||
eq(self.glob('sym1'), [self.norm('sym1')])
|
eq(self.glob('sym1'), [self.norm('sym1')])
|
||||||
eq(self.glob('sym2'), [self.norm('sym2')])
|
eq(self.glob('sym2'), [self.norm('sym2')])
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import os
|
||||||
import py_compile
|
import py_compile
|
||||||
import random
|
import random
|
||||||
import stat
|
import stat
|
||||||
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
import textwrap
|
import textwrap
|
||||||
|
@ -350,6 +351,46 @@ class ImportTests(unittest.TestCase):
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
remove_files(TESTFN)
|
remove_files(TESTFN)
|
||||||
|
|
||||||
|
def test_pyc_mtime(self):
|
||||||
|
# Test for issue #13863: .pyc timestamp sometimes incorrect on Windows.
|
||||||
|
sys.path.insert(0, os.curdir)
|
||||||
|
try:
|
||||||
|
# Jan 1, 2012; Jul 1, 2012.
|
||||||
|
mtimes = 1325376000, 1341100800
|
||||||
|
|
||||||
|
# Different names to avoid running into import caching.
|
||||||
|
tails = "spam", "eggs"
|
||||||
|
for mtime, tail in zip(mtimes, tails):
|
||||||
|
module = TESTFN + tail
|
||||||
|
source = module + ".py"
|
||||||
|
compiled = source + ('c' if __debug__ else 'o')
|
||||||
|
|
||||||
|
# Create a new Python file with the given mtime.
|
||||||
|
with open(source, 'w') as f:
|
||||||
|
f.write("# Just testing\nx=1, 2, 3\n")
|
||||||
|
os.utime(source, (mtime, mtime))
|
||||||
|
|
||||||
|
# Generate the .pyc/o file; if it couldn't be created
|
||||||
|
# for some reason, skip the test.
|
||||||
|
m = __import__(module)
|
||||||
|
if not os.path.exists(compiled):
|
||||||
|
unlink(source)
|
||||||
|
self.skipTest("Couldn't create .pyc/.pyo file.")
|
||||||
|
|
||||||
|
# Actual modification time of .py file.
|
||||||
|
mtime1 = int(os.stat(source).st_mtime) & 0xffffffff
|
||||||
|
|
||||||
|
# mtime that was encoded in the .pyc file.
|
||||||
|
with open(compiled, 'rb') as f:
|
||||||
|
mtime2 = struct.unpack('<L', f.read(8)[4:])[0]
|
||||||
|
|
||||||
|
unlink(compiled)
|
||||||
|
unlink(source)
|
||||||
|
|
||||||
|
self.assertEqual(mtime1, mtime2)
|
||||||
|
finally:
|
||||||
|
sys.path.pop(0)
|
||||||
|
|
||||||
|
|
||||||
class PycRewritingTests(unittest.TestCase):
|
class PycRewritingTests(unittest.TestCase):
|
||||||
# Test that the `co_filename` attribute on code objects always points
|
# Test that the `co_filename` attribute on code objects always points
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
from test import test_support
|
||||||
from test.test_support import run_unittest, have_unicode
|
from test.test_support import run_unittest, have_unicode
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
@ -44,7 +45,27 @@ if have_unicode:
|
||||||
(unichr(0x200), ValueError),
|
(unichr(0x200), ValueError),
|
||||||
]
|
]
|
||||||
|
|
||||||
class IntTestCases(unittest.TestCase):
|
class IntLongCommonTests(object):
|
||||||
|
|
||||||
|
"""Mixin of test cases to share between both test_int and test_long."""
|
||||||
|
|
||||||
|
# Change to int or long in the TestCase subclass.
|
||||||
|
ntype = None
|
||||||
|
|
||||||
|
def test_no_args(self):
|
||||||
|
self.assertEqual(self.ntype(), 0)
|
||||||
|
|
||||||
|
def test_keyword_args(self):
|
||||||
|
# Test invoking constructor using keyword arguments.
|
||||||
|
self.assertEqual(self.ntype(x=1.2), 1)
|
||||||
|
self.assertEqual(self.ntype('100', base=2), 4)
|
||||||
|
self.assertEqual(self.ntype(x='100', base=2), 4)
|
||||||
|
self.assertRaises(TypeError, self.ntype, base=10)
|
||||||
|
self.assertRaises(TypeError, self.ntype, base=0)
|
||||||
|
|
||||||
|
class IntTestCases(IntLongCommonTests, unittest.TestCase):
|
||||||
|
|
||||||
|
ntype = int
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
self.assertEqual(int(314), 314)
|
self.assertEqual(int(314), 314)
|
||||||
|
@ -315,6 +336,46 @@ class IntTestCases(unittest.TestCase):
|
||||||
self.assertEqual(int(float(2**54+10)), 2**54+8)
|
self.assertEqual(int(float(2**54+10)), 2**54+8)
|
||||||
self.assertEqual(int(float(2**54+11)), 2**54+12)
|
self.assertEqual(int(float(2**54+11)), 2**54+12)
|
||||||
|
|
||||||
|
def test_valid_non_numeric_input_types_for_x(self):
|
||||||
|
# Test possible valid non-numeric types for x, including subclasses
|
||||||
|
# of the allowed built-in types.
|
||||||
|
class CustomStr(str): pass
|
||||||
|
values = ['100', CustomStr('100')]
|
||||||
|
|
||||||
|
if have_unicode:
|
||||||
|
class CustomUnicode(unicode): pass
|
||||||
|
values += [unicode('100'), CustomUnicode(unicode('100'))]
|
||||||
|
|
||||||
|
for x in values:
|
||||||
|
msg = 'x has value %s and type %s' % (x, type(x).__name__)
|
||||||
|
try:
|
||||||
|
self.assertEqual(int(x), 100, msg=msg)
|
||||||
|
self.assertEqual(int(x, 2), 4, msg=msg)
|
||||||
|
except TypeError, err:
|
||||||
|
raise AssertionError('For %s got TypeError: %s' %
|
||||||
|
(type(x).__name__, err))
|
||||||
|
|
||||||
|
def test_error_on_string_float_for_x(self):
|
||||||
|
self.assertRaises(ValueError, int, '1.2')
|
||||||
|
|
||||||
|
def test_error_on_bytearray_for_x(self):
|
||||||
|
self.assertRaises(TypeError, int, bytearray('100'), 2)
|
||||||
|
|
||||||
|
def test_error_on_invalid_int_bases(self):
|
||||||
|
for base in [-1, 1, 1000]:
|
||||||
|
self.assertRaises(ValueError, int, '100', base)
|
||||||
|
|
||||||
|
def test_error_on_string_base(self):
|
||||||
|
self.assertRaises(TypeError, int, 100, base='foo')
|
||||||
|
|
||||||
|
@test_support.cpython_only
|
||||||
|
def test_small_ints(self):
|
||||||
|
self.assertIs(int('10'), 10)
|
||||||
|
self.assertIs(int('-1'), -1)
|
||||||
|
if have_unicode:
|
||||||
|
self.assertIs(int(u'10'), 10)
|
||||||
|
self.assertIs(int(u'-1'), -1)
|
||||||
|
|
||||||
def test_intconversion(self):
|
def test_intconversion(self):
|
||||||
# Test __int__()
|
# Test __int__()
|
||||||
class ClassicMissingMethods:
|
class ClassicMissingMethods:
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import unittest
|
import unittest
|
||||||
from test import test_support
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
from test import test_int, test_support
|
||||||
|
|
||||||
# Used for lazy formatting of failure messages
|
# Used for lazy formatting of failure messages
|
||||||
class Frm(object):
|
class Frm(object):
|
||||||
def __init__(self, format, *args):
|
def __init__(self, format, *args):
|
||||||
|
@ -78,8 +79,9 @@ if test_support.have_unicode:
|
||||||
(unichr(0x200), ValueError),
|
(unichr(0x200), ValueError),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class LongTest(test_int.IntLongCommonTests, unittest.TestCase):
|
||||||
|
|
||||||
class LongTest(unittest.TestCase):
|
ntype = long
|
||||||
|
|
||||||
# Get quasi-random long consisting of ndigits digits (in base BASE).
|
# Get quasi-random long consisting of ndigits digits (in base BASE).
|
||||||
# quasi == the most-significant digit will not be 0, and the number
|
# quasi == the most-significant digit will not be 0, and the number
|
||||||
|
|
|
@ -1513,6 +1513,7 @@ class _TestConnection(BaseTestCase):
|
||||||
self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1)
|
self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1)
|
||||||
|
|
||||||
conn.send(None)
|
conn.send(None)
|
||||||
|
time.sleep(.1)
|
||||||
|
|
||||||
self.assertEqual(poll(TIMEOUT1), True)
|
self.assertEqual(poll(TIMEOUT1), True)
|
||||||
self.assertTimingAlmostEqual(poll.elapsed, 0)
|
self.assertTimingAlmostEqual(poll.elapsed, 0)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class MutexTest(unittest.TestCase):
|
||||||
m.lock(called_by_mutex2, "eggs")
|
m.lock(called_by_mutex2, "eggs")
|
||||||
|
|
||||||
def called_by_mutex2(some_data):
|
def called_by_mutex2(some_data):
|
||||||
self.assertEquals(some_data, "eggs")
|
self.assertEqual(some_data, "eggs")
|
||||||
self.assertTrue(m.test(), "mutex not held")
|
self.assertTrue(m.test(), "mutex not held")
|
||||||
self.assertTrue(ready_for_2,
|
self.assertTrue(ready_for_2,
|
||||||
"called_by_mutex2 called too soon")
|
"called_by_mutex2 called too soon")
|
||||||
|
|
|
@ -962,8 +962,8 @@ class FileObjectClassTestCase(SocketConnectedTest):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.serv_file.close()
|
self.serv_file.close()
|
||||||
self.assertTrue(self.serv_file.closed)
|
self.assertTrue(self.serv_file.closed)
|
||||||
self.serv_file = None
|
|
||||||
SocketConnectedTest.tearDown(self)
|
SocketConnectedTest.tearDown(self)
|
||||||
|
self.serv_file = None
|
||||||
|
|
||||||
def clientSetUp(self):
|
def clientSetUp(self):
|
||||||
SocketConnectedTest.clientSetUp(self)
|
SocketConnectedTest.clientSetUp(self)
|
||||||
|
@ -1151,6 +1151,64 @@ class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
|
|
||||||
bufsize = 1 # Default-buffered for reading; line-buffered for writing
|
bufsize = 1 # Default-buffered for reading; line-buffered for writing
|
||||||
|
|
||||||
|
class SocketMemo(object):
|
||||||
|
"""A wrapper to keep track of sent data, needed to examine write behaviour"""
|
||||||
|
def __init__(self, sock):
|
||||||
|
self._sock = sock
|
||||||
|
self.sent = []
|
||||||
|
|
||||||
|
def send(self, data, flags=0):
|
||||||
|
n = self._sock.send(data, flags)
|
||||||
|
self.sent.append(data[:n])
|
||||||
|
return n
|
||||||
|
|
||||||
|
def sendall(self, data, flags=0):
|
||||||
|
self._sock.sendall(data, flags)
|
||||||
|
self.sent.append(data)
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return getattr(self._sock, attr)
|
||||||
|
|
||||||
|
def getsent(self):
|
||||||
|
return [e.tobytes() if isinstance(e, memoryview) else e for e in self.sent]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
FileObjectClassTestCase.setUp(self)
|
||||||
|
self.serv_file._sock = self.SocketMemo(self.serv_file._sock)
|
||||||
|
|
||||||
|
def testLinebufferedWrite(self):
|
||||||
|
# Write two lines, in small chunks
|
||||||
|
msg = MSG.strip()
|
||||||
|
print >> self.serv_file, msg,
|
||||||
|
print >> self.serv_file, msg
|
||||||
|
|
||||||
|
# second line:
|
||||||
|
print >> self.serv_file, msg,
|
||||||
|
print >> self.serv_file, msg,
|
||||||
|
print >> self.serv_file, msg
|
||||||
|
|
||||||
|
# third line
|
||||||
|
print >> self.serv_file, ''
|
||||||
|
|
||||||
|
self.serv_file.flush()
|
||||||
|
|
||||||
|
msg1 = "%s %s\n"%(msg, msg)
|
||||||
|
msg2 = "%s %s %s\n"%(msg, msg, msg)
|
||||||
|
msg3 = "\n"
|
||||||
|
self.assertEqual(self.serv_file._sock.getsent(), [msg1, msg2, msg3])
|
||||||
|
|
||||||
|
def _testLinebufferedWrite(self):
|
||||||
|
msg = MSG.strip()
|
||||||
|
msg1 = "%s %s\n"%(msg, msg)
|
||||||
|
msg2 = "%s %s %s\n"%(msg, msg, msg)
|
||||||
|
msg3 = "\n"
|
||||||
|
l1 = self.cli_file.readline()
|
||||||
|
self.assertEqual(l1, msg1)
|
||||||
|
l2 = self.cli_file.readline()
|
||||||
|
self.assertEqual(l2, msg2)
|
||||||
|
l3 = self.cli_file.readline()
|
||||||
|
self.assertEqual(l3, msg3)
|
||||||
|
|
||||||
|
|
||||||
class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
|
class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,34 @@ class NetworkedTests(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
def test_timeout_connect_ex(self):
|
||||||
|
# Issue #12065: on a timeout, connect_ex() should return the original
|
||||||
|
# errno (mimicking the behaviour of non-SSL sockets).
|
||||||
|
with test_support.transient_internet("svn.python.org"):
|
||||||
|
s = ssl.wrap_socket(socket.socket(socket.AF_INET),
|
||||||
|
cert_reqs=ssl.CERT_REQUIRED,
|
||||||
|
ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
|
||||||
|
do_handshake_on_connect=False)
|
||||||
|
try:
|
||||||
|
s.settimeout(0.0000001)
|
||||||
|
rc = s.connect_ex(('svn.python.org', 443))
|
||||||
|
if rc == 0:
|
||||||
|
self.skipTest("svn.python.org responded too quickly")
|
||||||
|
self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
|
||||||
|
finally:
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
def test_connect_ex_error(self):
|
||||||
|
with test_support.transient_internet("svn.python.org"):
|
||||||
|
s = ssl.wrap_socket(socket.socket(socket.AF_INET),
|
||||||
|
cert_reqs=ssl.CERT_REQUIRED,
|
||||||
|
ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
|
||||||
|
try:
|
||||||
|
self.assertEqual(errno.ECONNREFUSED,
|
||||||
|
s.connect_ex(("svn.python.org", 444)))
|
||||||
|
finally:
|
||||||
|
s.close()
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
|
@unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
|
||||||
def test_makefile_close(self):
|
def test_makefile_close(self):
|
||||||
# Issue #5238: creating a file-like object with makefile() shouldn't
|
# Issue #5238: creating a file-like object with makefile() shouldn't
|
||||||
|
|
|
@ -297,25 +297,20 @@ class MiscReadTest(CommonReadTest):
|
||||||
|
|
||||||
def test_extract_hardlink(self):
|
def test_extract_hardlink(self):
|
||||||
# Test hardlink extraction (e.g. bug #857297).
|
# Test hardlink extraction (e.g. bug #857297).
|
||||||
tar = tarfile.open(tarname, errorlevel=1, encoding="iso8859-1")
|
with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar:
|
||||||
|
|
||||||
tar.extract("ustar/regtype", TEMPDIR)
|
tar.extract("ustar/regtype", TEMPDIR)
|
||||||
try:
|
self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype"))
|
||||||
tar.extract("ustar/lnktype", TEMPDIR)
|
|
||||||
except EnvironmentError, e:
|
|
||||||
if e.errno == errno.ENOENT:
|
|
||||||
self.fail("hardlink not extracted properly")
|
|
||||||
|
|
||||||
data = open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb").read()
|
tar.extract("ustar/lnktype", TEMPDIR)
|
||||||
|
self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/lnktype"))
|
||||||
|
with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f:
|
||||||
|
data = f.read()
|
||||||
self.assertEqual(md5sum(data), md5_regtype)
|
self.assertEqual(md5sum(data), md5_regtype)
|
||||||
|
|
||||||
try:
|
|
||||||
tar.extract("ustar/symtype", TEMPDIR)
|
tar.extract("ustar/symtype", TEMPDIR)
|
||||||
except EnvironmentError, e:
|
self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/symtype"))
|
||||||
if e.errno == errno.ENOENT:
|
with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f:
|
||||||
self.fail("symlink not extracted properly")
|
data = f.read()
|
||||||
|
|
||||||
data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read()
|
|
||||||
self.assertEqual(md5sum(data), md5_regtype)
|
self.assertEqual(md5sum(data), md5_regtype)
|
||||||
|
|
||||||
def test_extractall(self):
|
def test_extractall(self):
|
||||||
|
@ -858,7 +853,7 @@ class WriteTest(WriteTestBase):
|
||||||
|
|
||||||
tar = tarfile.open(tmpname, "r")
|
tar = tarfile.open(tmpname, "r")
|
||||||
for t in tar:
|
for t in tar:
|
||||||
self.assert_(t.name == "." or t.name.startswith("./"))
|
self.assertTrue(t.name == "." or t.name.startswith("./"))
|
||||||
tar.close()
|
tar.close()
|
||||||
finally:
|
finally:
|
||||||
os.chdir(cwd)
|
os.chdir(cwd)
|
||||||
|
|
|
@ -1336,7 +1336,7 @@ class RequestTests(unittest.TestCase):
|
||||||
req = Request(url)
|
req = Request(url)
|
||||||
self.assertEqual(req.get_full_url(), url)
|
self.assertEqual(req.get_full_url(), url)
|
||||||
|
|
||||||
def test_HTTPError_interface():
|
def test_HTTPError_interface(self):
|
||||||
"""
|
"""
|
||||||
Issue 13211 reveals that HTTPError didn't implement the URLError
|
Issue 13211 reveals that HTTPError didn't implement the URLError
|
||||||
interface even though HTTPError is a subclass of URLError.
|
interface even though HTTPError is a subclass of URLError.
|
||||||
|
@ -1347,6 +1347,22 @@ def test_HTTPError_interface():
|
||||||
'something bad happened'
|
'something bad happened'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def test_HTTPError_interface_call(self):
|
||||||
|
"""
|
||||||
|
Issue 15701= - HTTPError interface has info method available from URLError.
|
||||||
|
"""
|
||||||
|
err = urllib2.HTTPError(msg='something bad happened', url=None,
|
||||||
|
code=None, hdrs='Content-Length:42', fp=None)
|
||||||
|
self.assertTrue(hasattr(err, 'reason'))
|
||||||
|
assert hasattr(err, 'reason')
|
||||||
|
assert hasattr(err, 'info')
|
||||||
|
assert callable(err.info)
|
||||||
|
try:
|
||||||
|
err.info()
|
||||||
|
except AttributeError:
|
||||||
|
self.fail("err.info() failed")
|
||||||
|
self.assertEqual(err.info(), "Content-Length:42")
|
||||||
|
|
||||||
def test_main(verbose=None):
|
def test_main(verbose=None):
|
||||||
from test import test_urllib2
|
from test import test_urllib2
|
||||||
test_support.run_doctest(test_urllib2, verbose)
|
test_support.run_doctest(test_urllib2, verbose)
|
||||||
|
|
|
@ -5,7 +5,9 @@ import urllib2
|
||||||
import BaseHTTPServer
|
import BaseHTTPServer
|
||||||
import unittest
|
import unittest
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from test import test_support
|
from test import test_support
|
||||||
|
|
||||||
mimetools = test_support.import_module('mimetools', deprecated=True)
|
mimetools = test_support.import_module('mimetools', deprecated=True)
|
||||||
threading = test_support.import_module('threading')
|
threading = test_support.import_module('threading')
|
||||||
|
|
||||||
|
@ -346,6 +348,12 @@ class TestUrlopen(BaseTestCase):
|
||||||
for transparent redirection have been written.
|
for transparent redirection have been written.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
proxy_handler = urllib2.ProxyHandler({})
|
||||||
|
opener = urllib2.build_opener(proxy_handler)
|
||||||
|
urllib2.install_opener(opener)
|
||||||
|
super(TestUrlopen, self).setUp()
|
||||||
|
|
||||||
def start_server(self, responses):
|
def start_server(self, responses):
|
||||||
handler = GetRequestHandler(responses)
|
handler = GetRequestHandler(responses)
|
||||||
|
|
||||||
|
|
|
@ -446,10 +446,43 @@ class UrlParseTestCase(unittest.TestCase):
|
||||||
p1 = urlparse.urlsplit('tel:+31-641044153')
|
p1 = urlparse.urlsplit('tel:+31-641044153')
|
||||||
self.assertEqual(p1.scheme, 'tel')
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
self.assertEqual(p1.path, '+31-641044153')
|
self.assertEqual(p1.path, '+31-641044153')
|
||||||
|
|
||||||
p2 = urlparse.urlsplit('tel:+31641044153')
|
p2 = urlparse.urlsplit('tel:+31641044153')
|
||||||
self.assertEqual(p2.scheme, 'tel')
|
self.assertEqual(p2.scheme, 'tel')
|
||||||
self.assertEqual(p2.path, '+31641044153')
|
self.assertEqual(p2.path, '+31641044153')
|
||||||
|
|
||||||
|
# Assert for urlparse
|
||||||
|
p1 = urlparse.urlparse('tel:+31-641044153')
|
||||||
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
|
self.assertEqual(p1.path, '+31-641044153')
|
||||||
|
|
||||||
|
p2 = urlparse.urlparse('tel:+31641044153')
|
||||||
|
self.assertEqual(p2.scheme, 'tel')
|
||||||
|
self.assertEqual(p2.path, '+31641044153')
|
||||||
|
|
||||||
|
|
||||||
|
def test_telurl_params(self):
|
||||||
|
p1 = urlparse.urlparse('tel:123-4;phone-context=+1-650-516')
|
||||||
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
|
self.assertEqual(p1.path, '123-4')
|
||||||
|
self.assertEqual(p1.params, 'phone-context=+1-650-516')
|
||||||
|
|
||||||
|
p1 = urlparse.urlparse('tel:+1-201-555-0123')
|
||||||
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
|
self.assertEqual(p1.path, '+1-201-555-0123')
|
||||||
|
self.assertEqual(p1.params, '')
|
||||||
|
|
||||||
|
p1 = urlparse.urlparse('tel:7042;phone-context=example.com')
|
||||||
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
|
self.assertEqual(p1.path, '7042')
|
||||||
|
self.assertEqual(p1.params, 'phone-context=example.com')
|
||||||
|
|
||||||
|
p1 = urlparse.urlparse('tel:863-1234;phone-context=+1-914-555')
|
||||||
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
|
self.assertEqual(p1.path, '863-1234')
|
||||||
|
self.assertEqual(p1.params, 'phone-context=+1-914-555')
|
||||||
|
|
||||||
|
|
||||||
def test_attributes_bad_port(self):
|
def test_attributes_bad_port(self):
|
||||||
"""Check handling of non-integer ports."""
|
"""Check handling of non-integer ports."""
|
||||||
p = urlparse.urlsplit("http://www.example.net:foo")
|
p = urlparse.urlsplit("http://www.example.net:foo")
|
||||||
|
|
|
@ -314,6 +314,35 @@ class LocalWinregTests(BaseWinregTests):
|
||||||
finally:
|
finally:
|
||||||
DeleteKey(HKEY_CURRENT_USER, test_key_name)
|
DeleteKey(HKEY_CURRENT_USER, test_key_name)
|
||||||
|
|
||||||
|
def test_setvalueex_value_range(self):
|
||||||
|
# Test for Issue #14420, accept proper ranges for SetValueEx.
|
||||||
|
# Py2Reg, which gets called by SetValueEx, was using PyLong_AsLong,
|
||||||
|
# thus raising OverflowError. The implementation now uses
|
||||||
|
# PyLong_AsUnsignedLong to match DWORD's size.
|
||||||
|
try:
|
||||||
|
with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
|
||||||
|
self.assertNotEqual(ck.handle, 0)
|
||||||
|
SetValueEx(ck, "test_name", None, REG_DWORD, 0x80000000)
|
||||||
|
finally:
|
||||||
|
DeleteKey(HKEY_CURRENT_USER, test_key_name)
|
||||||
|
|
||||||
|
def test_queryvalueex_return_value(self):
|
||||||
|
# Test for Issue #16759, return unsigned int from QueryValueEx.
|
||||||
|
# Reg2Py, which gets called by QueryValueEx, was returning a value
|
||||||
|
# generated by PyLong_FromLong. The implmentation now uses
|
||||||
|
# PyLong_FromUnsignedLong to match DWORD's size.
|
||||||
|
try:
|
||||||
|
with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck:
|
||||||
|
self.assertNotEqual(ck.handle, 0)
|
||||||
|
test_val = 0x80000000
|
||||||
|
SetValueEx(ck, "test_name", None, REG_DWORD, test_val)
|
||||||
|
ret_val, ret_type = QueryValueEx(ck, "test_name")
|
||||||
|
self.assertEqual(ret_type, REG_DWORD)
|
||||||
|
self.assertEqual(ret_val, test_val)
|
||||||
|
finally:
|
||||||
|
DeleteKey(HKEY_CURRENT_USER, test_key_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests")
|
@unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests")
|
||||||
class RemoteWinregTests(BaseWinregTests):
|
class RemoteWinregTests(BaseWinregTests):
|
||||||
|
|
|
@ -173,6 +173,9 @@ class HTTPError(URLError, addinfourl):
|
||||||
def reason(self):
|
def reason(self):
|
||||||
return self.msg
|
return self.msg
|
||||||
|
|
||||||
|
def info(self):
|
||||||
|
return self.hdrs
|
||||||
|
|
||||||
# copied from cookielib.py
|
# copied from cookielib.py
|
||||||
_cut_port_re = re.compile(r":\d+$")
|
_cut_port_re = re.compile(r":\d+$")
|
||||||
def request_host(request):
|
def request_host(request):
|
||||||
|
|
|
@ -42,7 +42,7 @@ uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet',
|
||||||
'svn', 'svn+ssh', 'sftp','nfs','git', 'git+ssh']
|
'svn', 'svn+ssh', 'sftp','nfs','git', 'git+ssh']
|
||||||
uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
|
uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
|
||||||
'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
|
'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
|
||||||
'mms', '', 'sftp']
|
'mms', '', 'sftp', 'tel']
|
||||||
|
|
||||||
# These are not actually used anymore, but should stay for backwards
|
# These are not actually used anymore, but should stay for backwards
|
||||||
# compatibility. (They are undocumented, but have a public-looking name.)
|
# compatibility. (They are undocumented, but have a public-looking name.)
|
||||||
|
|
|
@ -499,6 +499,7 @@ Tamito Kajiyama
|
||||||
Peter van Kampen
|
Peter van Kampen
|
||||||
Jacob Kaplan-Moss
|
Jacob Kaplan-Moss
|
||||||
Piotr Kasprzyk
|
Piotr Kasprzyk
|
||||||
|
Anton Kasyanov
|
||||||
Lou Kates
|
Lou Kates
|
||||||
Hiroaki Kawai
|
Hiroaki Kawai
|
||||||
Sebastien Keim
|
Sebastien Keim
|
||||||
|
|
44
Misc/NEWS
44
Misc/NEWS
|
@ -9,6 +9,21 @@ What's New in Python 2.7.4
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #16761: Calling ``int()`` and ``long()`` with *base* argument only
|
||||||
|
now raises TypeError.
|
||||||
|
|
||||||
|
- Issue #16759: Support the full DWORD (unsigned long) range in Reg2Py
|
||||||
|
when retreiving a REG_DWORD value. This corrects functions like
|
||||||
|
winreg.QueryValueEx that may have been returning truncated values.
|
||||||
|
|
||||||
|
- Issue #14420: Support the full DWORD (unsigned long) range in Py2Reg
|
||||||
|
when passed a REG_DWORD value. Fixes ValueError in winreg.SetValueEx when
|
||||||
|
given a long.
|
||||||
|
|
||||||
|
- Issue #13863: Work around buggy 'fstat' implementation on Windows / NTFS that
|
||||||
|
lead to incorrect timestamps (off by one hour) being stored in .pyc files on
|
||||||
|
some systems.
|
||||||
|
|
||||||
- Issue #16602: When a weakref's target was part of a long deallocation
|
- Issue #16602: When a weakref's target was part of a long deallocation
|
||||||
chain, the object could remain reachable through its weakref even though
|
chain, the object could remain reachable through its weakref even though
|
||||||
its refcount had dropped to zero.
|
its refcount had dropped to zero.
|
||||||
|
@ -160,11 +175,32 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue 10527: make multiprocessing use poll() instead of select() if available.
|
||||||
|
|
||||||
|
- Issue #16485: Fix file descriptor not being closed if file header patching
|
||||||
|
fails on closing of aifc file.
|
||||||
|
|
||||||
|
- Issue #12065: connect_ex() on an SSL socket now returns the original errno
|
||||||
|
when the socket's timeout expires (it used to return None).
|
||||||
|
|
||||||
|
- Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by
|
||||||
|
Roger Serwy.
|
||||||
|
|
||||||
|
- Issue #16702: test_urllib2_localnet tests now correctly ignores proxies for
|
||||||
|
localhost tests.
|
||||||
|
|
||||||
|
- Issue #16713: Fix the parsing of tel url with params using urlparse module.
|
||||||
|
|
||||||
|
- Issue #16443: Add docstrings to regular expression match objects.
|
||||||
|
Patch by Anton Kasyanov.
|
||||||
|
|
||||||
- Issue #8853: Allow port to be of type long for socket.getaddrinfo().
|
- Issue #8853: Allow port to be of type long for socket.getaddrinfo().
|
||||||
|
|
||||||
- Issue #16597: In buffered and text IO, call close() on the underlying stream
|
- Issue #16597: In buffered and text IO, call close() on the underlying stream
|
||||||
if invoking flush() fails.
|
if invoking flush() fails.
|
||||||
|
|
||||||
|
- Issue #15701: Fix HTTPError info method call to return the headers information.
|
||||||
|
|
||||||
- Issue #16646: ftplib.FTP.makeport() might lose socket error details.
|
- Issue #16646: ftplib.FTP.makeport() might lose socket error details.
|
||||||
(patch by Serhiy Storchaka)
|
(patch by Serhiy Storchaka)
|
||||||
|
|
||||||
|
@ -394,6 +430,9 @@ Library
|
||||||
- Issue #12157: Make pool.map() empty iterables correctly. Initial
|
- Issue #12157: Make pool.map() empty iterables correctly. Initial
|
||||||
patch by mouad.
|
patch by mouad.
|
||||||
|
|
||||||
|
- Issue #14958: Change IDLE systax highlighting to recognize all string and byte
|
||||||
|
literals currently supported in Python 2.7.
|
||||||
|
|
||||||
- Issue #14962: Update text coloring in IDLE shell window after changing
|
- Issue #14962: Update text coloring in IDLE shell window after changing
|
||||||
options. Patch by Roger Serwy.
|
options. Patch by Roger Serwy.
|
||||||
|
|
||||||
|
@ -560,6 +599,11 @@ Extension Modules
|
||||||
Tests
|
Tests
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Issue #15324: Fix regrtest parsing of --fromfile and --randomize options.
|
||||||
|
|
||||||
|
- Issue #16618: Add more regression tests for glob.
|
||||||
|
Patch by Serhiy Storchaka.
|
||||||
|
|
||||||
- Issue #16664: Add regression tests for glob's behaviour concerning entries
|
- Issue #16664: Add regression tests for glob's behaviour concerning entries
|
||||||
starting with a ".". Patch by Sebastian Kreft.
|
starting with a ".". Patch by Sebastian Kreft.
|
||||||
|
|
||||||
|
|
|
@ -844,11 +844,11 @@ static int _call_function_pointer(int flags,
|
||||||
space[0] = errno;
|
space[0] = errno;
|
||||||
errno = temp;
|
errno = temp;
|
||||||
}
|
}
|
||||||
Py_XDECREF(error_object);
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
|
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
|
||||||
Py_BLOCK_THREADS
|
Py_BLOCK_THREADS
|
||||||
#endif
|
#endif
|
||||||
|
Py_XDECREF(error_object);
|
||||||
#ifdef MS_WIN32
|
#ifdef MS_WIN32
|
||||||
#ifndef DONT_USE_SEH
|
#ifndef DONT_USE_SEH
|
||||||
if (dwExceptionCode) {
|
if (dwExceptionCode) {
|
||||||
|
|
|
@ -2546,7 +2546,7 @@ PyDoc_STRVAR(pattern_match_doc,
|
||||||
PyDoc_STRVAR(pattern_search_doc,
|
PyDoc_STRVAR(pattern_search_doc,
|
||||||
"search(string[, pos[, endpos]]) --> match object or None.\n\
|
"search(string[, pos[, endpos]]) --> match object or None.\n\
|
||||||
Scan through string looking for a match, and return a corresponding\n\
|
Scan through string looking for a match, and return a corresponding\n\
|
||||||
MatchObject instance. Return None if no position in the string matches.");
|
match object instance. Return None if no position in the string matches.");
|
||||||
|
|
||||||
PyDoc_STRVAR(pattern_split_doc,
|
PyDoc_STRVAR(pattern_split_doc,
|
||||||
"split(string[, maxsplit = 0]) --> list.\n\
|
"split(string[, maxsplit = 0]) --> list.\n\
|
||||||
|
@ -3545,14 +3545,54 @@ match_deepcopy(MatchObject* self, PyObject* memo)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyMethodDef match_methods[] = {
|
PyDoc_STRVAR(match_doc,
|
||||||
{"group", (PyCFunction) match_group, METH_VARARGS},
|
"The result of re.match() and re.search().\n\
|
||||||
{"start", (PyCFunction) match_start, METH_VARARGS},
|
Match objects always have a boolean value of True.");
|
||||||
{"end", (PyCFunction) match_end, METH_VARARGS},
|
|
||||||
{"span", (PyCFunction) match_span, METH_VARARGS},
|
PyDoc_STRVAR(match_group_doc,
|
||||||
{"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS},
|
"group([group1, ...]) -> str or tuple.\n\
|
||||||
{"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS},
|
Return subgroup(s) of the match by indices or names.\n\
|
||||||
{"expand", (PyCFunction) match_expand, METH_O},
|
For 0 returns the entire match.");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(match_start_doc,
|
||||||
|
"start([group=0]) -> int.\n\
|
||||||
|
Return index of the start of the substring matched by group.");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(match_end_doc,
|
||||||
|
"end([group=0]) -> int.\n\
|
||||||
|
Return index of the end of the substring matched by group.");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(match_span_doc,
|
||||||
|
"span([group]) -> tuple.\n\
|
||||||
|
For MatchObject m, return the 2-tuple (m.start(group), m.end(group)).");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(match_groups_doc,
|
||||||
|
"groups([default=None]) -> tuple.\n\
|
||||||
|
Return a tuple containing all the subgroups of the match, from 1.\n\
|
||||||
|
The default argument is used for groups\n\
|
||||||
|
that did not participate in the match");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(match_groupdict_doc,
|
||||||
|
"groupdict([default=None]) -> dict.\n\
|
||||||
|
Return a dictionary containing all the named subgroups of the match,\n\
|
||||||
|
keyed by the subgroup name. The default argument is used for groups\n\
|
||||||
|
that did not participate in the match");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(match_expand_doc,
|
||||||
|
"expand(template) -> str.\n\
|
||||||
|
Return the string obtained by doing backslash substitution\n\
|
||||||
|
on the string template, as done by the sub() method.");
|
||||||
|
|
||||||
|
static PyMethodDef match_methods[] = {
|
||||||
|
{"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc},
|
||||||
|
{"start", (PyCFunction) match_start, METH_VARARGS, match_start_doc},
|
||||||
|
{"end", (PyCFunction) match_end, METH_VARARGS, match_end_doc},
|
||||||
|
{"span", (PyCFunction) match_span, METH_VARARGS, match_span_doc},
|
||||||
|
{"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS,
|
||||||
|
match_groups_doc},
|
||||||
|
{"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS,
|
||||||
|
match_groupdict_doc},
|
||||||
|
{"expand", (PyCFunction) match_expand, METH_O, match_expand_doc},
|
||||||
{"__copy__", (PyCFunction) match_copy, METH_NOARGS},
|
{"__copy__", (PyCFunction) match_copy, METH_NOARGS},
|
||||||
{"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
|
{"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
@ -3632,7 +3672,7 @@ static PyTypeObject Match_Type = {
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT,
|
Py_TPFLAGS_DEFAULT,
|
||||||
0, /* tp_doc */
|
match_doc, /* tp_doc */
|
||||||
0, /* tp_traverse */
|
0, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
|
|
|
@ -1059,8 +1059,14 @@ int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
|
||||||
&x, &base))
|
&x, &base))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (x == NULL)
|
if (x == NULL) {
|
||||||
|
if (base != -909) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"int() missing string argument");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return PyInt_FromLong(0L);
|
return PyInt_FromLong(0L);
|
||||||
|
}
|
||||||
if (base == -909)
|
if (base == -909)
|
||||||
return PyNumber_Int(x);
|
return PyNumber_Int(x);
|
||||||
if (PyString_Check(x)) {
|
if (PyString_Check(x)) {
|
||||||
|
|
|
@ -3987,8 +3987,14 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
|
||||||
&x, &base))
|
&x, &base))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (x == NULL)
|
if (x == NULL) {
|
||||||
|
if (base != -909) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"long() missing string argument");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return PyLong_FromLong(0L);
|
return PyLong_FromLong(0L);
|
||||||
|
}
|
||||||
if (base == -909)
|
if (base == -909)
|
||||||
return PyNumber_Long(x);
|
return PyNumber_Long(x);
|
||||||
else if (PyString_Check(x)) {
|
else if (PyString_Check(x)) {
|
||||||
|
|
15
PC/_winreg.c
15
PC/_winreg.c
|
@ -753,7 +753,8 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
|
||||||
Py_ssize_t i,j;
|
Py_ssize_t i,j;
|
||||||
switch (typ) {
|
switch (typ) {
|
||||||
case REG_DWORD:
|
case REG_DWORD:
|
||||||
if (value != Py_None && !PyInt_Check(value))
|
if (value != Py_None &&
|
||||||
|
!(PyInt_Check(value) || PyLong_Check(value)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
|
*retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
|
||||||
if (*retDataBuf==NULL){
|
if (*retDataBuf==NULL){
|
||||||
|
@ -765,10 +766,10 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
|
||||||
DWORD zero = 0;
|
DWORD zero = 0;
|
||||||
memcpy(*retDataBuf, &zero, sizeof(DWORD));
|
memcpy(*retDataBuf, &zero, sizeof(DWORD));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
memcpy(*retDataBuf,
|
DWORD d = PyLong_AsUnsignedLong(value);
|
||||||
&PyInt_AS_LONG((PyIntObject *)value),
|
memcpy(*retDataBuf, &d, sizeof(DWORD));
|
||||||
sizeof(DWORD));
|
}
|
||||||
break;
|
break;
|
||||||
case REG_SZ:
|
case REG_SZ:
|
||||||
case REG_EXPAND_SZ:
|
case REG_EXPAND_SZ:
|
||||||
|
@ -917,9 +918,9 @@ Reg2Py(char *retDataBuf, DWORD retDataSize, DWORD typ)
|
||||||
switch (typ) {
|
switch (typ) {
|
||||||
case REG_DWORD:
|
case REG_DWORD:
|
||||||
if (retDataSize == 0)
|
if (retDataSize == 0)
|
||||||
obData = Py_BuildValue("i", 0);
|
obData = Py_BuildValue("k", 0);
|
||||||
else
|
else
|
||||||
obData = Py_BuildValue("i",
|
obData = Py_BuildValue("k",
|
||||||
*(int *)retDataBuf);
|
*(int *)retDataBuf);
|
||||||
break;
|
break;
|
||||||
case REG_SZ:
|
case REG_SZ:
|
||||||
|
|
|
@ -904,10 +904,9 @@ open_exclusive(char *filename, mode_t mode)
|
||||||
remove the file. */
|
remove the file. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
|
write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat, time_t mtime)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
time_t mtime = srcstat->st_mtime;
|
|
||||||
#ifdef MS_WINDOWS /* since Windows uses different permissions */
|
#ifdef MS_WINDOWS /* since Windows uses different permissions */
|
||||||
mode_t mode = srcstat->st_mode & ~S_IEXEC;
|
mode_t mode = srcstat->st_mode & ~S_IEXEC;
|
||||||
/* Issue #6074: We ensure user write access, so we can delete it later
|
/* Issue #6074: We ensure user write access, so we can delete it later
|
||||||
|
@ -993,6 +992,38 @@ update_compiled_module(PyCodeObject *co, char *pathname)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
|
||||||
|
/* Seconds between 1.1.1601 and 1.1.1970 */
|
||||||
|
static __int64 secs_between_epochs = 11644473600;
|
||||||
|
|
||||||
|
/* Get mtime from file pointer. */
|
||||||
|
|
||||||
|
static time_t
|
||||||
|
win32_mtime(FILE *fp, char *pathname)
|
||||||
|
{
|
||||||
|
__int64 filetime;
|
||||||
|
HANDLE fh;
|
||||||
|
BY_HANDLE_FILE_INFORMATION file_information;
|
||||||
|
|
||||||
|
fh = (HANDLE)_get_osfhandle(fileno(fp));
|
||||||
|
if (fh == INVALID_HANDLE_VALUE ||
|
||||||
|
!GetFileInformationByHandle(fh, &file_information)) {
|
||||||
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
|
"unable to get file status from '%s'",
|
||||||
|
pathname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* filetime represents the number of 100ns intervals since
|
||||||
|
1.1.1601 (UTC). Convert to seconds since 1.1.1970 (UTC). */
|
||||||
|
filetime = (__int64)file_information.ftLastWriteTime.dwHighDateTime << 32 |
|
||||||
|
file_information.ftLastWriteTime.dwLowDateTime;
|
||||||
|
return filetime / 10000000 - secs_between_epochs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #ifdef MS_WINDOWS */
|
||||||
|
|
||||||
|
|
||||||
/* Load a source module from a given file and return its module
|
/* Load a source module from a given file and return its module
|
||||||
object WITH INCREMENTED REFERENCE COUNT. If there's a matching
|
object WITH INCREMENTED REFERENCE COUNT. If there's a matching
|
||||||
byte-compiled file, use that instead. */
|
byte-compiled file, use that instead. */
|
||||||
|
@ -1006,6 +1037,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
|
||||||
char *cpathname;
|
char *cpathname;
|
||||||
PyCodeObject *co = NULL;
|
PyCodeObject *co = NULL;
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
|
time_t mtime;
|
||||||
|
|
||||||
if (fstat(fileno(fp), &st) != 0) {
|
if (fstat(fileno(fp), &st) != 0) {
|
||||||
PyErr_Format(PyExc_RuntimeError,
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
|
@ -1013,13 +1045,21 @@ load_source_module(char *name, char *pathname, FILE *fp)
|
||||||
pathname);
|
pathname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (sizeof st.st_mtime > 4) {
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
mtime = win32_mtime(fp, pathname);
|
||||||
|
if (mtime == (time_t)-1 && PyErr_Occurred())
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
mtime = st.st_mtime;
|
||||||
|
#endif
|
||||||
|
if (sizeof mtime > 4) {
|
||||||
/* Python's .pyc timestamp handling presumes that the timestamp fits
|
/* Python's .pyc timestamp handling presumes that the timestamp fits
|
||||||
in 4 bytes. Since the code only does an equality comparison,
|
in 4 bytes. Since the code only does an equality comparison,
|
||||||
ordering is not important and we can safely ignore the higher bits
|
ordering is not important and we can safely ignore the higher bits
|
||||||
(collisions are extremely unlikely).
|
(collisions are extremely unlikely).
|
||||||
*/
|
*/
|
||||||
st.st_mtime &= 0xFFFFFFFF;
|
mtime &= 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
buf = PyMem_MALLOC(MAXPATHLEN+1);
|
buf = PyMem_MALLOC(MAXPATHLEN+1);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
|
@ -1028,7 +1068,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
|
||||||
cpathname = make_compiled_pathname(pathname, buf,
|
cpathname = make_compiled_pathname(pathname, buf,
|
||||||
(size_t)MAXPATHLEN + 1);
|
(size_t)MAXPATHLEN + 1);
|
||||||
if (cpathname != NULL &&
|
if (cpathname != NULL &&
|
||||||
(fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) {
|
(fpc = check_compiled_module(pathname, mtime, cpathname))) {
|
||||||
co = read_compiled_module(cpathname, fpc);
|
co = read_compiled_module(cpathname, fpc);
|
||||||
fclose(fpc);
|
fclose(fpc);
|
||||||
if (co == NULL)
|
if (co == NULL)
|
||||||
|
@ -1053,7 +1093,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
|
||||||
if (b < 0)
|
if (b < 0)
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
if (!b)
|
if (!b)
|
||||||
write_compiled_module(co, cpathname, &st);
|
write_compiled_module(co, cpathname, &st, mtime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
|
m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue