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)
.. index::
single: argument; difference from parameter
single: parameter; difference from argument
.. _faq-argument-vs-parameter:
What is the difference between arguments and parameters?

View File

@ -245,8 +245,9 @@ Glossary
function
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
the body. See also :term:`argument` and :term:`method`.
be passed zero or more :term:`arguments <argument>` which may be used in
the execution of the body. See also :term:`parameter`, :term:`method`,
and the :ref:`function` section.
__future__
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
they're successful, a ``MatchObject`` instance is returned, containing
information about the match: where it starts and ends, the substring it matched,
and more.
they're successful, a :ref:`match object <match-objects>` instance is returned,
containing information about the match: where it starts and ends, the substring
it matched, and more.
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
@ -392,16 +392,16 @@ interpreter to print no output. You can explicitly print the result of
None
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
result in a variable for later use. ::
case, :meth:`match` will return a :ref:`match object <match-objects>`, so you
should store the result in a variable for later use. ::
>>> m = p.match('tempo')
>>> m #doctest: +ELLIPSIS
<_sre.SRE_Match object at 0x...>
Now you can query the :class:`MatchObject` for information about the matching
string. :class:`MatchObject` instances also have several methods and
attributes; the most important ones are:
Now you can query the :ref:`match object <match-objects>` for information
about the matching string. :ref:`match object <match-objects>` instances
also have several methods and attributes; the most important ones are:
+------------------+--------------------------------------------+
| Method/Attribute | Purpose |
@ -442,8 +442,9 @@ case. ::
>>> m.span()
(4, 11)
In actual programs, the most common style is to store the :class:`MatchObject`
in a variable, and then check if it was ``None``. This usually looks like::
In actual programs, the most common style is to store the
:ref:`match object <match-objects>` in a variable, and then check if it was
``None``. This usually looks like::
p = re.compile( ... )
m = p.match( 'string goes here' )
@ -460,8 +461,8 @@ Two pattern methods return all of the matches for a pattern.
['12', '11', '10']
: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`
instances as an :term:`iterator`. [#]_ ::
result. The :meth:`finditer` method returns a sequence of
:ref:`match object <match-objects>` instances as an :term:`iterator`. [#]_ ::
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> 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
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
:class:`MatchObject` instance. ::
:ref:`match object <match-objects>` instance. ::
>>> print re.match(r'From\s+', 'Fromage amk')
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
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
:class:`MatchObject` methods all have group 0 as their default argument. Later
we'll see how to express groups that don't capture the span of text that they
match. ::
:ref:`match object <match-objects>` methods all have group 0 as their default
argument. Later we'll see how to express groups that don't capture the span
of text that they match. ::
>>> p = re.compile('(a)b')
>>> 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:
``(?P<name>...)``. *name* is, obviously, the name of the group. Named groups
also behave exactly like capturing groups, and additionally associate a name
with a group. The :class:`MatchObject` methods that deal with capturing groups
all accept either integers that refer to the group by number or strings that
contain the desired group's name. Named groups are still given numbers, so you
can retrieve information about a group in two ways::
with a group. The :ref:`match object <match-objects>` methods that deal with
capturing groups all accept either integers that refer to the group by number
or strings that contain the desired group's name. Named groups are still
given numbers, so you can retrieve information about a group in two ways::
>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> 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* is a function, the function is called for every non-overlapping
occurrence of *pattern*. On each call, the function is passed a
:class:`MatchObject` argument for the match and can use this information to
compute the desired replacement string and return it.
:ref:`match object <match-objects>` argument for the match and can use this
information to compute the desired replacement string and return it.
In the following example, the replacement function translates decimals into
hexadecimal::

View File

@ -1439,7 +1439,7 @@ Sub-commands
different functions which require different kinds of command-line arguments.
:class:`ArgumentParser` supports the creation of such sub-commands with the
: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
command name and any :class:`ArgumentParser` constructor arguments, and
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()
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
call the :class:`FTP` instance should not be used any more (after a call to
:meth:`close` or :meth:`quit` you cannot reopen the connection by issuing
another :meth:`login` method).
closed connection such as after a successful call to :meth:`~FTP.quit`.
After this call the :class:`FTP` instance should not be used any more (after
a call to :meth:`close` or :meth:`~FTP.quit` you cannot reopen the
connection by issuing another :meth:`login` method).
FTP_TLS Objects

View File

@ -106,9 +106,8 @@ loops that truncate the stream.
.. classmethod:: chain.from_iterable(iterable)
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):
# chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
for it in iterables:

View File

@ -102,7 +102,7 @@ An :class:`POP3` instance has the following methods:
.. method:: POP3.pass_(password)
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)

View File

@ -32,7 +32,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
setting will be used).
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
*timeout* was added.

View File

@ -230,7 +230,7 @@ The module :mod:`socket` exports the following constants and functions:
*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
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.
The *family*, *socktype* and *proto* arguments can be optionally specified
in order to narrow the list of addresses returned. Passing zero as a
value for each of these arguments selects the full range of results.
in order to narrow the list of addresses returned. By default, their value
is ``0``, meaning that the full range of results is selected.
The *flags* argument can be one or several of the ``AI_*`` constants,
and will influence how results are computed and returned.
For example, :const:`AI_NUMERICHOST` will disable domain name resolution
and will raise an error if *host* is a domain name.
and will influence how results are computed and returned. Its default value
is ``0``. For example, :const:`AI_NUMERICHOST` will disable 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:

View File

@ -306,8 +306,8 @@ request.
.. method:: RequestHandler.finish()
Called after the :meth:`handle` method to perform any clean-up actions
required. The default implementation does nothing. If :meth:`setup` or
:meth:`handle` raise an exception, this function will not be called.
required. The default implementation does nothing. If :meth:`setup`
raises an exception, this function will not be called.
.. method:: RequestHandler.handle()

View File

@ -407,6 +407,9 @@ is equivalent to ::
statement.
.. index::
single: parameter; function definition
.. _function:
.. _def:
@ -467,12 +470,15 @@ is equivalent to::
def func(): pass
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* ``=``
*expression*, the function is said to have "default parameter values." For a
parameter with a default value, the corresponding argument may be omitted from a
call, in which case the parameter's default value is substituted. If a
When one or more top-level :term:`parameters <parameter>` have the form
*parameter* ``=`` *expression*, the function is said to have "default parameter
values." For a parameter with a default value, the corresponding
: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
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.
.. index::
object: callable
single: call
single: argument; call semantics
.. _calls:
Calls
-----
.. index:: single: call
.. index:: object: callable
A call calls a callable object (e.g., a function) with a possibly empty series
of arguments:
A call calls a callable object (e.g., a :term:`function`) with a possibly empty
series of :term:`arguments <argument>`:
.. productionlist::
call: `primary` "(" [`argument_list` [","]
@ -696,12 +697,15 @@ of arguments:
A trailing comma may be present after the positional and keyword arguments but
does not affect the semantics.
.. index::
single: parameter; call semantics
The primary must evaluate to a callable object (user-defined functions, built-in
functions, methods of built-in objects, class objects, methods of class
instances, and certain class instances themselves are callable; extensions may
define additional callable object types). All argument expressions are
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
arguments, as follows. First, a list of unfilled slots is created for the
@ -1339,8 +1343,8 @@ their suffixes::
.. _operator-summary:
Summary
=======
Operator precedence
===================
.. index:: pair: operator; precedence
@ -1363,9 +1367,9 @@ groups from right to left).
+-----------------------------------------------+-------------------------------------+
| :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, |
| ``<=``, ``>``, ``>=``, ``<>``, ``!=``, ``==`` | |
+-----------------------------------------------+-------------------------------------+
@ -1391,7 +1395,7 @@ groups from right to left).
+-----------------------------------------------+-------------------------------------+
| ``(expressions...)``, | Binding or tuple display, |
| ``[expressions...]``, | list display, |
| ``{key:datum...}``, | dictionary display, |
| ``{key: value...}``, | dictionary display, |
| ```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.
.. _setting-envvars:
Excursus: Setting environment variables
---------------------------------------

View File

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

View File

@ -732,6 +732,9 @@ class Aifc_write:
self._patchheader()
def close(self):
if self._file is None:
return
try:
self._ensure_header_written(0)
if self._datawritten & 1:
# quick pad to even size
@ -745,9 +748,12 @@ class Aifc_write:
if self._comp:
self._comp.CloseCompressor()
self._comp = None
finally:
# Prevent ref cycles
self._convert = None
self._file.close()
f = self._file
self._file = None
f.close()
#
# Internal methods.

View File

@ -37,7 +37,6 @@ __version__ = "2.6"
from operator import attrgetter
import sys
import os
import urllib
import UserDict
import urlparse

View File

@ -246,9 +246,9 @@ class BitFieldTest(unittest.TestCase):
_fields_ = [("a", c_uint32, 32)]
x = X()
x.a = 10
self.assertEquals(x.a, 10)
self.assertEqual(x.a, 10)
x.a = 0xFDCBA987
self.assertEquals(x.a, 0xFDCBA987)
self.assertEqual(x.a, 0xFDCBA987)
@unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required")
def test_uint64(self):
@ -256,9 +256,9 @@ class BitFieldTest(unittest.TestCase):
_fields_ = [("a", c_uint64, 64)]
x = X()
x.a = 10
self.assertEquals(x.a, 10)
self.assertEqual(x.a, 10)
x.a = 0xFEDCBA9876543211
self.assertEquals(x.a, 0xFEDCBA9876543211)
self.assertEqual(x.a, 0xFEDCBA9876543211)
if __name__ == "__main__":
unittest.main()

View File

@ -5,7 +5,7 @@ the package, and perhaps a particular module inside it.
import curses
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
builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
comment = any("COMMENT", [r"#[^\n]*"])
sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR)?"
sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?"
dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?'
sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
return kw + "|" + builtin + "|" + comment + "|" + string +\
"|" + any("SYNC", [r"\n"])

View File

@ -172,13 +172,13 @@ class EditorWindow(object):
'recent-files.lst')
self.text_frame = text_frame = Frame(top)
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 = {
'name': 'text',
'padx': 5,
'wrap': 'none',
'width': self.width,
'height': idleConf.GetOption('main', 'EditorWindow', 'height')}
'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')}
if TkVersion >= 8.5:
# Starting with tk 8.5 we have to set the new tabstyle option
# 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'):
fontWeight='bold'
text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
idleConf.GetOption('main', 'EditorWindow', 'font-size'),
idleConf.GetOption('main', 'EditorWindow',
'font-size', type='int'),
fontWeight))
text_frame.pack(side=LEFT, 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'):
fontWeight='bold'
self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'),
idleConf.GetOption('main','EditorWindow','font-size'),
idleConf.GetOption('main','EditorWindow','font-size',
type='int'),
fontWeight))
def RemoveKeybindings(self):
@ -1609,7 +1611,7 @@ class IndentSearcher(object):
try:
try:
_tokenize.tokenize(self.readline, self.tokeneater)
except _tokenize.TokenError:
except (_tokenize.TokenError, SyntaxError):
# since we cut off the tokenizer early, we can trigger
# spurious errors
pass

View File

@ -32,7 +32,8 @@ class FormatParagraph:
self.editwin = None
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
first, last = self.editwin.get_selection_indices()
if first and last:

View File

@ -947,7 +947,7 @@ class ConfigDialog(Toplevel):
self.listFontName.select_anchor(currentFontIndex)
##font size dropdown
fontSize=idleConf.GetOption('main','EditorWindow','font-size',
default='10')
type='int', default='10')
self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
'16','18','20','22'),fontSize )
##fontWeight
@ -1033,10 +1033,13 @@ class ConfigDialog(Toplevel):
self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave',
default=0, type='bool'))
#initial window size
self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
self.winWidth.set(idleConf.GetOption('main','EditorWindow','width',
type='int'))
self.winHeight.set(idleConf.GetOption('main','EditorWindow','height',
type='int'))
#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
self.encoding.set(idleConf.GetOption('main', 'EditorWindow',
'encoding', default='none'))

View File

@ -237,13 +237,28 @@ class IdleConf:
printed to stderr.
"""
try:
if self.userCfg[configType].has_option(section,option):
return self.userCfg[configType].Get(section, option,
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,
type=type, raw=raw)
else: #returning default, print warning
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'

View File

@ -200,6 +200,27 @@ if sys.platform != 'win32':
return c1, c2
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

View File

@ -319,8 +319,8 @@ class _fileobject(object):
self._wbuf.append(data)
self._wbuf_len += len(data)
if (self._wbufsize == 0 or
self._wbufsize == 1 and '\n' in data or
self._wbuf_len >= self._wbufsize):
(self._wbufsize == 1 and '\n' in data) or
(self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)):
self.flush()
def writelines(self, list):

View File

@ -313,17 +313,19 @@ class SSLSocket(socket):
self.cert_reqs, self.ssl_version,
self.ca_certs, self.ciphers)
try:
if return_errno:
rc = socket.connect_ex(self, addr)
else:
rc = None
socket.connect(self, addr)
if not rc:
if self.do_handshake_on_connect:
self.do_handshake()
except socket_error as e:
if return_errno:
return e.errno
else:
self._sslobj = None
raise e
self._connected = True
return 0
return rc
except socket_error:
self._sslobj = None
raise
def connect(self, addr):
"""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,
_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
attribute.
@ -1308,7 +1308,7 @@ class Popen(object):
except _os_error as e:
if _deadstate is not None:
self.returncode = _deadstate
if e.errno == errno.ECHILD:
if e.errno == _ECHILD:
# This happens if SIGCLD is set to be ignored or
# waiting for child processes has otherwise been
# disabled for our process. This child is dead, we

View File

@ -32,7 +32,7 @@ Verbosity
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
-f/--fromfile -- read names of tests to run from a file (see below)
-x/--exclude -- arguments are tests to *exclude*
@ -258,7 +258,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
try:
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:',
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks',
'exclude', 'single', 'slow', 'randomize', 'fromfile=', 'findleaks',
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
'multiprocess=', 'slaveargs=', 'forever', 'header'])

View File

@ -106,6 +106,13 @@ class AIFCTest(unittest.TestCase):
self.assertEqual(testfile.closed, False)
f.close()
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):

View File

@ -680,6 +680,8 @@ class BuiltinTest(unittest.TestCase):
# Test input() later, together with raw_input
# test_int(): see test_int.py for int() tests.
def test_intern(self):
self.assertRaises(TypeError, intern)
# This fails if the test is run twice with a constant string,

View File

@ -261,7 +261,7 @@ class CalendarTestCase(unittest.TestCase):
return
calendar.LocaleHTMLCalendar(locale='').formatmonthname(2010, 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):
# 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 os
import shutil
import sys
import unittest
from test.test_support import run_unittest, TESTFN
def fsdecode(s):
return unicode(s, sys.getfilesystemencoding())
class GlobTests(unittest.TestCase):
@ -31,7 +36,8 @@ class GlobTests(unittest.TestCase):
self.mktemp('a', 'bcd', 'efg', 'ha')
if hasattr(os, 'symlink'):
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):
shutil.rmtree(self.tempdir)
@ -44,10 +50,16 @@ class GlobTests(unittest.TestCase):
p = os.path.join(self.tempdir, pattern)
res = glob.glob(p)
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
def assertSequencesEqual_noorder(self, l1, l2):
l1 = list(l1)
l2 = list(l2)
self.assertEqual(set(l1), set(l2))
self.assertEqual(sorted(l1), sorted(l2))
def test_glob_literal(self):
eq = self.assertSequencesEqual_noorder
@ -56,15 +68,19 @@ class GlobTests(unittest.TestCase):
eq(self.glob('aab'), [self.norm('aab')])
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
# returns unicode filenames
uniset = set([unicode])
tmp = os.listdir(u'.')
if set(type(x) for x in tmp) == uniset:
u1 = glob.glob(u'*')
u2 = glob.glob(u'./*')
self.assertEqual(set(type(r) for r in u1), uniset)
self.assertEqual(set(type(r) for r in u2), uniset)
tmp = os.listdir(fsdecode(os.curdir))
if {type(x) for x in tmp} == {unicode}:
res = glob.glob(u'*')
self.assertEqual({type(r) for r in res}, {unicode})
res = glob.glob(os.path.join(fsdecode(os.curdir), u'*'))
self.assertEqual({type(r) for r in res}, {unicode})
def test_glob_one_directory(self):
eq = self.assertSequencesEqual_noorder
@ -93,21 +109,58 @@ class GlobTests(unittest.TestCase):
eq(self.glob('*', '*a'), [])
eq(self.glob('a', '*', '*', '*a'),
[self.norm('a', 'bcd', 'efg', 'ha')])
eq(self.glob('?a?', '*F'), map(self.norm, [os.path.join('aaa', 'zzzF'),
os.path.join('aab', 'F')]))
eq(self.glob('?a?', '*F'), [self.norm('aaa', 'zzzF'),
self.norm('aab', 'F')])
def test_glob_directory_with_trailing_slash(self):
# We are verifying that when there is wildcard pattern which
# ends with os.sep doesn't blow up.
res = glob.glob(self.tempdir + '*' + os.sep)
self.assertEqual(len(res), 1)
# either of these results are reasonable
self.assertIn(res[0], [self.tempdir, self.tempdir + os.sep])
# Patterns ending with a slash shouldn't match non-dirs
res = glob.glob(self.norm('Z*Z') + os.sep)
self.assertEqual(res, [])
res = glob.glob(self.norm('ZZZ') + os.sep)
self.assertEqual(res, [])
# 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):
if hasattr(os, 'symlink'):
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('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('sym2'), [self.norm('sym2')])

View File

@ -5,6 +5,7 @@ import os
import py_compile
import random
import stat
import struct
import sys
import unittest
import textwrap
@ -350,6 +351,46 @@ class ImportTests(unittest.TestCase):
del sys.path[0]
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):
# Test that the `co_filename` attribute on code objects always points

View File

@ -1,6 +1,7 @@
import sys
import unittest
from test import test_support
from test.test_support import run_unittest, have_unicode
import math
@ -44,7 +45,27 @@ if have_unicode:
(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):
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+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):
# Test __int__()
class ClassicMissingMethods:

View File

@ -1,10 +1,11 @@
import unittest
from test import test_support
import sys
import random
import math
from test import test_int, test_support
# Used for lazy formatting of failure messages
class Frm(object):
def __init__(self, format, *args):
@ -78,8 +79,9 @@ if test_support.have_unicode:
(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).
# 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)
conn.send(None)
time.sleep(.1)
self.assertEqual(poll(TIMEOUT1), True)
self.assertTimingAlmostEqual(poll.elapsed, 0)

View File

@ -14,7 +14,7 @@ class MutexTest(unittest.TestCase):
m.lock(called_by_mutex2, "eggs")
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(ready_for_2,
"called_by_mutex2 called too soon")

View File

@ -962,8 +962,8 @@ class FileObjectClassTestCase(SocketConnectedTest):
def tearDown(self):
self.serv_file.close()
self.assertTrue(self.serv_file.closed)
self.serv_file = None
SocketConnectedTest.tearDown(self)
self.serv_file = None
def clientSetUp(self):
SocketConnectedTest.clientSetUp(self)
@ -1151,6 +1151,64 @@ class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
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):

View File

@ -280,6 +280,34 @@ class NetworkedTests(unittest.TestCase):
finally:
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")
def test_makefile_close(self):
# Issue #5238: creating a file-like object with makefile() shouldn't

View File

@ -297,25 +297,20 @@ class MiscReadTest(CommonReadTest):
def test_extract_hardlink(self):
# 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)
try:
tar.extract("ustar/lnktype", TEMPDIR)
except EnvironmentError, e:
if e.errno == errno.ENOENT:
self.fail("hardlink not extracted properly")
self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype"))
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)
try:
tar.extract("ustar/symtype", TEMPDIR)
except EnvironmentError, e:
if e.errno == errno.ENOENT:
self.fail("symlink not extracted properly")
data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read()
self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/symtype"))
with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f:
data = f.read()
self.assertEqual(md5sum(data), md5_regtype)
def test_extractall(self):
@ -858,7 +853,7 @@ class WriteTest(WriteTestBase):
tar = tarfile.open(tmpname, "r")
for t in tar:
self.assert_(t.name == "." or t.name.startswith("./"))
self.assertTrue(t.name == "." or t.name.startswith("./"))
tar.close()
finally:
os.chdir(cwd)

View File

@ -1336,7 +1336,7 @@ class RequestTests(unittest.TestCase):
req = Request(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
interface even though HTTPError is a subclass of URLError.
@ -1347,6 +1347,22 @@ def test_HTTPError_interface():
'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):
from test import test_urllib2
test_support.run_doctest(test_urllib2, verbose)

View File

@ -5,7 +5,9 @@ import urllib2
import BaseHTTPServer
import unittest
import hashlib
from test import test_support
mimetools = test_support.import_module('mimetools', deprecated=True)
threading = test_support.import_module('threading')
@ -346,6 +348,12 @@ class TestUrlopen(BaseTestCase):
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):
handler = GetRequestHandler(responses)

View File

@ -446,10 +446,43 @@ class UrlParseTestCase(unittest.TestCase):
p1 = urlparse.urlsplit('tel:+31-641044153')
self.assertEqual(p1.scheme, 'tel')
self.assertEqual(p1.path, '+31-641044153')
p2 = urlparse.urlsplit('tel:+31641044153')
self.assertEqual(p2.scheme, 'tel')
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):
"""Check handling of non-integer ports."""
p = urlparse.urlsplit("http://www.example.net:foo")

View File

@ -314,6 +314,35 @@ class LocalWinregTests(BaseWinregTests):
finally:
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")
class RemoteWinregTests(BaseWinregTests):

View File

@ -173,6 +173,9 @@ class HTTPError(URLError, addinfourl):
def reason(self):
return self.msg
def info(self):
return self.hdrs
# copied from cookielib.py
_cut_port_re = re.compile(r":\d+$")
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']
uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
'mms', '', 'sftp']
'mms', '', 'sftp', 'tel']
# These are not actually used anymore, but should stay for backwards
# compatibility. (They are undocumented, but have a public-looking name.)

View File

@ -499,6 +499,7 @@ Tamito Kajiyama
Peter van Kampen
Jacob Kaplan-Moss
Piotr Kasprzyk
Anton Kasyanov
Lou Kates
Hiroaki Kawai
Sebastien Keim

View File

@ -9,6 +9,21 @@ What's New in Python 2.7.4
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
chain, the object could remain reachable through its weakref even though
its refcount had dropped to zero.
@ -160,11 +175,32 @@ Core and Builtins
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 #16597: In buffered and text IO, call close() on the underlying stream
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.
(patch by Serhiy Storchaka)
@ -394,6 +430,9 @@ Library
- Issue #12157: Make pool.map() empty iterables correctly. Initial
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
options. Patch by Roger Serwy.
@ -560,6 +599,11 @@ Extension Modules
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
starting with a ".". Patch by Sebastian Kreft.

View File

@ -844,11 +844,11 @@ static int _call_function_pointer(int flags,
space[0] = errno;
errno = temp;
}
Py_XDECREF(error_object);
#ifdef WITH_THREAD
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS
#endif
Py_XDECREF(error_object);
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
if (dwExceptionCode) {

View File

@ -2546,7 +2546,7 @@ PyDoc_STRVAR(pattern_match_doc,
PyDoc_STRVAR(pattern_search_doc,
"search(string[, pos[, endpos]]) --> match object or None.\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,
"split(string[, maxsplit = 0]) --> list.\n\
@ -3545,14 +3545,54 @@ match_deepcopy(MatchObject* self, PyObject* memo)
#endif
}
static struct PyMethodDef match_methods[] = {
{"group", (PyCFunction) match_group, METH_VARARGS},
{"start", (PyCFunction) match_start, METH_VARARGS},
{"end", (PyCFunction) match_end, METH_VARARGS},
{"span", (PyCFunction) match_span, METH_VARARGS},
{"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS},
{"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS},
{"expand", (PyCFunction) match_expand, METH_O},
PyDoc_STRVAR(match_doc,
"The result of re.match() and re.search().\n\
Match objects always have a boolean value of True.");
PyDoc_STRVAR(match_group_doc,
"group([group1, ...]) -> str or tuple.\n\
Return subgroup(s) of the match by indices or names.\n\
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},
{"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
{NULL, NULL}
@ -3632,7 +3672,7 @@ static PyTypeObject Match_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT,
0, /* tp_doc */
match_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
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,
&x, &base))
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);
}
if (base == -909)
return PyNumber_Int(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,
&x, &base))
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);
}
if (base == -909)
return PyNumber_Long(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;
switch (typ) {
case REG_DWORD:
if (value != Py_None && !PyInt_Check(value))
if (value != Py_None &&
!(PyInt_Check(value) || PyLong_Check(value)))
return FALSE;
*retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1);
if (*retDataBuf==NULL){
@ -765,10 +766,10 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
DWORD zero = 0;
memcpy(*retDataBuf, &zero, sizeof(DWORD));
}
else
memcpy(*retDataBuf,
&PyInt_AS_LONG((PyIntObject *)value),
sizeof(DWORD));
else {
DWORD d = PyLong_AsUnsignedLong(value);
memcpy(*retDataBuf, &d, sizeof(DWORD));
}
break;
case REG_SZ:
case REG_EXPAND_SZ:
@ -917,9 +918,9 @@ Reg2Py(char *retDataBuf, DWORD retDataSize, DWORD typ)
switch (typ) {
case REG_DWORD:
if (retDataSize == 0)
obData = Py_BuildValue("i", 0);
obData = Py_BuildValue("k", 0);
else
obData = Py_BuildValue("i",
obData = Py_BuildValue("k",
*(int *)retDataBuf);
break;
case REG_SZ:

View File

@ -904,10 +904,9 @@ open_exclusive(char *filename, mode_t mode)
remove the file. */
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;
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
/* 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;
}
#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
object WITH INCREMENTED REFERENCE COUNT. If there's a matching
byte-compiled file, use that instead. */
@ -1006,6 +1037,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
char *cpathname;
PyCodeObject *co = NULL;
PyObject *m;
time_t mtime;
if (fstat(fileno(fp), &st) != 0) {
PyErr_Format(PyExc_RuntimeError,
@ -1013,13 +1045,21 @@ load_source_module(char *name, char *pathname, FILE *fp)
pathname);
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
in 4 bytes. Since the code only does an equality comparison,
ordering is not important and we can safely ignore the higher bits
(collisions are extremely unlikely).
*/
st.st_mtime &= 0xFFFFFFFF;
mtime &= 0xFFFFFFFF;
}
buf = PyMem_MALLOC(MAXPATHLEN+1);
if (buf == NULL) {
@ -1028,7 +1068,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
cpathname = make_compiled_pathname(pathname, buf,
(size_t)MAXPATHLEN + 1);
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);
fclose(fpc);
if (co == NULL)
@ -1053,7 +1093,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
if (b < 0)
goto error_exit;
if (!b)
write_compiled_module(co, cpathname, &st);
write_compiled_module(co, cpathname, &st, mtime);
}
}
m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);