merge heads

This commit is contained in:
Benjamin Peterson 2012-12-31 21:40:42 -06:00
commit 1f7df8f207
55 changed files with 768 additions and 220 deletions

View file

@ -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?

View file

@ -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

View file

@ -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 )))' )
@ -1180,11 +1181,11 @@ 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::
>>> def hexrepl(match): >>> def hexrepl(match):

View file

@ -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.

View file

@ -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

View file

@ -239,14 +239,14 @@ around for backward compatibility:
.. impl-detail:: .. impl-detail::
The import internals identify extension modules by filename, so doing The import internals identify extension modules by filename, so doing
``foo = load_dynamic("foo", "mod.so")`` and ``foo = load_dynamic("foo", "mod.so")`` and
``bar = load_dynamic("bar", "mod.so")`` will result in both foo and bar ``bar = load_dynamic("bar", "mod.so")`` will result in both foo and bar
referring to the same module, regardless of whether or not referring to the same module, regardless of whether or not
``mod.so`` exports an ``initbar`` function. On systems which ``mod.so`` exports an ``initbar`` function. On systems which
support them, symlinks can be used to import multiple modules from support them, symlinks can be used to import multiple modules from
the same shared library, as each reference to the module will use the same shared library, as each reference to the module will use
a different file name. a different file name.
.. function:: load_source(name, pathname[, file]) .. function:: load_source(name, pathname[, file])

View file

@ -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:

View file

@ -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)

View file

@ -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.

View file

@ -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:

View file

@ -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()

View file

@ -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.

View file

@ -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 |
+-----------------------------------------------+-------------------------------------+ +-----------------------------------------------+-------------------------------------+

View file

@ -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
--------------------------------------- ---------------------------------------

View file

@ -701,7 +701,12 @@ class StreamRequestHandler(BaseRequestHandler):
def finish(self): def finish(self):
if not self.wfile.closed: if not self.wfile.closed:
self.wfile.flush() try:
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()

View file

@ -732,22 +732,28 @@ class Aifc_write:
self._patchheader() self._patchheader()
def close(self): def close(self):
self._ensure_header_written(0) if self._file is None:
if self._datawritten & 1: return
# quick pad to even size try:
self._file.write(chr(0)) self._ensure_header_written(0)
self._datawritten = self._datawritten + 1 if self._datawritten & 1:
self._writemarkers() # quick pad to even size
if self._nframeswritten != self._nframes or \ self._file.write(chr(0))
self._datalength != self._datawritten or \ self._datawritten = self._datawritten + 1
self._marklength: self._writemarkers()
self._patchheader() if self._nframeswritten != self._nframes or \
if self._comp: self._datalength != self._datawritten or \
self._comp.CloseCompressor() self._marklength:
self._comp = None self._patchheader()
# Prevent ref cycles if self._comp:
self._convert = None self._comp.CloseCompressor()
self._file.close() self._comp = None
finally:
# Prevent ref cycles
self._convert = None
f = self._file
self._file = None
f.close()
# #
# Internal methods. # Internal methods.

View file

@ -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

View file

@ -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()

View file

@ -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()
... ...
""" """

View file

@ -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"])

View file

@ -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

View file

@ -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:

View file

@ -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'))

View file

@ -237,24 +237,39 @@ class IdleConf:
printed to stderr. printed to stderr.
""" """
if self.userCfg[configType].has_option(section,option): try:
return self.userCfg[configType].Get(section, option, if self.userCfg[configType].has_option(section,option):
type=type, raw=raw) return self.userCfg[configType].Get(section, option,
elif self.defaultCfg[configType].has_option(section,option): type=type, raw=raw)
return self.defaultCfg[configType].Get(section, option, except ValueError:
type=type, raw=raw) warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
else: #returning default, print warning ' invalid %r value for configuration option %r\n'
if warn_on_default: ' from section %r: %r\n' %
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' (type, option, section,
' problem retrieving configuration option %r\n' self.userCfg[configType].Get(section, option,
' from section %r.\n' raw=raw)))
' returning default value: %r\n' % try:
(option, section, default)) sys.stderr.write(warning)
try: except IOError:
sys.stderr.write(warning) pass
except IOError: try:
pass if self.defaultCfg[configType].has_option(section,option):
return default return self.defaultCfg[configType].Get(section, option,
type=type, raw=raw)
except ValueError:
pass
#returning default, print warning
if warn_on_default:
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
' problem retrieving configuration option %r\n'
' from section %r.\n'
' returning default value: %r\n' %
(option, section, default))
try:
sys.stderr.write(warning)
except IOError:
pass
return default
def SetOption(self, configType, section, option, value): def SetOption(self, configType, section, option, value):
"""In user's config file, set section's option to value. """In user's config file, set section's option to value.

View file

@ -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

View file

@ -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):

View file

@ -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:
socket.connect(self, addr)
if self.do_handshake_on_connect:
self.do_handshake()
except socket_error as e:
if return_errno: if return_errno:
return e.errno rc = socket.connect_ex(self, addr)
else: else:
self._sslobj = None rc = None
raise e socket.connect(self, addr)
self._connected = True if not rc:
return 0 if self.do_handshake_on_connect:
self.do_handshake()
self._connected = True
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

View file

@ -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

View file

@ -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'])

View file

@ -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):

View file

@ -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,

View file

@ -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

View file

@ -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,23 +109,60 @@ 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_unicode_directory_with_trailing_slash(self):
# 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.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): def test_glob_broken_symlinks(self):
if hasattr(os, 'symlink'): eq = self.assertSequencesEqual_noorder
eq = self.assertSequencesEqual_noorder eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2'),
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')])
@unittest.skipUnless(sys.platform == "win32", "Win32 specific test") @unittest.skipUnless(sys.platform == "win32", "Win32 specific test")
def test_glob_magic_in_drive(self): def test_glob_magic_in_drive(self):

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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)

View file

@ -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")

View file

@ -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):

View file

@ -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

View file

@ -297,26 +297,21 @@ 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)
self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype"))
tar.extract("ustar/regtype", TEMPDIR)
try:
tar.extract("ustar/lnktype", TEMPDIR) tar.extract("ustar/lnktype", TEMPDIR)
except EnvironmentError, e: self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/lnktype"))
if e.errno == errno.ENOENT: with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f:
self.fail("hardlink not extracted properly") data = f.read()
self.assertEqual(md5sum(data), md5_regtype)
data = open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb").read()
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()
self.assertEqual(md5sum(data), md5_regtype)
data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read()
self.assertEqual(md5sum(data), md5_regtype)
def test_extractall(self): def test_extractall(self):
# Test if extractall() correctly restores directory permissions # Test if extractall() correctly restores directory permissions
@ -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)

View file

@ -1336,16 +1336,32 @@ 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.
>>> err = urllib2.HTTPError(msg='something bad happened', url=None, code=None, hdrs=None, fp=None) >>> err = urllib2.HTTPError(msg='something bad happened', url=None, code=None, hdrs=None, fp=None)
>>> assert hasattr(err, 'reason') >>> assert hasattr(err, 'reason')
>>> err.reason >>> err.reason
'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

View file

@ -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)

View file

@ -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")

View file

@ -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):

View file

@ -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):

View file

@ -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.)

View file

@ -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

View file

@ -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.

View file

@ -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) {

View file

@ -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 */

View file

@ -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)) {

View file

@ -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)) {

View file

@ -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:

View file

@ -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);