"Copyright © 2001-2013 Python Software Foundation; All Rights
"Copyright © 2001-2014 Python Software Foundation; All Rights
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
diff -r 3a1db0d2747e Doc/reference/datamodel.rst
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -207,7 +207,7 @@
single: True
These represent the truth values False and True. The two objects
- representing the values False and True are the only Boolean objects.
+ representing the values ``False`` and ``True`` are the only Boolean objects.
The Boolean type is a subtype of plain integers, and Boolean values
behave like the values 0 and 1, respectively, in almost all contexts,
the exception being that when converted to a string, the strings
@@ -486,44 +486,39 @@
+-----------------------+-------------------------------+-----------+
| Attribute | Meaning | |
+=======================+===============================+===========+
- | :attr:`func_doc` | The function's documentation | Writable |
- | | string, or ``None`` if | |
- | | unavailable | |
+ | :attr:`__doc__` | The function's documentation | Writable |
+ | :attr:`func_doc` | string, or ``None`` if | |
+ | | unavailable. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`__doc__` | Another way of spelling | Writable |
- | | :attr:`func_doc` | |
- +-----------------------+-------------------------------+-----------+
- | :attr:`func_name` | The function's name | Writable |
- +-----------------------+-------------------------------+-----------+
- | :attr:`__name__` | Another way of spelling | Writable |
- | | :attr:`func_name` | |
+ | :attr:`__name__` | The function's name. | Writable |
+ | :attr:`func_name` | | |
+-----------------------+-------------------------------+-----------+
| :attr:`__module__` | The name of the module the | Writable |
| | function was defined in, or | |
| | ``None`` if unavailable. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`func_defaults` | A tuple containing default | Writable |
- | | argument values for those | |
+ | :attr:`__defaults__` | A tuple containing default | Writable |
+ | :attr:`func_defaults` | argument values for those | |
| | arguments that have defaults, | |
| | or ``None`` if no arguments | |
- | | have a default value | |
+ | | have a default value. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`func_code` | The code object representing | Writable |
- | | the compiled function body. | |
+ | :attr:`__code__` | The code object representing | Writable |
+ | :attr:`func_code` | the compiled function body. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`func_globals` | A reference to the dictionary | Read-only |
- | | that holds the function's | |
+ | :attr:`__globals__` | A reference to the dictionary | Read-only |
+ | :attr:`func_globals` | that holds the function's | |
| | global variables --- the | |
| | global namespace of the | |
| | module in which the function | |
| | was defined. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`func_dict` | The namespace supporting | Writable |
- | | arbitrary function | |
+ | :attr:`__dict__` | The namespace supporting | Writable |
+ | :attr:`func_dict` | arbitrary function | |
| | attributes. | |
+-----------------------+-------------------------------+-----------+
- | :attr:`func_closure` | ``None`` or a tuple of cells | Read-only |
- | | that contain bindings for the | |
+ | :attr:`__closure__` | ``None`` or a tuple of cells | Read-only |
+ | :attr:`func_closure` | that contain bindings for the | |
| | function's free variables. | |
+-----------------------+-------------------------------+-----------+
@@ -532,6 +527,12 @@
.. versionchanged:: 2.4
``func_name`` is now writable.
+ .. versionchanged:: 2.6
+ The double-underscore attributes ``__closure__``, ``__code__``,
+ ``__defaults__``, and ``__globals__`` were introduced as aliases for
+ the corresponding ``func_*`` attributes for forwards compatibility
+ with Python 3.
+
Function objects also support getting and setting arbitrary attributes, which
can be used, for example, to attach metadata to functions. Regular attribute
dot-notation is used to get and set such attributes. *Note that the current
@@ -542,16 +543,21 @@
code object; see the description of internal types below.
.. index::
- single: func_doc (function attribute)
single: __doc__ (function attribute)
single: __name__ (function attribute)
single: __module__ (function attribute)
single: __dict__ (function attribute)
+ single: __defaults__ (function attribute)
+ single: __code__ (function attribute)
+ single: __globals__ (function attribute)
+ single: __closure__ (function attribute)
+ single: func_doc (function attribute)
+ single: func_name (function attribute)
+ single: func_dict (function attribute)
single: func_defaults (function attribute)
- single: func_closure (function attribute)
single: func_code (function attribute)
single: func_globals (function attribute)
- single: func_dict (function attribute)
+ single: func_closure (function attribute)
pair: global; namespace
User-defined methods
diff -r 3a1db0d2747e Doc/tools/dailybuild.py
--- a/Doc/tools/dailybuild.py
+++ b/Doc/tools/dailybuild.py
@@ -29,6 +29,7 @@
BUILDROOT = '/home/gbrandl/docbuild'
+SPHINXBUILD = os.path.join(BUILDROOT, 'sphinx-env/bin/sphinx-build')
WWWROOT = '/data/ftp.python.org/pub/docs.python.org'
BRANCHES = [
@@ -43,11 +44,11 @@
print 'Doc autobuild started in %s' % checkout
os.chdir(checkout)
print 'Running hg pull --update'
- os.system('/usr/local/bin/hg pull --update')
+ os.system('hg pull --update')
print 'Running make autobuild'
maketarget = 'autobuild-' + ('html' if quick else
('dev' if isdev else 'stable'))
- if os.WEXITSTATUS(os.system('cd Doc; make %s' % maketarget)) == 2:
+ if os.WEXITSTATUS(os.system('cd Doc; make SPHINXBUILD=%s %s' % (SPHINXBUILD, maketarget))) == 2:
print '*' * 80
return
print 'Copying HTML files to %s' % target
diff -r 3a1db0d2747e Doc/tools/sphinx-build.py
--- a/Doc/tools/sphinx-build.py
+++ b/Doc/tools/sphinx-build.py
@@ -15,13 +15,13 @@
if __name__ == '__main__':
- if sys.version_info[:3] < (2, 4, 0):
- print >>sys.stderr, """\
-Error: Sphinx needs to be executed with Python 2.4 or newer
+ if sys.version_info[:3] < (2, 4, 0) or sys.version_info[:3] > (3, 0, 0):
+ sys.stderr.write("""\
+Error: Sphinx needs to be executed with Python 2.4 or newer (not 3.x though).
(If you run this from the Makefile, you can set the PYTHON variable
to the path of an alternative interpreter executable, e.g.,
``make html PYTHON=python2.5``).
-"""
+""")
sys.exit(1)
from sphinx import main
diff -r 3a1db0d2747e Doc/tools/sphinxext/pyspecific.py
--- a/Doc/tools/sphinxext/pyspecific.py
+++ b/Doc/tools/sphinxext/pyspecific.py
@@ -184,11 +184,11 @@
'bltin-null-object', 'bltin-type-objects', 'booleans',
'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound',
'context-managers', 'continue', 'conversions', 'customization', 'debugger',
- 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel',
+ 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'exec', 'execmodel',
'exprlists', 'floating', 'for', 'formatstrings', 'function', 'global',
'id-classes', 'identifiers', 'if', 'imaginary', 'import', 'in', 'integers',
'lambda', 'lists', 'naming', 'numbers', 'numeric-types',
- 'objects', 'operator-summary', 'pass', 'power', 'raise', 'return',
+ 'objects', 'operator-summary', 'pass', 'power', 'print', 'raise', 'return',
'sequence-types', 'shifting', 'slicings', 'specialattrs', 'specialnames',
'string-methods', 'strings', 'subscriptions', 'truth', 'try', 'types',
'typesfunctions', 'typesmapping', 'typesmethods', 'typesmodules',
diff -r 3a1db0d2747e Doc/tools/sphinxext/static/version_switch.js
--- a/Doc/tools/sphinxext/static/version_switch.js
+++ b/Doc/tools/sphinxext/static/version_switch.js
@@ -2,7 +2,8 @@
'use strict';
var all_versions = {
- '3.4': 'dev (3.4)',
+ '3.5': 'dev (3.5)',
+ '3.4': '3.4',
'3.3': '3.3',
'3.2': '3.2',
'2.7': '2.7',
diff -r 3a1db0d2747e Doc/tools/sphinxext/susp-ignored.csv
--- a/Doc/tools/sphinxext/susp-ignored.csv
+++ b/Doc/tools/sphinxext/susp-ignored.csv
@@ -8,6 +8,10 @@
extending/extending,,:myfunction,"PyArg_ParseTuple(args, ""D:myfunction"", &c);"
extending/newtypes,,:call,"if (!PyArg_ParseTuple(args, ""sss:call"", &arg1, &arg2, &arg3)) {"
extending/windows,,:initspam,/export:initspam
+faq/programming,,:reduce,"print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,"
+faq/programming,,:reduce,"Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,"
+faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr("
+faq/programming,,::,for x in sequence[::-1]:
howto/cporting,,:encode,"if (!PyArg_ParseTuple(args, ""O:encode_object"", &myobj))"
howto/cporting,,:say,"if (!PyArg_ParseTuple(args, ""U:say_hello"", &name))"
howto/curses,,:black,"They are: 0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and"
@@ -39,10 +43,15 @@
howto/logging,,:logger,severity:logger name:message
howto/logging,,:message,severity:logger name:message
howto/logging,,:This,DEBUG:root:This message should go to the log file
+howto/pyporting,75,::,# make sure to use :: Python *and* :: Python :: 3 so
+howto/pyporting,75,::,"'Programming Language :: Python',"
+howto/pyporting,75,::,'Programming Language :: Python :: 3'
howto/regex,,::,
howto/regex,,:foo,(?:foo)
howto/urllib2,,:example,"for example ""joe@password:example.com"""
library/audioop,,:ipos,"# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],"
+library/bisect,,:hi,all(val >= x for val in a[i:hi])
+library/bisect,,:hi,all(val > x for val in a[i:hi])
library/cookie,,`,!#$%&'*+-.^_`|~
library/datetime,,:MM,
library/datetime,,:SS,
@@ -92,8 +101,9 @@
library/profile,,:lineno,filename:lineno(function)
library/pyexpat,,:elem1,<py:elem1 />
library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">"
-library/smtplib,,:port,"as well as a regular host:port server."
+library/smtplib,,:port,method must support that as well as a regular host:port
library/socket,,::,'5aef:2b::8'
+library/socket,,::,"(10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))]"
library/sqlite3,,:memory,
library/sqlite3,,:who,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})"
library/sqlite3,,:age,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})"
@@ -105,6 +115,7 @@
library/ssl,,:Some,"Locality Name (eg, city) []:Some City"
library/ssl,,:US,Country Name (2 letter code) [AU]:US
library/stdtypes,,:len,s[len(s):len(s)]
+library/stdtypes,,:end,s[start:end]
library/string,,:end,s[start:end]
library/subprocess,,`,"output=`mycmd myarg`"
library/subprocess,,`,"output=`dmesg | grep hda`"
@@ -116,6 +127,7 @@
library/turtle,,::,Example::
library/urllib,,:port,:port
library/urllib2,,:password,"""joe:password@python.org"""
+library/urllib2,,:close,Connection:close
library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678
library/xmlrpclib,,:pass,http://user:pass@host:port/path
library/xmlrpclib,,:pass,user:pass
@@ -123,6 +135,10 @@
license,,`,THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
license,,:zooko,mailto:zooko@zooko.com
license,,`,THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+license,,`,* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+license,,`,* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+license,,`,"``Software''), to deal in the Software without restriction, including"
+license,,`,"THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,"
reference/datamodel,,:step,a[i:j:step]
reference/datamodel,,:max,
reference/expressions,,:index,x[index:index]
@@ -150,6 +166,7 @@
using/cmdline,,:message,action:message:category:module:line
using/cmdline,,:module,action:message:category:module:line
using/cmdline,,:errorhandler,:errorhandler
+using/unix,,:Packaging,http://en.opensuse.org/Portal:Packaging
whatsnew/2.0,418,:len,
whatsnew/2.3,,::,
whatsnew/2.3,,:config,
@@ -163,24 +180,8 @@
whatsnew/2.5,,:memory,:memory:
whatsnew/2.5,,:step,[start:stop:step]
whatsnew/2.5,,:stop,[start:stop:step]
-faq/programming,,:reduce,"print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,"
-faq/programming,,:reduce,"Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,"
-faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr("
-faq/programming,,::,for x in sequence[::-1]:
-library/bisect,,:hi,all(val >= x for val in a[i:hi])
-library/bisect,,:hi,all(val > x for val in a[i:hi])
-library/socket,,::,"(10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))]"
-library/stdtypes,,:end,s[start:end]
-license,,`,* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-license,,`,* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-license,,`,"``Software''), to deal in the Software without restriction, including"
-license,,`,"THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,"
whatsnew/2.7,735,:Sunday,'2009:4:Sunday'
whatsnew/2.7,862,::,"export PYTHONWARNINGS=all,error:::Cookie:0"
whatsnew/2.7,862,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0"
whatsnew/2.7,,::,>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo')
whatsnew/2.7,,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]',"
-howto/pyporting,75,::,# make sure to use :: Python *and* :: Python :: 3 so
-howto/pyporting,75,::,"'Programming Language :: Python',"
-howto/pyporting,75,::,'Programming Language :: Python :: 3'
-library/urllib2,67,:close,Connection:close
diff -r 3a1db0d2747e Doc/tutorial/controlflow.rst
--- a/Doc/tutorial/controlflow.rst
+++ b/Doc/tutorial/controlflow.rst
@@ -19,14 +19,14 @@
>>> x = int(raw_input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
- ... x = 0
- ... print 'Negative changed to zero'
+ ... x = 0
+ ... print 'Negative changed to zero'
... elif x == 0:
- ... print 'Zero'
+ ... print 'Zero'
... elif x == 1:
- ... print 'Single'
+ ... print 'Single'
... else:
- ... print 'More'
+ ... print 'More'
...
More
diff -r 3a1db0d2747e Doc/tutorial/inputoutput.rst
--- a/Doc/tutorial/inputoutput.rst
+++ b/Doc/tutorial/inputoutput.rst
@@ -358,47 +358,64 @@
Reference for a complete guide to file objects.
-.. _tut-pickle:
+.. _tut-json:
-The :mod:`pickle` Module
-------------------------
+Saving structured data with :mod:`json`
+---------------------------------------
-.. index:: module: pickle
+.. index:: module: json
-Strings can easily be written to and read from a file. Numbers take a bit more
+Strings can easily be written to and read from a file. Numbers take a bit more
effort, since the :meth:`read` method only returns strings, which will have to
be passed to a function like :func:`int`, which takes a string like ``'123'``
-and returns its numeric value 123. However, when you want to save more complex
-data types like lists, dictionaries, or class instances, things get a lot more
-complicated.
+and returns its numeric value 123. When you want to save more complex data
+types like nested lists and dictionaries, parsing and serializing by hand
+becomes complicated.
-Rather than have users be constantly writing and debugging code to save
-complicated data types, Python provides a standard module called :mod:`pickle`.
-This is an amazing module that can take almost any Python object (even some
-forms of Python code!), and convert it to a string representation; this process
-is called :dfn:`pickling`. Reconstructing the object from the string
-representation is called :dfn:`unpickling`. Between pickling and unpickling,
-the string representing the object may have been stored in a file or data, or
+Rather than having users constantly writing and debugging code to save
+complicated data types to files, Python allows you to use the popular data
+interchange format called `JSON (JavaScript Object Notation)
+<http://json.org>`_. The standard module called :mod:`json` can take Python
+data hierarchies, and convert them to string representations; this process is
+called :dfn:`serializing`. Reconstructing the data from the string representation
+is called :dfn:`deserializing`. Between serializing and deserializing, the
+string representing the object may have been stored in a file or data, or
sent over a network connection to some distant machine.
-If you have an object ``x``, and a file object ``f`` that's been opened for
-writing, the simplest way to pickle the object takes only one line of code::
+.. note::
+ The JSON format is commonly used by modern applications to allow for data
+ exchange. Many programmers are already familiar with it, which makes
+ it a good choice for interoperability.
- pickle.dump(x, f)
+If you have an object ``x``, you can view its JSON string representation with a
+simple line of code::
-To unpickle the object again, if ``f`` is a file object which has been opened
-for reading::
+ >>> json.dumps([1, 'simple', 'list'])
+ '[1, "simple", "list"]'
- x = pickle.load(f)
+Another variant of the :func:`~json.dumps` function, called :func:`~json.dump`,
+simply serializes the object to a file. So if ``f`` is a :term:`file object`
+opened for writing, we can do this::
-(There are other variants of this, used when pickling many objects or when you
-don't want to write the pickled data to a file; consult the complete
-documentation for :mod:`pickle` in the Python Library Reference.)
+ json.dump(x, f)
-:mod:`pickle` is the standard way to make Python objects which can be stored and
-reused by other programs or by a future invocation of the same program; the
-technical term for this is a :dfn:`persistent` object. Because :mod:`pickle` is
-so widely used, many authors who write Python extensions take care to ensure
-that new data types such as matrices can be properly pickled and unpickled.
+To decode the object again, if ``f`` is a :term:`file object` which has
+been opened for reading::
+ x = json.load(f)
+This simple serialization technique can handle lists and dictionaries, but
+serializing arbitrary class instances in JSON requires a bit of extra effort.
+The reference for the :mod:`json` module contains an explanation of this.
+
+.. seealso::
+
+ :mod:`pickle` - the pickle module
+
+ Contrary to :ref:`JSON <tut-json>`, *pickle* is a protocol which allows
+ the serialization of arbitrarily complex Python objects. As such, it is
+ specific to Python and cannot be used to communicate with applications
+ written in other languages. It is also insecure by default:
+ deserializing pickle data coming from an untrusted source can execute
+ arbitrary code, if the data was crafted by a skilled attacker.
+
diff -r 3a1db0d2747e Doc/whatsnew/2.4.rst
--- a/Doc/whatsnew/2.4.rst
+++ b/Doc/whatsnew/2.4.rst
@@ -846,7 +846,7 @@
['A', 'b', 'c', 'D']
Finally, the *reverse* parameter takes a Boolean value. If the value is true,
- the list will be sorted into reverse order. Instead of ``L.sort() ;
+ the list will be sorted into reverse order. Instead of ``L.sort();
L.reverse()``, you can now write ``L.sort(reverse=True)``.
The results of sorting are now guaranteed to be stable. This means that two
diff -r 3a1db0d2747e Doc/whatsnew/2.5.rst
--- a/Doc/whatsnew/2.5.rst
+++ b/Doc/whatsnew/2.5.rst
@@ -286,7 +286,7 @@
:mod:`pkg.string` and look for the standard module; generally you had to look at
the contents of ``sys.modules``, which is slightly unclean. Holger Krekel's
:mod:`py.std` package provides a tidier way to perform imports from the standard
-library, ``import py ; py.std.string.join()``, but that package isn't available
+library, ``import py; py.std.string.join()``, but that package isn't available
on all Python installations.
Reading code which relies on relative imports is also less clear, because a
diff -r 3a1db0d2747e Doc/whatsnew/2.6.rst
--- a/Doc/whatsnew/2.6.rst
+++ b/Doc/whatsnew/2.6.rst
@@ -1887,7 +1887,7 @@
>>> dq=deque(maxlen=3)
>>> dq
deque([], maxlen=3)
- >>> dq.append(1) ; dq.append(2) ; dq.append(3)
+ >>> dq.append(1); dq.append(2); dq.append(3)
>>> dq
deque([1, 2, 3], maxlen=3)
>>> dq.append(4)
@@ -2779,12 +2779,12 @@
types. The following example encodes and decodes a dictionary::
>>> import json
- >>> data = {"spam" : "foo", "parrot" : 42}
+ >>> data = {"spam": "foo", "parrot": 42}
>>> in_json = json.dumps(data) # Encode the data
>>> in_json
'{"parrot": 42, "spam": "foo"}'
>>> json.loads(in_json) # Decode into a Python object
- {"spam" : "foo", "parrot" : 42}
+ {"spam": "foo", "parrot": 42}
It's also possible to write your own decoders and encoders to support
more types. Pretty-printing of the JSON strings is also supported.
diff -r 3a1db0d2747e Include/import.h
--- a/Include/import.h
+++ b/Include/import.h
@@ -40,8 +40,8 @@
PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *);
PyAPI_FUNC(void) _PyImport_ReInitLock(void);
-PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *);
-PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *);
+PyAPI_FUNC(PyObject *) _PyImport_FindExtension(char *, char *);
+PyAPI_FUNC(PyObject *) _PyImport_FixupExtension(char *, char *);
struct _inittab {
char *name;
diff -r 3a1db0d2747e LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -74,7 +74,7 @@
distribute, and otherwise use Python alone or in any derivative version,
provided, however, that PSF's License Agreement and PSF's notice of copyright,
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013 Python Software Foundation; All Rights Reserved" are retained
+2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are retained
in Python alone or in any derivative version prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on
diff -r 3a1db0d2747e Lib/Cookie.py
--- a/Lib/Cookie.py
+++ b/Lib/Cookie.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python
-#
-
####
# Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>
#
diff -r 3a1db0d2747e Lib/HTMLParser.py
--- a/Lib/HTMLParser.py
+++ b/Lib/HTMLParser.py
@@ -22,9 +22,12 @@
starttagopen = re.compile('<[a-zA-Z]')
piclose = re.compile('>')
commentclose = re.compile(r'--\s*>')
-tagfind = re.compile('([a-zA-Z][-.a-zA-Z0-9:_]*)(?:\s|/(?!>))*')
+
# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state
# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state
+# note: if you change tagfind/attrfind remember to update locatestarttagend too
+tagfind = re.compile('([a-zA-Z][^\t\n\r\f />\x00]*)(?:\s|/(?!>))*')
+# this regex is currently unused, but left for backward compatibility
tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*')
attrfind = re.compile(
@@ -32,7 +35,7 @@
r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*')
locatestarttagend = re.compile(r"""
- <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name
+ <[a-zA-Z][^\t\n\r\f />\x00]* # tag name
(?:[\s/]* # optional whitespace before attribute name
(?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name
(?:\s*=+\s* # value indicator
@@ -192,9 +195,9 @@
i = self.updatepos(i, k)
continue
else:
- if ";" in rawdata[i:]: #bail by consuming &#
- self.handle_data(rawdata[0:2])
- i = self.updatepos(i, 2)
+ if ";" in rawdata[i:]: # bail by consuming '&#'
+ self.handle_data(rawdata[i:i+2])
+ i = self.updatepos(i, i+2)
break
elif startswith('&', i):
match = entityref.match(rawdata, i)
@@ -373,14 +376,14 @@
self.handle_data(rawdata[i:gtpos])
return gtpos
# find the name: w3.org/TR/html5/tokenization.html#tag-name-state
- namematch = tagfind_tolerant.match(rawdata, i+2)
+ namematch = tagfind.match(rawdata, i+2)
if not namematch:
# w3.org/TR/html5/tokenization.html#end-tag-open-state
if rawdata[i:i+3] == '</>':
return i+3
else:
return self.parse_bogus_comment(i)
- tagname = namematch.group().lower()
+ tagname = namematch.group(1).lower()
# consume and ignore other stuff between the name and the >
# Note: this is not 100% correct, since we might have things like
# </tag attr=">">, but looking for > after tha name should cover
diff -r 3a1db0d2747e Lib/SimpleHTTPServer.py
--- a/Lib/SimpleHTTPServer.py
+++ b/Lib/SimpleHTTPServer.py
@@ -43,8 +43,10 @@
"""Serve a GET request."""
f = self.send_head()
if f:
- self.copyfile(f, self.wfile)
- f.close()
+ try:
+ self.copyfile(f, self.wfile)
+ finally:
+ f.close()
def do_HEAD(self):
"""Serve a HEAD request."""
@@ -88,13 +90,17 @@
except IOError:
self.send_error(404, "File not found")
return None
- self.send_response(200)
- self.send_header("Content-type", ctype)
- fs = os.fstat(f.fileno())
- self.send_header("Content-Length", str(fs[6]))
- self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
- self.end_headers()
- return f
+ try:
+ self.send_response(200)
+ self.send_header("Content-type", ctype)
+ fs = os.fstat(f.fileno())
+ self.send_header("Content-Length", str(fs[6]))
+ self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+ self.end_headers()
+ return f
+ except:
+ f.close()
+ raise
def list_directory(self, path):
"""Helper to produce a directory listing (absent index.html).
diff -r 3a1db0d2747e Lib/SimpleXMLRPCServer.py
--- a/Lib/SimpleXMLRPCServer.py
+++ b/Lib/SimpleXMLRPCServer.py
@@ -704,4 +704,5 @@
server = SimpleXMLRPCServer(("localhost", 8000))
server.register_function(pow)
server.register_function(lambda x,y: x+y, 'add')
+ server.register_multicall_functions()
server.serve_forever()
diff -r 3a1db0d2747e Lib/_MozillaCookieJar.py
--- a/Lib/_MozillaCookieJar.py
+++ b/Lib/_MozillaCookieJar.py
@@ -39,7 +39,7 @@
magic_re = "#( Netscape)? HTTP Cookie File"
header = """\
# Netscape HTTP Cookie File
-# http://www.netscape.com/newsref/std/cookie_spec.html
+# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file! Do not edit.
"""
diff -r 3a1db0d2747e Lib/_abcoll.py
--- a/Lib/_abcoll.py
+++ b/Lib/_abcoll.py
@@ -165,12 +165,12 @@
def __gt__(self, other):
if not isinstance(other, Set):
return NotImplemented
- return other < self
+ return other.__lt__(self)
def __ge__(self, other):
if not isinstance(other, Set):
return NotImplemented
- return other <= self
+ return other.__le__(self)
def __eq__(self, other):
if not isinstance(other, Set):
diff -r 3a1db0d2747e Lib/_pyio.py
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1997,7 +1997,13 @@
def getvalue(self):
self.flush()
- return self.buffer.getvalue().decode(self._encoding, self._errors)
+ decoder = self._decoder or self._get_decoder()
+ old_state = decoder.getstate()
+ decoder.reset()
+ try:
+ return decoder.decode(self.buffer.getvalue(), final=True)
+ finally:
+ decoder.setstate(old_state)
def __repr__(self):
# TextIOWrapper tells the encoding in its repr. In StringIO,
diff -r 3a1db0d2747e Lib/_weakrefset.py
--- a/Lib/_weakrefset.py
+++ b/Lib/_weakrefset.py
@@ -60,6 +60,8 @@
for itemref in self.data:
item = itemref()
if item is not None:
+ # Caveat: the iterator will keep a strong reference to
+ # `item` until it is resumed or closed.
yield item
def __len__(self):
diff -r 3a1db0d2747e Lib/aifc.py
--- a/Lib/aifc.py
+++ b/Lib/aifc.py
@@ -778,7 +778,7 @@
def _ensure_header_written(self, datasize):
if not self._nframeswritten:
- if self._comptype in ('ULAW', 'ALAW'):
+ if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw'):
if not self._sampwidth:
self._sampwidth = 2
if self._sampwidth != 2:
@@ -844,7 +844,7 @@
if self._datalength & 1:
self._datalength = self._datalength + 1
if self._aifc:
- if self._comptype in ('ULAW', 'ALAW'):
+ if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw'):
self._datalength = self._datalength // 2
if self._datalength & 1:
self._datalength = self._datalength + 1
@@ -852,7 +852,10 @@
self._datalength = (self._datalength + 3) // 4
if self._datalength & 1:
self._datalength = self._datalength + 1
- self._form_length_pos = self._file.tell()
+ try:
+ self._form_length_pos = self._file.tell()
+ except (AttributeError, IOError):
+ self._form_length_pos = None
commlength = self._write_form_length(self._datalength)
if self._aifc:
self._file.write('AIFC')
@@ -864,7 +867,8 @@
self._file.write('COMM')
_write_ulong(self._file, commlength)
_write_short(self._file, self._nchannels)
- self._nframes_pos = self._file.tell()
+ if self._form_length_pos is not None:
+ self._nframes_pos = self._file.tell()
_write_ulong(self._file, self._nframes)
if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'):
_write_short(self._file, 8)
@@ -875,7 +879,8 @@
self._file.write(self._comptype)
_write_string(self._file, self._compname)
self._file.write('SSND')
- self._ssnd_length_pos = self._file.tell()
+ if self._form_length_pos is not None:
+ self._ssnd_length_pos = self._file.tell()
_write_ulong(self._file, self._datalength + 8)
_write_ulong(self._file, 0)
_write_ulong(self._file, 0)
diff -r 3a1db0d2747e Lib/argparse.py
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -168,6 +168,8 @@
self._prog = prog
self._indent_increment = indent_increment
self._max_help_position = max_help_position
+ self._max_help_position = min(max_help_position,
+ max(width - 20, indent_increment * 2))
self._width = width
self._current_indent = 0
@@ -339,7 +341,7 @@
else:
line_len = len(indent) - 1
for part in parts:
- if line_len + 1 + len(part) > text_width:
+ if line_len + 1 + len(part) > text_width and line:
lines.append(indent + ' '.join(line))
line = []
line_len = len(indent) - 1
@@ -478,7 +480,7 @@
def _format_text(self, text):
if '%(prog)' in text:
text = text % dict(prog=self._prog)
- text_width = self._width - self._current_indent
+ text_width = max(self._width - self._current_indent, 11)
indent = ' ' * self._current_indent
return self._fill_text(text, text_width, indent) + '\n\n'
@@ -486,7 +488,7 @@
# determine the required width and the entry label
help_position = min(self._action_max_length + 2,
self._max_help_position)
- help_width = self._width - help_position
+ help_width = max(self._width - help_position, 11)
action_width = help_position - self._current_indent - 2
action_header = self._format_action_invocation(action)
diff -r 3a1db0d2747e Lib/bsddb/dbshelve.py
--- a/Lib/bsddb/dbshelve.py
+++ b/Lib/bsddb/dbshelve.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#------------------------------------------------------------------------
# Copyright (c) 1997-2001 by Total Control Software
# All Rights Reserved
diff -r 3a1db0d2747e Lib/bsddb/test/test_dbtables.py
--- a/Lib/bsddb/test/test_dbtables.py
+++ b/Lib/bsddb/test/test_dbtables.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
#-----------------------------------------------------------------------
# A test suite for the table interface built on bsddb.db
#-----------------------------------------------------------------------
diff -r 3a1db0d2747e Lib/codecs.py
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -456,15 +456,12 @@
# read until we get the required number of characters (if available)
while True:
- # can the request can be satisfied from the character buffer?
- if chars < 0:
- if size < 0:
- if self.charbuffer:
- break
- elif len(self.charbuffer) >= size:
+ # can the request be satisfied from the character buffer?
+ if chars >= 0:
+ if len(self.charbuffer) >= chars:
break
- else:
- if len(self.charbuffer) >= chars:
+ elif size >= 0:
+ if len(self.charbuffer) >= size:
break
# we need more data
if size < 0:
diff -r 3a1db0d2747e Lib/csv.py
--- a/Lib/csv.py
+++ b/Lib/csv.py
@@ -93,6 +93,10 @@
self.line_num = self.reader.line_num
return self._fieldnames
+ # Issue 20004: Because DictReader is a classic class, this setter is
+ # ignored. At this point in 2.7's lifecycle, it is too late to change the
+ # base class for fear of breaking working code. If you want to change
+ # fieldnames without overwriting the getter, set _fieldnames directly.
@fieldnames.setter
def fieldnames(self, value):
self._fieldnames = value
@@ -140,8 +144,8 @@
if self.extrasaction == "raise":
wrong_fields = [k for k in rowdict if k not in self.fieldnames]
if wrong_fields:
- raise ValueError("dict contains fields not in fieldnames: " +
- ", ".join(wrong_fields))
+ raise ValueError("dict contains fields not in fieldnames: "
+ + ", ".join([repr(x) for x in wrong_fields]))
return [rowdict.get(key, self.restval) for key in self.fieldnames]
def writerow(self, rowdict):
diff -r 3a1db0d2747e Lib/ctypes/test/test_arrays.py
--- a/Lib/ctypes/test/test_arrays.py
+++ b/Lib/ctypes/test/test_arrays.py
@@ -87,8 +87,8 @@
self.assertEqual(values, [1, 2, 3, 4, 5])
def test_classcache(self):
- self.assertTrue(not ARRAY(c_int, 3) is ARRAY(c_int, 4))
- self.assertTrue(ARRAY(c_int, 3) is ARRAY(c_int, 3))
+ self.assertIsNot(ARRAY(c_int, 3), ARRAY(c_int, 4))
+ self.assertIs(ARRAY(c_int, 3), ARRAY(c_int, 3))
def test_from_address(self):
# Failed with 0.9.8, reported by JUrner
@@ -128,7 +128,7 @@
# Create a new array type based on it:
t1 = my_int * 1
t2 = my_int * 1
- self.assertTrue(t1 is t2)
+ self.assertIs(t1, t2)
if __name__ == '__main__':
unittest.main()
diff -r 3a1db0d2747e Lib/ctypes/test/test_as_parameter.py
--- a/Lib/ctypes/test/test_as_parameter.py
+++ b/Lib/ctypes/test/test_as_parameter.py
@@ -134,7 +134,7 @@
f.argtypes = [c_longlong, MyCallback]
def callback(value):
- self.assertTrue(isinstance(value, (int, long)))
+ self.assertIsInstance(value, (int, long))
return value & 0x7FFFFFFF
cb = MyCallback(callback)
diff -r 3a1db0d2747e Lib/ctypes/test/test_bitfields.py
--- a/Lib/ctypes/test/test_bitfields.py
+++ b/Lib/ctypes/test/test_bitfields.py
@@ -207,7 +207,7 @@
class X(Structure):
_fields_ = [("a", c_byte, 4),
("b", c_int, 32)]
- self.assertEqual(sizeof(X), sizeof(c_int)*2)
+ self.assertEqual(sizeof(X), alignment(c_int)+sizeof(c_int))
def test_mixed_3(self):
class X(Structure):
diff -r 3a1db0d2747e Lib/ctypes/test/test_buffers.py
--- a/Lib/ctypes/test/test_buffers.py
+++ b/Lib/ctypes/test/test_buffers.py
@@ -7,12 +7,12 @@
b = create_string_buffer(32)
self.assertEqual(len(b), 32)
self.assertEqual(sizeof(b), 32 * sizeof(c_char))
- self.assertTrue(type(b[0]) is str)
+ self.assertIs(type(b[0]), str)
b = create_string_buffer("abc")
self.assertEqual(len(b), 4) # trailing nul char
self.assertEqual(sizeof(b), 4 * sizeof(c_char))
- self.assertTrue(type(b[0]) is str)
+ self.assertIs(type(b[0]), str)
self.assertEqual(b[0], "a")
self.assertEqual(b[:], "abc\0")
self.assertEqual(b[::], "abc\0")
@@ -45,12 +45,12 @@
b = create_unicode_buffer(32)
self.assertEqual(len(b), 32)
self.assertEqual(sizeof(b), 32 * sizeof(c_wchar))
- self.assertTrue(type(b[0]) is unicode)
+ self.assertIs(type(b[0]), unicode)
b = create_unicode_buffer(u"abc")
self.assertEqual(len(b), 4) # trailing nul char
self.assertEqual(sizeof(b), 4 * sizeof(c_wchar))
- self.assertTrue(type(b[0]) is unicode)
+ self.assertIs(type(b[0]), unicode)
self.assertEqual(b[0], u"a")
self.assertEqual(b[:], "abc\0")
self.assertEqual(b[::], "abc\0")
@@ -62,7 +62,7 @@
b = create_unicode_buffer("abc")
self.assertEqual(len(b), 4) # trailing nul char
self.assertEqual(sizeof(b), 4 * sizeof(c_wchar))
- self.assertTrue(type(b[0]) is unicode)
+ self.assertIs(type(b[0]), unicode)
self.assertEqual(b[0], u"a")
self.assertEqual(b[:], "abc\0")
self.assertEqual(b[::], "abc\0")
diff -r 3a1db0d2747e Lib/ctypes/test/test_byteswap.py
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -23,11 +23,11 @@
def test_endian_short(self):
if sys.byteorder == "little":
- self.assertTrue(c_short.__ctype_le__ is c_short)
- self.assertTrue(c_short.__ctype_be__.__ctype_le__ is c_short)
+ self.assertIs(c_short.__ctype_le__, c_short)
+ self.assertIs(c_short.__ctype_be__.__ctype_le__, c_short)
else:
- self.assertTrue(c_short.__ctype_be__ is c_short)
- self.assertTrue(c_short.__ctype_le__.__ctype_be__ is c_short)
+ self.assertIs(c_short.__ctype_be__, c_short)
+ self.assertIs(c_short.__ctype_le__.__ctype_be__, c_short)
s = c_short.__ctype_be__(0x1234)
self.assertEqual(bin(struct.pack(">h", 0x1234)), "1234")
self.assertEqual(bin(s), "1234")
@@ -50,11 +50,11 @@
def test_endian_int(self):
if sys.byteorder == "little":
- self.assertTrue(c_int.__ctype_le__ is c_int)
- self.assertTrue(c_int.__ctype_be__.__ctype_le__ is c_int)
+ self.assertIs(c_int.__ctype_le__, c_int)
+ self.assertIs(c_int.__ctype_be__.__ctype_le__, c_int)
else:
- self.assertTrue(c_int.__ctype_be__ is c_int)
- self.assertTrue(c_int.__ctype_le__.__ctype_be__ is c_int)
+ self.assertIs(c_int.__ctype_be__, c_int)
+ self.assertIs(c_int.__ctype_le__.__ctype_be__, c_int)
s = c_int.__ctype_be__(0x12345678)
self.assertEqual(bin(struct.pack(">i", 0x12345678)), "12345678")
@@ -78,11 +78,11 @@
def test_endian_longlong(self):
if sys.byteorder == "little":
- self.assertTrue(c_longlong.__ctype_le__ is c_longlong)
- self.assertTrue(c_longlong.__ctype_be__.__ctype_le__ is c_longlong)
+ self.assertIs(c_longlong.__ctype_le__, c_longlong)
+ self.assertIs(c_longlong.__ctype_be__.__ctype_le__, c_longlong)
else:
- self.assertTrue(c_longlong.__ctype_be__ is c_longlong)
- self.assertTrue(c_longlong.__ctype_le__.__ctype_be__ is c_longlong)
+ self.assertIs(c_longlong.__ctype_be__, c_longlong)
+ self.assertIs(c_longlong.__ctype_le__.__ctype_be__, c_longlong)
s = c_longlong.__ctype_be__(0x1234567890ABCDEF)
self.assertEqual(bin(struct.pack(">q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
@@ -106,11 +106,11 @@
def test_endian_float(self):
if sys.byteorder == "little":
- self.assertTrue(c_float.__ctype_le__ is c_float)
- self.assertTrue(c_float.__ctype_be__.__ctype_le__ is c_float)
+ self.assertIs(c_float.__ctype_le__, c_float)
+ self.assertIs(c_float.__ctype_be__.__ctype_le__, c_float)
else:
- self.assertTrue(c_float.__ctype_be__ is c_float)
- self.assertTrue(c_float.__ctype_le__.__ctype_be__ is c_float)
+ self.assertIs(c_float.__ctype_be__, c_float)
+ self.assertIs(c_float.__ctype_le__.__ctype_be__, c_float)
s = c_float(math.pi)
self.assertEqual(bin(struct.pack("f", math.pi)), bin(s))
# Hm, what's the precision of a float compared to a double?
@@ -124,11 +124,11 @@
def test_endian_double(self):
if sys.byteorder == "little":
- self.assertTrue(c_double.__ctype_le__ is c_double)
- self.assertTrue(c_double.__ctype_be__.__ctype_le__ is c_double)
+ self.assertIs(c_double.__ctype_le__, c_double)
+ self.assertIs(c_double.__ctype_be__.__ctype_le__, c_double)
else:
- self.assertTrue(c_double.__ctype_be__ is c_double)
- self.assertTrue(c_double.__ctype_le__.__ctype_be__ is c_double)
+ self.assertIs(c_double.__ctype_be__, c_double)
+ self.assertIs(c_double.__ctype_le__.__ctype_be__, c_double)
s = c_double(math.pi)
self.assertEqual(s.value, math.pi)
self.assertEqual(bin(struct.pack("d", math.pi)), bin(s))
@@ -140,14 +140,14 @@
self.assertEqual(bin(struct.pack(">d", math.pi)), bin(s))
def test_endian_other(self):
- self.assertTrue(c_byte.__ctype_le__ is c_byte)
- self.assertTrue(c_byte.__ctype_be__ is c_byte)
+ self.assertIs(c_byte.__ctype_le__, c_byte)
+ self.assertIs(c_byte.__ctype_be__, c_byte)
- self.assertTrue(c_ubyte.__ctype_le__ is c_ubyte)
- self.assertTrue(c_ubyte.__ctype_be__ is c_ubyte)
+ self.assertIs(c_ubyte.__ctype_le__, c_ubyte)
+ self.assertIs(c_ubyte.__ctype_be__, c_ubyte)
- self.assertTrue(c_char.__ctype_le__ is c_char)
- self.assertTrue(c_char.__ctype_be__ is c_char)
+ self.assertIs(c_char.__ctype_le__, c_char)
+ self.assertIs(c_char.__ctype_be__, c_char)
def test_struct_fields_1(self):
if sys.byteorder == "little":
diff -r 3a1db0d2747e Lib/ctypes/test/test_cast.py
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -38,14 +38,14 @@
p = cast(array, POINTER(c_char_p))
# array and p share a common _objects attribute
- self.assertTrue(p._objects is array._objects)
+ self.assertIs(p._objects, array._objects)
self.assertEqual(array._objects, {'0': "foo bar", id(array): array})
p[0] = "spam spam"
self.assertEqual(p._objects, {'0': "spam spam", id(array): array})
- self.assertTrue(array._objects is p._objects)
+ self.assertIs(array._objects, p._objects)
p[1] = "foo bar"
self.assertEqual(p._objects, {'1': 'foo bar', '0': "spam spam", id(array): array})
- self.assertTrue(array._objects is p._objects)
+ self.assertIs(array._objects, p._objects)
def test_other(self):
p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int))
diff -r 3a1db0d2747e Lib/ctypes/test/test_frombuffer.py
--- a/Lib/ctypes/test/test_frombuffer.py
+++ b/Lib/ctypes/test/test_frombuffer.py
@@ -23,7 +23,7 @@
a[0], a[-1] = 200, -200
self.assertEqual(x[:], a.tolist())
- self.assertTrue(a in x._objects.values())
+ self.assertIn(a, x._objects.values())
self.assertRaises(ValueError,
c_int.from_buffer, a, -1)
diff -r 3a1db0d2747e Lib/ctypes/test/test_funcptr.py
--- a/Lib/ctypes/test/test_funcptr.py
+++ b/Lib/ctypes/test/test_funcptr.py
@@ -75,7 +75,7 @@
## "lpfnWndProc", WNDPROC_2(wndproc))
# instead:
- self.assertTrue(WNDPROC is WNDPROC_2)
+ self.assertIs(WNDPROC, WNDPROC_2)
# 'wndclass.lpfnWndProc' leaks 94 references. Why?
self.assertEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10)
diff -r 3a1db0d2747e Lib/ctypes/test/test_functions.py
--- a/Lib/ctypes/test/test_functions.py
+++ b/Lib/ctypes/test/test_functions.py
@@ -306,7 +306,7 @@
f.argtypes = [c_longlong, MyCallback]
def callback(value):
- self.assertTrue(isinstance(value, (int, long)))
+ self.assertIsInstance(value, (int, long))
return value & 0x7FFFFFFF
cb = MyCallback(callback)
diff -r 3a1db0d2747e Lib/ctypes/test/test_loading.py
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -43,7 +43,7 @@
if os.name in ("nt", "ce"):
def test_load_library(self):
- self.assertFalse(libc_name is None)
+ self.assertIsNotNone(libc_name)
if is_resource_enabled("printing"):
print find_library("kernel32")
print find_library("user32")
diff -r 3a1db0d2747e Lib/ctypes/test/test_numbers.py
--- a/Lib/ctypes/test/test_numbers.py
+++ b/Lib/ctypes/test/test_numbers.py
@@ -181,10 +181,10 @@
a = array(t._type_, [3.14])
v = t.from_address(a.buffer_info()[0])
self.assertEqual(v.value, a[0])
- self.assertTrue(type(v) is t)
+ self.assertIs(type(v), t)
a[0] = 2.3456e17
self.assertEqual(v.value, a[0])
- self.assertTrue(type(v) is t)
+ self.assertIs(type(v), t)
def test_char_from_address(self):
from ctypes import c_char
@@ -193,7 +193,7 @@
a = array('c', 'x')
v = c_char.from_address(a.buffer_info()[0])
self.assertEqual(v.value, a[0])
- self.assertTrue(type(v) is c_char)
+ self.assertIs(type(v), c_char)
a[0] = '?'
self.assertEqual(v.value, a[0])
diff -r 3a1db0d2747e Lib/ctypes/test/test_parameters.py
--- a/Lib/ctypes/test/test_parameters.py
+++ b/Lib/ctypes/test/test_parameters.py
@@ -55,7 +55,7 @@
# c_char_p.from_param on a Python String packs the string
# into a cparam object
s = "123"
- self.assertTrue(c_char_p.from_param(s)._obj is s)
+ self.assertIs(c_char_p.from_param(s)._obj, s)
# new in 0.9.1: convert (encode) unicode to ascii
self.assertEqual(c_char_p.from_param(u"123")._obj, "123")
@@ -66,7 +66,7 @@
# calling c_char_p.from_param with a c_char_p instance
# returns the argument itself:
a = c_char_p("123")
- self.assertTrue(c_char_p.from_param(a) is a)
+ self.assertIs(c_char_p.from_param(a), a)
def test_cw_strings(self):
from ctypes import byref
diff -r 3a1db0d2747e Lib/ctypes/test/test_pointers.py
--- a/Lib/ctypes/test/test_pointers.py
+++ b/Lib/ctypes/test/test_pointers.py
@@ -78,7 +78,7 @@
## i = c_int(42)
## callback(byref(i))
-## self.assertTrue(i.value == 84)
+## self.assertEqual(i.value, 84)
doit(callback)
## print self.result
@@ -91,11 +91,11 @@
i = ct(42)
p = pointer(i)
## print type(p.contents), ct
- self.assertTrue(type(p.contents) is ct)
+ self.assertIs(type(p.contents), ct)
# p.contents is the same as p[0]
## print p.contents
-## self.assertTrue(p.contents == 42)
-## self.assertTrue(p[0] == 42)
+## self.assertEqual(p.contents, 42)
+## self.assertEqual(p[0], 42)
self.assertRaises(TypeError, delitem, p, 0)
diff -r 3a1db0d2747e Lib/ctypes/test/test_python_api.py
--- a/Lib/ctypes/test/test_python_api.py
+++ b/Lib/ctypes/test/test_python_api.py
@@ -61,7 +61,7 @@
ref = grc(s)
# id(python-object) is the address
pyobj = PyObj_FromPtr(id(s))
- self.assertTrue(s is pyobj)
+ self.assertIs(s, pyobj)
self.assertEqual(grc(s), ref + 1)
del pyobj
diff -r 3a1db0d2747e Lib/ctypes/test/test_refcounts.py
--- a/Lib/ctypes/test/test_refcounts.py
+++ b/Lib/ctypes/test/test_refcounts.py
@@ -24,7 +24,7 @@
self.assertEqual(grc(callback), 2)
cb = MyCallback(callback)
- self.assertTrue(grc(callback) > 2)
+ self.assertGreater(grc(callback), 2)
result = f(-10, cb)
self.assertEqual(result, -18)
cb = None
@@ -43,15 +43,15 @@
# the CFuncPtr instance holds at least one refcount on func:
f = OtherCallback(func)
- self.assertTrue(grc(func) > 2)
+ self.assertGreater(grc(func), 2)
# and may release it again
del f
- self.assertTrue(grc(func) >= 2)
+ self.assertGreaterEqual(grc(func), 2)
# but now it must be gone
gc.collect()
- self.assertTrue(grc(func) == 2)
+ self.assertEqual(grc(func), 2)
class X(ctypes.Structure):
_fields_ = [("a", OtherCallback)]
@@ -59,11 +59,11 @@
x.a = OtherCallback(func)
# the CFuncPtr instance holds at least one refcount on func:
- self.assertTrue(grc(func) > 2)
+ self.assertGreater(grc(func), 2)
# and may release it again
del x
- self.assertTrue(grc(func) >= 2)
+ self.assertGreaterEqual(grc(func), 2)
# and now it must be gone again
gc.collect()
@@ -72,7 +72,7 @@
f = OtherCallback(func)
# the CFuncPtr instance holds at least one refcount on func:
- self.assertTrue(grc(func) > 2)
+ self.assertGreater(grc(func), 2)
# create a cycle
f.cycle = f
diff -r 3a1db0d2747e Lib/ctypes/test/test_strings.py
--- a/Lib/ctypes/test/test_strings.py
+++ b/Lib/ctypes/test/test_strings.py
@@ -115,24 +115,24 @@
# New in releases later than 0.4.0:
# c_string(number) returns an empty string of size number
- self.assertTrue(len(c_string(32).raw) == 32)
+ self.assertEqual(len(c_string(32).raw), 32)
self.assertRaises(ValueError, c_string, -1)
self.assertRaises(ValueError, c_string, 0)
# These tests fail, because it is no longer initialized
-## self.assertTrue(c_string(2).value == "")
-## self.assertTrue(c_string(2).raw == "\000\000")
- self.assertTrue(c_string(2).raw[-1] == "\000")
- self.assertTrue(len(c_string(2).raw) == 2)
+## self.assertEqual(c_string(2).value, "")
+## self.assertEqual(c_string(2).raw, "\000\000")
+ self.assertEqual(c_string(2).raw[-1], "\000")
+ self.assertEqual(len(c_string(2).raw), 2)
def XX_test_initialized_strings(self):
- self.assertTrue(c_string("ab", 4).raw[:2] == "ab")
- self.assertTrue(c_string("ab", 4).raw[:2:] == "ab")
- self.assertTrue(c_string("ab", 4).raw[:2:-1] == "ba")
- self.assertTrue(c_string("ab", 4).raw[:2:2] == "a")
- self.assertTrue(c_string("ab", 4).raw[-1] == "\000")
- self.assertTrue(c_string("ab", 2).raw == "a\000")
+ self.assertEqual(c_string("ab", 4).raw[:2], "ab")
+ self.assertEqual(c_string("ab", 4).raw[:2:], "ab")
+ self.assertEqual(c_string("ab", 4).raw[:2:-1], "ba")
+ self.assertEqual(c_string("ab", 4).raw[:2:2], "a")
+ self.assertEqual(c_string("ab", 4).raw[-1], "\000")
+ self.assertEqual(c_string("ab", 2).raw, "a\000")
def XX_test_toolong(self):
cs = c_string("abcdef")
@@ -163,22 +163,22 @@
# XXX This behaviour is about to change:
# len returns the size of the internal buffer in bytes.
# This includes the terminating NUL character.
- self.assertTrue(sizeof(cs) == 14)
+ self.assertEqual(sizeof(cs), 14)
# The value property is the string up to the first terminating NUL.
- self.assertTrue(cs.value == u"abcdef")
- self.assertTrue(c_wstring(u"abc\000def").value == u"abc")
+ self.assertEqual(cs.value, u"abcdef")
+ self.assertEqual(c_wstring(u"abc\000def").value, u"abc")
- self.assertTrue(c_wstring(u"abc\000def").value == u"abc")
+ self.assertEqual(c_wstring(u"abc\000def").value, u"abc")
# The raw property is the total buffer contents:
- self.assertTrue(cs.raw == u"abcdef\000")
- self.assertTrue(c_wstring(u"abc\000def").raw == u"abc\000def\000")
+ self.assertEqual(cs.raw, u"abcdef\000")
+ self.assertEqual(c_wstring(u"abc\000def").raw, u"abc\000def\000")
# We can change the value:
cs.value = u"ab"
- self.assertTrue(cs.value == u"ab")
- self.assertTrue(cs.raw == u"ab\000\000\000\000\000")
+ self.assertEqual(cs.value, u"ab")
+ self.assertEqual(cs.raw, u"ab\000\000\000\000\000")
self.assertRaises(TypeError, c_wstring, "123")
self.assertRaises(ValueError, c_wstring, 0)
diff -r 3a1db0d2747e Lib/ctypes/test/test_structures.py
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -83,7 +83,7 @@
class Y(Structure):
_fields_ = [("x", c_char * 3),
("y", c_int)]
- self.assertEqual(alignment(Y), calcsize("i"))
+ self.assertEqual(alignment(Y), alignment(c_int))
self.assertEqual(sizeof(Y), calcsize("3si"))
class SI(Structure):
@@ -175,13 +175,6 @@
self.assertEqual(sizeof(X), 10)
self.assertEqual(X.b.offset, 2)
- class X(Structure):
- _fields_ = [("a", c_byte),
- ("b", c_longlong)]
- _pack_ = 4
- self.assertEqual(sizeof(X), 12)
- self.assertEqual(X.b.offset, 4)
-
import struct
longlong_size = struct.calcsize("q")
longlong_align = struct.calcsize("bq") - longlong_size
@@ -189,9 +182,16 @@
class X(Structure):
_fields_ = [("a", c_byte),
("b", c_longlong)]
+ _pack_ = 4
+ self.assertEqual(sizeof(X), min(4, longlong_align) + longlong_size)
+ self.assertEqual(X.b.offset, min(4, longlong_align))
+
+ class X(Structure):
+ _fields_ = [("a", c_byte),
+ ("b", c_longlong)]
_pack_ = 8
- self.assertEqual(sizeof(X), longlong_align + longlong_size)
+ self.assertEqual(sizeof(X), min(8, longlong_align) + longlong_size)
self.assertEqual(X.b.offset, min(8, longlong_align))
@@ -380,9 +380,9 @@
## class X(Structure):
## _fields_ = []
- self.assertTrue("in_dll" in dir(type(Structure)))
- self.assertTrue("from_address" in dir(type(Structure)))
- self.assertTrue("in_dll" in dir(type(Structure)))
+ self.assertIn("in_dll", dir(type(Structure)))
+ self.assertIn("from_address", dir(type(Structure)))
+ self.assertIn("in_dll", dir(type(Structure)))
def test_positional_args(self):
# see also http://bugs.python.org/issue5042
@@ -452,8 +452,8 @@
try:
Recursive._fields_ = [("next", Recursive)]
except AttributeError, details:
- self.assertTrue("Structure or union cannot contain itself" in
- str(details))
+ self.assertIn("Structure or union cannot contain itself",
+ str(details))
else:
self.fail("Structure or union cannot contain itself")
@@ -469,8 +469,7 @@
try:
Second._fields_ = [("first", First)]
except AttributeError, details:
- self.assertTrue("_fields_ is final" in
- str(details))
+ self.assertIn("_fields_ is final", str(details))
else:
self.fail("AttributeError not raised")
diff -r 3a1db0d2747e Lib/difflib.py
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -1,5 +1,3 @@
-#! /usr/bin/env python
-
"""
Module difflib -- helpers for computing deltas between objects.
diff -r 3a1db0d2747e Lib/distutils/command/bdist_rpm.py
--- a/Lib/distutils/command/bdist_rpm.py
+++ b/Lib/distutils/command/bdist_rpm.py
@@ -12,6 +12,7 @@
from distutils.core import Command
from distutils.debug import DEBUG
from distutils.file_util import write_file
+from distutils.sysconfig import get_python_version
from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
DistutilsFileError, DistutilsExecError)
from distutils import log
diff -r 3a1db0d2747e Lib/distutils/command/build_py.py
--- a/Lib/distutils/command/build_py.py
+++ b/Lib/distutils/command/build_py.py
@@ -128,7 +128,8 @@
# Each pattern has to be converted to a platform-specific path
filelist = glob(os.path.join(src_dir, convert_path(pattern)))
# Files that match more than one pattern are only added once
- files.extend([fn for fn in filelist if fn not in files])
+ files.extend([fn for fn in filelist if fn not in files
+ and os.path.isfile(fn)])
return files
def build_package_data(self):
diff -r 3a1db0d2747e Lib/distutils/command/upload.py
--- a/Lib/distutils/command/upload.py
+++ b/Lib/distutils/command/upload.py
@@ -177,7 +177,7 @@
status = result.getcode()
reason = result.msg
if self.show_response:
- msg = '\n'.join(('-' * 75, r.read(), '-' * 75))
+ msg = '\n'.join(('-' * 75, result.read(), '-' * 75))
self.announce(msg, log.INFO)
except socket.error, e:
self.announce(str(e), log.ERROR)
diff -r 3a1db0d2747e Lib/distutils/config.py
--- a/Lib/distutils/config.py
+++ b/Lib/distutils/config.py
@@ -21,7 +21,7 @@
class PyPIRCCommand(Command):
"""Base command that knows how to handle the .pypirc file
"""
- DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
+ DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi'
DEFAULT_REALM = 'pypi'
repository = None
realm = None
diff -r 3a1db0d2747e Lib/distutils/core.py
--- a/Lib/distutils/core.py
+++ b/Lib/distutils/core.py
@@ -14,7 +14,6 @@
from distutils.debug import DEBUG
from distutils.errors import (DistutilsSetupError, DistutilsArgError,
DistutilsError, CCompilerError)
-from distutils.util import grok_environment_error
# Mainly import these so setup scripts can "from distutils.core import" them.
from distutils.dist import Distribution
@@ -153,13 +152,11 @@
except KeyboardInterrupt:
raise SystemExit, "interrupted"
except (IOError, os.error), exc:
- error = grok_environment_error(exc)
-
if DEBUG:
- sys.stderr.write(error + "\n")
+ sys.stderr.write("error: %s\n" % (exc,))
raise
else:
- raise SystemExit, error
+ raise SystemExit, "error: %s" % (exc,)
except (DistutilsError,
CCompilerError), msg:
diff -r 3a1db0d2747e Lib/distutils/dir_util.py
--- a/Lib/distutils/dir_util.py
+++ b/Lib/distutils/dir_util.py
@@ -185,7 +185,6 @@
Any errors are ignored (apart from being reported to stdout if 'verbose'
is true).
"""
- from distutils.util import grok_environment_error
global _path_created
if verbose >= 1:
@@ -202,8 +201,7 @@
if abspath in _path_created:
del _path_created[abspath]
except (IOError, OSError), exc:
- log.warn(grok_environment_error(
- exc, "error removing %s: " % directory))
+ log.warn("error removing %s: %s", directory, exc)
def ensure_relative(path):
"""Take the full path 'path', and make it a relative path.
diff -r 3a1db0d2747e Lib/distutils/spawn.py
--- a/Lib/distutils/spawn.py
+++ b/Lib/distutils/spawn.py
@@ -12,6 +12,7 @@
import os
from distutils.errors import DistutilsPlatformError, DistutilsExecError
+from distutils.debug import DEBUG
from distutils import log
def spawn(cmd, search_path=1, verbose=0, dry_run=0):
@@ -30,6 +31,9 @@
Raise DistutilsExecError if running the program fails in any way; just
return on success.
"""
+ # cmd is documented as a list, but just in case some code passes a tuple
+ # in, protect our %-formatting code against horrible death
+ cmd = list(cmd)
if os.name == 'posix':
_spawn_posix(cmd, search_path, dry_run=dry_run)
elif os.name == 'nt':
@@ -69,12 +73,16 @@
rc = os.spawnv(os.P_WAIT, executable, cmd)
except OSError, exc:
# this seems to happen when the command isn't found
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "command '%s' failed: %s" % (cmd[0], exc[-1])
+ "command %r failed: %s" % (cmd, exc[-1])
if rc != 0:
# and this reflects the command running but failing
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "command '%s' failed with exit status %d" % (cmd[0], rc)
+ "command %r failed with exit status %d" % (cmd, rc)
def _spawn_os2(cmd, search_path=1, verbose=0, dry_run=0):
executable = cmd[0]
@@ -88,13 +96,17 @@
rc = os.spawnv(os.P_WAIT, executable, cmd)
except OSError, exc:
# this seems to happen when the command isn't found
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "command '%s' failed: %s" % (cmd[0], exc[-1])
+ "command %r failed: %s" % (cmd, exc[-1])
if rc != 0:
# and this reflects the command running but failing
- log.debug("command '%s' failed with exit status %d" % (cmd[0], rc))
+ if not DEBUG:
+ cmd = executable
+ log.debug("command %r failed with exit status %d" % (cmd, rc))
raise DistutilsExecError, \
- "command '%s' failed with exit status %d" % (cmd[0], rc)
+ "command %r failed with exit status %d" % (cmd, rc)
if sys.platform == 'darwin':
from distutils import sysconfig
@@ -105,8 +117,9 @@
log.info(' '.join(cmd))
if dry_run:
return
+ executable = cmd[0]
exec_fn = search_path and os.execvp or os.execv
- exec_args = [cmd[0], cmd]
+ env = None
if sys.platform == 'darwin':
global _cfg_target, _cfg_target_split
if _cfg_target is None:
@@ -127,18 +140,24 @@
env = dict(os.environ,
MACOSX_DEPLOYMENT_TARGET=cur_target)
exec_fn = search_path and os.execvpe or os.execve
- exec_args.append(env)
pid = os.fork()
if pid == 0: # in the child
try:
- exec_fn(*exec_args)
+ if env is None:
+ exec_fn(executable, cmd)
+ else:
+ exec_fn(executable, cmd, env)
except OSError, e:
- sys.stderr.write("unable to execute %s: %s\n" %
- (cmd[0], e.strerror))
+ if not DEBUG:
+ cmd = executable
+ sys.stderr.write("unable to execute %r: %s\n" %
+ (cmd, e.strerror))
os._exit(1)
- sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])
+ if not DEBUG:
+ cmd = executable
+ sys.stderr.write("unable to execute %r for unknown reasons" % cmd)
os._exit(1)
else: # in the parent
# Loop until the child either exits or is terminated by a signal
@@ -150,29 +169,37 @@
import errno
if exc.errno == errno.EINTR:
continue
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "command '%s' failed: %s" % (cmd[0], exc[-1])
+ "command %r failed: %s" % (cmd, exc[-1])
if os.WIFSIGNALED(status):
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "command '%s' terminated by signal %d" % \
- (cmd[0], os.WTERMSIG(status))
+ "command %r terminated by signal %d" % \
+ (cmd, os.WTERMSIG(status))
elif os.WIFEXITED(status):
exit_status = os.WEXITSTATUS(status)
if exit_status == 0:
return # hey, it succeeded!
else:
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "command '%s' failed with exit status %d" % \
- (cmd[0], exit_status)
+ "command %r failed with exit status %d" % \
+ (cmd, exit_status)
elif os.WIFSTOPPED(status):
continue
else:
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError, \
- "unknown error executing '%s': termination status %d" % \
- (cmd[0], status)
+ "unknown error executing %r: termination status %d" % \
+ (cmd, status)
def find_executable(executable, path=None):
"""Tries to find 'executable' in the directories listed in 'path'.
diff -r 3a1db0d2747e Lib/distutils/tests/test_archive_util.py
--- a/Lib/distutils/tests/test_archive_util.py
+++ b/Lib/distutils/tests/test_archive_util.py
@@ -199,7 +199,7 @@
dry_run=True)
finally:
os.chdir(old_dir)
- self.assertTrue(not os.path.exists(tarball))
+ self.assertFalse(os.path.exists(tarball))
self.assertEqual(len(w.warnings), 1)
@unittest.skipUnless(zlib, "Requires zlib")
diff -r 3a1db0d2747e Lib/distutils/tests/test_bdist_rpm.py
--- a/Lib/distutils/tests/test_bdist_rpm.py
+++ b/Lib/distutils/tests/test_bdist_rpm.py
@@ -39,18 +39,15 @@
sys.argv[:] = self.old_sys_argv[1]
super(BuildRpmTestCase, self).tearDown()
+ # XXX I am unable yet to make this test work without
+ # spurious sdtout/stderr output under Mac OS X
+ @unittest.skipUnless(sys.platform.startswith('linux'),
+ 'spurious sdtout/stderr output under Mac OS X')
+ @unittest.skipIf(find_executable('rpm') is None,
+ 'the rpm command is not found')
+ @unittest.skipIf(find_executable('rpmbuild') is None,
+ 'the rpmbuild command is not found')
def test_quiet(self):
-
- # XXX I am unable yet to make this test work without
- # spurious sdtout/stderr output under Mac OS X
- if sys.platform != 'linux2':
- return
-
- # this test will run only if the rpm commands are found
- if (find_executable('rpm') is None or
- find_executable('rpmbuild') is None):
- return
-
# let's create a package
tmp_dir = self.mkdtemp()
pkg_dir = os.path.join(tmp_dir, 'foo')
@@ -77,25 +74,22 @@
cmd.run()
dist_created = os.listdir(os.path.join(pkg_dir, 'dist'))
- self.assertTrue('foo-0.1-1.noarch.rpm' in dist_created)
+ self.assertIn('foo-0.1-1.noarch.rpm', dist_created)
# bug #2945: upload ignores bdist_rpm files
self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files)
self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files)
+ # XXX I am unable yet to make this test work without
+ # spurious sdtout/stderr output under Mac OS X
+ @unittest.skipUnless(sys.platform.startswith('linux'),
+ 'spurious sdtout/stderr output under Mac OS X')
+ # http://bugs.python.org/issue1533164
+ @unittest.skipIf(find_executable('rpm') is None,
+ 'the rpm command is not found')
+ @unittest.skipIf(find_executable('rpmbuild') is None,
+ 'the rpmbuild command is not found')
def test_no_optimize_flag(self):
-
- # XXX I am unable yet to make this test work without
- # spurious sdtout/stderr output under Mac OS X
- if sys.platform != 'linux2':
- return
-
- # http://bugs.python.org/issue1533164
- # this test will run only if the rpm command is found
- if (find_executable('rpm') is None or
- find_executable('rpmbuild') is None):
- return
-
# let's create a package that brakes bdist_rpm
tmp_dir = self.mkdtemp()
pkg_dir = os.path.join(tmp_dir, 'foo')
@@ -121,7 +115,7 @@
cmd.run()
dist_created = os.listdir(os.path.join(pkg_dir, 'dist'))
- self.assertTrue('foo-0.1-1.noarch.rpm' in dist_created)
+ self.assertIn('foo-0.1-1.noarch.rpm', dist_created)
# bug #2945: upload ignores bdist_rpm files
self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files)
diff -r 3a1db0d2747e Lib/distutils/tests/test_bdist_wininst.py
--- a/Lib/distutils/tests/test_bdist_wininst.py
+++ b/Lib/distutils/tests/test_bdist_wininst.py
@@ -23,7 +23,7 @@
# and make sure it finds it and returns its content
# no matter what platform we have
exe_file = cmd.get_exe_bytes()
- self.assertTrue(len(exe_file) > 10)
+ self.assertGreater(len(exe_file), 10)
def test_suite():
return unittest.makeSuite(BuildWinInstTestCase)
diff -r 3a1db0d2747e Lib/distutils/tests/test_build_clib.py
--- a/Lib/distutils/tests/test_build_clib.py
+++ b/Lib/distutils/tests/test_build_clib.py
@@ -102,11 +102,8 @@
cmd.distribution.libraries = 'WONTWORK'
self.assertRaises(DistutilsSetupError, cmd.finalize_options)
+ @unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
def test_run(self):
- # can't test on windows
- if sys.platform == 'win32':
- return
-
pkg_dir, dist = self.create_dist()
cmd = build_clib(dist)
@@ -131,13 +128,13 @@
if ccmd is None:
continue
if find_executable(ccmd[0]) is None:
- return # can't test
+ self.skipTest('The %r command is not found' % ccmd[0])
# this should work
cmd.run()
# let's check the result
- self.assertTrue('libfoo.a' in os.listdir(build_temp))
+ self.assertIn('libfoo.a', os.listdir(build_temp))
def test_suite():
return unittest.makeSuite(BuildCLibTestCase)
diff -r 3a1db0d2747e Lib/distutils/tests/test_build_ext.py
--- a/Lib/distutils/tests/test_build_ext.py
+++ b/Lib/distutils/tests/test_build_ext.py
@@ -65,9 +65,9 @@
sys.stdout = old_stdout
if ALREADY_TESTED:
- return
+ self.skipTest('Already tested in %s' % ALREADY_TESTED)
else:
- ALREADY_TESTED = True
+ ALREADY_TESTED = type(self).__name__
import xx
@@ -80,8 +80,8 @@
if test_support.HAVE_DOCSTRINGS:
doc = 'This is a template module just for instruction.'
self.assertEqual(xx.__doc__, doc)
- self.assertTrue(isinstance(xx.Null(), xx.Null))
- self.assertTrue(isinstance(xx.Str(), xx.Str))
+ self.assertIsInstance(xx.Null(), xx.Null)
+ self.assertIsInstance(xx.Str(), xx.Str)
def test_solaris_enable_shared(self):
dist = Distribution({'name': 'xx'})
@@ -102,13 +102,11 @@
_config_vars['Py_ENABLE_SHARED'] = old_var
# make sure we get some library dirs under solaris
- self.assertTrue(len(cmd.library_dirs) > 0)
+ self.assertGreater(len(cmd.library_dirs), 0)
+ @unittest.skipIf(sys.version < '2.6',
+ 'site.USER_SITE was introduced in 2.6')
def test_user_site(self):
- # site.USER_SITE was introduced in 2.6
- if sys.version < '2.6':
- return
-
import site
dist = Distribution({'name': 'xx'})
cmd = build_ext(dist)
@@ -143,10 +141,10 @@
cmd.finalize_options()
py_include = sysconfig.get_python_inc()
- self.assertTrue(py_include in cmd.include_dirs)
+ self.assertIn(py_include, cmd.include_dirs)
plat_py_include = sysconfig.get_python_inc(plat_specific=1)
- self.assertTrue(plat_py_include in cmd.include_dirs)
+ self.assertIn(plat_py_include, cmd.include_dirs)
# make sure cmd.libraries is turned into a list
# if it's a string
@@ -226,13 +224,13 @@
'some': 'bar'})]
cmd.check_extensions_list(exts)
ext = exts[0]
- self.assertTrue(isinstance(ext, Extension))
+ self.assertIsInstance(ext, Extension)
# check_extensions_list adds in ext the values passed
# when they are in ('include_dirs', 'library_dirs', 'libraries'
# 'extra_objects', 'extra_compile_args', 'extra_link_args')
self.assertEqual(ext.libraries, 'foo')
- self.assertTrue(not hasattr(ext, 'some'))
+ self.assertFalse(hasattr(ext, 'some'))
# 'macros' element of build info dict must be 1- or 2-tuple
exts = [('foo.bar', {'sources': [''], 'libraries': 'foo',
@@ -414,9 +412,8 @@
wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext)
self.assertEqual(ext_path, wanted)
+ @unittest.skipUnless(sys.platform == 'win32', 'these tests require Windows')
def test_build_ext_path_cross_platform(self):
- if sys.platform != 'win32':
- return
dist = Distribution({'name': 'UpdateManager'})
cmd = build_ext(dist)
cmd.ensure_finalized()
diff -r 3a1db0d2747e Lib/distutils/tests/test_build_py.py
--- a/Lib/distutils/tests/test_build_py.py
+++ b/Lib/distutils/tests/test_build_py.py
@@ -99,6 +99,37 @@
os.chdir(cwd)
sys.stdout = old_stdout
+ def test_dir_in_package_data(self):
+ """
+ A directory in package_data should not be added to the filelist.
+ """
+ # See bug 19286
+ sources = self.mkdtemp()
+ pkg_dir = os.path.join(sources, "pkg")
+
+ os.mkdir(pkg_dir)
+ open(os.path.join(pkg_dir, "__init__.py"), "w").close()
+
+ docdir = os.path.join(pkg_dir, "doc")
+ os.mkdir(docdir)
+ open(os.path.join(docdir, "testfile"), "w").close()
+
+ # create the directory that could be incorrectly detected as a file
+ os.mkdir(os.path.join(docdir, 'otherdir'))
+
+ os.chdir(sources)
+ dist = Distribution({"packages": ["pkg"],
+ "package_data": {"pkg": ["doc/*"]}})
+ # script_name need not exist, it just need to be initialized
+ dist.script_name = os.path.join(sources, "setup.py")
+ dist.script_args = ["build"]
+ dist.parse_command_line()
+
+ try:
+ dist.run_commands()
+ except DistutilsFileError:
+ self.fail("failed package_data when data dir includes a dir")
+
def test_dont_write_bytecode(self):
# makes sure byte_compile is not used
pkg_dir, dist = self.create_dist()
diff -r 3a1db0d2747e Lib/distutils/tests/test_build_scripts.py
--- a/Lib/distutils/tests/test_build_scripts.py
+++ b/Lib/distutils/tests/test_build_scripts.py
@@ -17,8 +17,8 @@
def test_default_settings(self):
cmd = self.get_build_scripts_cmd("/foo/bar", [])
- self.assertTrue(not cmd.force)
- self.assertTrue(cmd.build_dir is None)
+ self.assertFalse(cmd.force)
+ self.assertIsNone(cmd.build_dir)
cmd.finalize_options()
@@ -38,7 +38,7 @@
built = os.listdir(target)
for name in expected:
- self.assertTrue(name in built)
+ self.assertIn(name, built)
def get_build_scripts_cmd(self, target, scripts):
import sys
@@ -103,7 +103,7 @@
built = os.listdir(target)
for name in expected:
- self.assertTrue(name in built)
+ self.assertIn(name, built)
def test_suite():
return unittest.makeSuite(BuildScriptsTestCase)
diff -r 3a1db0d2747e Lib/distutils/tests/test_ccompiler.py
--- a/Lib/distutils/tests/test_ccompiler.py
+++ b/Lib/distutils/tests/test_ccompiler.py
@@ -55,12 +55,9 @@
finally:
debug.DEBUG = False
+ @unittest.skipUnless(get_default_compiler() == 'unix',
+ 'not testing if default compiler is not unix')
def test_customize_compiler(self):
-
- # not testing if default compiler is not unix
- if get_default_compiler() != 'unix':
- return
-
os.environ['AR'] = 'my_ar'
os.environ['ARFLAGS'] = '-arflags'
diff -r 3a1db0d2747e Lib/distutils/tests/test_check.py
--- a/Lib/distutils/tests/test_check.py
+++ b/Lib/distutils/tests/test_check.py
@@ -56,9 +56,8 @@
cmd = self._run(metadata)
self.assertEqual(cmd._warnings, 0)
+ @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils")
def test_check_document(self):
- if not HAS_DOCUTILS: # won't test without docutils
- return
pkg_info, dist = self.create_dist()
cmd = check(dist)
@@ -72,9 +71,8 @@
msgs = cmd._check_rst_data(rest)
self.assertEqual(len(msgs), 0)
+ @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils")
def test_check_restructuredtext(self):
- if not HAS_DOCUTILS: # won't test without docutils
- return
# let's see if it detects broken rest in long_description
broken_rest = 'title\n===\n\ntest'
pkg_info, dist = self.create_dist(long_description=broken_rest)
diff -r 3a1db0d2747e Lib/distutils/tests/test_clean.py
--- a/Lib/distutils/tests/test_clean.py
+++ b/Lib/distutils/tests/test_clean.py
@@ -36,7 +36,7 @@
# make sure the files where removed
for name, path in dirs:
- self.assertTrue(not os.path.exists(path),
+ self.assertFalse(os.path.exists(path),
'%s was not removed' % path)
# let's run the command again (should spit warnings but succeed)
diff -r 3a1db0d2747e Lib/distutils/tests/test_config.py
--- a/Lib/distutils/tests/test_config.py
+++ b/Lib/distutils/tests/test_config.py
@@ -89,7 +89,7 @@
config = config.items()
config.sort()
waited = [('password', 'secret'), ('realm', 'pypi'),
- ('repository', 'http://pypi.python.org/pypi'),
+ ('repository', 'https://pypi.python.org/pypi'),
('server', 'server1'), ('username', 'me')]
self.assertEqual(config, waited)
@@ -99,14 +99,14 @@
config = config.items()
config.sort()
waited = [('password', 'secret'), ('realm', 'pypi'),
- ('repository', 'http://pypi.python.org/pypi'),
+ ('repository', 'https://pypi.python.org/pypi'),
('server', 'server-login'), ('username', 'tarek')]
self.assertEqual(config, waited)
def test_server_empty_registration(self):
cmd = self._cmd(self.dist)
rc = cmd._get_rc_file()
- self.assertTrue(not os.path.exists(rc))
+ self.assertFalse(os.path.exists(rc))
cmd._store_pypirc('tarek', 'xxx')
self.assertTrue(os.path.exists(rc))
f = open(rc)
diff -r 3a1db0d2747e Lib/distutils/tests/test_config_cmd.py
--- a/Lib/distutils/tests/test_config_cmd.py
+++ b/Lib/distutils/tests/test_config_cmd.py
@@ -37,9 +37,8 @@
dump_file(this_file, 'I am the header')
self.assertEqual(len(self._logs), numlines+1)
+ @unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
def test_search_cpp(self):
- if sys.platform == 'win32':
- return
pkg_dir, dist = self.create_dist()
cmd = config(dist)
@@ -81,7 +80,7 @@
cmd._clean(f1, f2)
for f in (f1, f2):
- self.assertTrue(not os.path.exists(f))
+ self.assertFalse(os.path.exists(f))
def test_suite():
return unittest.makeSuite(ConfigTestCase)
diff -r 3a1db0d2747e Lib/distutils/tests/test_install.py
--- a/Lib/distutils/tests/test_install.py
+++ b/Lib/distutils/tests/test_install.py
@@ -65,11 +65,9 @@
check_path(cmd.install_scripts, os.path.join(destination, "bin"))
check_path(cmd.install_data, destination)
+ @unittest.skipIf(sys.version < '2.6',
+ 'site.USER_SITE was introduced in 2.6')
def test_user_site(self):
- # site.USER_SITE was introduced in 2.6
- if sys.version < '2.6':
- return
-
# preparing the environment for the test
self.old_user_base = site.USER_BASE
self.old_user_site = site.USER_SITE
@@ -237,7 +235,7 @@
self.test_record()
finally:
install_module.DEBUG = False
- self.assertTrue(len(self.logs) > old_logs_len)
+ self.assertGreater(len(self.logs), old_logs_len)
def test_suite():
diff -r 3a1db0d2747e Lib/distutils/tests/test_install_lib.py
--- a/Lib/distutils/tests/test_install_lib.py
+++ b/Lib/distutils/tests/test_install_lib.py
@@ -65,7 +65,7 @@
cmd.distribution.script_name = 'setup.py'
# get_output should return 4 elements
- self.assertTrue(len(cmd.get_outputs()) >= 2)
+ self.assertGreaterEqual(len(cmd.get_outputs()), 2)
def test_get_inputs(self):
pkg_dir, dist = self.create_dist()
@@ -98,7 +98,7 @@
finally:
sys.dont_write_bytecode = old_dont_write_bytecode
- self.assertTrue('byte-compiling is disabled' in self.logs[0][1])
+ self.assertIn('byte-compiling is disabled', self.logs[0][1])
def test_suite():
return unittest.makeSuite(InstallLibTestCase)
diff -r 3a1db0d2747e Lib/distutils/tests/test_install_scripts.py
--- a/Lib/distutils/tests/test_install_scripts.py
+++ b/Lib/distutils/tests/test_install_scripts.py
@@ -24,10 +24,10 @@
skip_build=1,
)
cmd = install_scripts(dist)
- self.assertTrue(not cmd.force)
- self.assertTrue(not cmd.skip_build)
- self.assertTrue(cmd.build_dir is None)
- self.assertTrue(cmd.install_dir is None)
+ self.assertFalse(cmd.force)
+ self.assertFalse(cmd.skip_build)
+ self.assertIsNone(cmd.build_dir)
+ self.assertIsNone(cmd.install_dir)
cmd.finalize_options()
@@ -72,7 +72,7 @@
installed = os.listdir(target)
for name in expected:
- self.assertTrue(name in installed)
+ self.assertIn(name, installed)
def test_suite():
diff -r 3a1db0d2747e Lib/distutils/tests/test_msvc9compiler.py
--- a/Lib/distutils/tests/test_msvc9compiler.py
+++ b/Lib/distutils/tests/test_msvc9compiler.py
@@ -128,7 +128,7 @@
# windows registeries versions.
path = r'Control Panel\Desktop'
v = Reg.get_value(path, u'dragfullwindows')
- self.assertTrue(v in (u'0', u'1', u'2'))
+ self.assertIn(v, (u'0', u'1', u'2'))
import _winreg
HKCU = _winreg.HKEY_CURRENT_USER
@@ -136,7 +136,7 @@
self.assertEqual(keys, None)
keys = Reg.read_keys(HKCU, r'Control Panel')
- self.assertTrue('Desktop' in keys)
+ self.assertIn('Desktop', keys)
def test_remove_visual_c_ref(self):
from distutils.msvc9compiler import MSVCCompiler
@@ -174,7 +174,7 @@
compiler = MSVCCompiler()
got = compiler._remove_visual_c_ref(manifest)
- self.assertIs(got, None)
+ self.assertIsNone(got)
def test_suite():
diff -r 3a1db0d2747e Lib/distutils/tests/test_register.py
--- a/Lib/distutils/tests/test_register.py
+++ b/Lib/distutils/tests/test_register.py
@@ -99,7 +99,7 @@
cmd = self._get_cmd()
# we shouldn't have a .pypirc file yet
- self.assertTrue(not os.path.exists(self.rc))
+ self.assertFalse(os.path.exists(self.rc))
# patching raw_input and getpass.getpass
# so register gets happy
@@ -144,7 +144,7 @@
req1 = dict(self.conn.reqs[0].headers)
req2 = dict(self.conn.reqs[1].headers)
self.assertEqual(req2['Content-length'], req1['Content-length'])
- self.assertTrue('xxx' in self.conn.reqs[1].data)
+ self.assertIn('xxx', self.conn.reqs[1].data)
def test_password_not_in_file(self):
@@ -174,7 +174,7 @@
req = self.conn.reqs[0]
headers = dict(req.headers)
self.assertEqual(headers['Content-length'], '608')
- self.assertTrue('tarek' in req.data)
+ self.assertIn('tarek', req.data)
def test_password_reset(self):
# this test runs choice 3
@@ -192,7 +192,7 @@
req = self.conn.reqs[0]
headers = dict(req.headers)
self.assertEqual(headers['Content-length'], '290')
- self.assertTrue('tarek' in req.data)
+ self.assertIn('tarek', req.data)
@unittest.skipUnless(docutils is not None, 'needs docutils')
def test_strict(self):
diff -r 3a1db0d2747e Lib/distutils/tests/test_sdist.py
--- a/Lib/distutils/tests/test_sdist.py
+++ b/Lib/distutils/tests/test_sdist.py
@@ -134,12 +134,6 @@
@unittest.skipUnless(zlib, "requires zlib")
def test_make_distribution(self):
-
- # check if tar and gzip are installed
- if (find_executable('tar') is None or
- find_executable('gzip') is None):
- return
-
# now building a sdist
dist, cmd = self.get_cmd()
@@ -325,13 +319,11 @@
@unittest.skipUnless(zlib, "requires zlib")
@unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ @unittest.skipIf(find_executable('tar') is None,
+ "The tar command is not found")
+ @unittest.skipIf(find_executable('gzip') is None,
+ "The gzip command is not found")
def test_make_distribution_owner_group(self):
-
- # check if tar and gzip are installed
- if (find_executable('tar') is None or
- find_executable('gzip') is None):
- return
-
# now building a sdist
dist, cmd = self.get_cmd()
diff -r 3a1db0d2747e Lib/distutils/tests/test_sysconfig.py
--- a/Lib/distutils/tests/test_sysconfig.py
+++ b/Lib/distutils/tests/test_sysconfig.py
@@ -95,7 +95,7 @@
import sysconfig as global_sysconfig
if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'):
- return
+ self.skipTest('compiler flags customized')
self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), sysconfig.get_config_var('LDSHARED'))
self.assertEqual(global_sysconfig.get_config_var('CC'), sysconfig.get_config_var('CC'))
diff -r 3a1db0d2747e Lib/distutils/tests/test_unixccompiler.py
--- a/Lib/distutils/tests/test_unixccompiler.py
+++ b/Lib/distutils/tests/test_unixccompiler.py
@@ -21,12 +21,8 @@
sys.platform = self._backup_platform
sysconfig.get_config_var = self._backup_get_config_var
+ @unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
def test_runtime_libdir_option(self):
-
- # not tested under windows
- if sys.platform == 'win32':
- return
-
# Issue#5900
#
# Ensure RUNPATH is added to extension modules with RPATH if
diff -r 3a1db0d2747e Lib/distutils/tests/test_upload.py
--- a/Lib/distutils/tests/test_upload.py
+++ b/Lib/distutils/tests/test_upload.py
@@ -78,7 +78,7 @@
cmd.finalize_options()
for attr, waited in (('username', 'me'), ('password', 'secret'),
('realm', 'pypi'),
- ('repository', 'http://pypi.python.org/pypi')):
+ ('repository', 'https://pypi.python.org/pypi')):
self.assertEqual(getattr(cmd, attr), waited)
def test_saved_password(self):
@@ -119,10 +119,10 @@
self.assertTrue(headers['Content-type'].startswith('multipart/form-data'))
self.assertEqual(self.last_open.req.get_method(), 'POST')
self.assertEqual(self.last_open.req.get_full_url(),
- 'http://pypi.python.org/pypi')
- self.assertTrue('xxx' in self.last_open.req.data)
+ 'https://pypi.python.org/pypi')
+ self.assertIn('xxx', self.last_open.req.data)
auth = self.last_open.req.headers['Authorization']
- self.assertFalse('\n' in auth)
+ self.assertNotIn('\n', auth)
def test_suite():
return unittest.makeSuite(uploadTestCase)
diff -r 3a1db0d2747e Lib/distutils/tests/test_util.py
--- a/Lib/distutils/tests/test_util.py
+++ b/Lib/distutils/tests/test_util.py
@@ -3,8 +3,9 @@
import unittest
from test.test_support import run_unittest
-from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError
-from distutils.util import byte_compile
+from distutils.errors import DistutilsByteCompileError
+from distutils.util import byte_compile, grok_environment_error
+
class UtilTestCase(unittest.TestCase):
@@ -18,6 +19,13 @@
finally:
sys.dont_write_bytecode = old_dont_write_bytecode
+ def test_grok_environment_error(self):
+ # test obsolete function to ensure backward compat (#4931)
+ exc = IOError("Unable to find batch file")
+ msg = grok_environment_error(exc)
+ self.assertEqual(msg, "error: Unable to find batch file")
+
+
def test_suite():
return unittest.makeSuite(UtilTestCase)
diff -r 3a1db0d2747e Lib/distutils/util.py
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -213,25 +213,10 @@
def grok_environment_error (exc, prefix="error: "):
- """Generate a useful error message from an EnvironmentError (IOError or
- OSError) exception object. Handles Python 1.5.1 and 1.5.2 styles, and
- does what it can to deal with exception objects that don't have a
- filename (which happens when the error is due to a two-file operation,
- such as 'rename()' or 'link()'. Returns the error message as a string
- prefixed with 'prefix'.
- """
- # check for Python 1.5.2-style {IO,OS}Error exception objects
- if hasattr(exc, 'filename') and hasattr(exc, 'strerror'):
- if exc.filename:
- error = prefix + "%s: %s" % (exc.filename, exc.strerror)
- else:
- # two-argument functions in posix module don't
- # include the filename in the exception object!
- error = prefix + "%s" % exc.strerror
- else:
- error = prefix + str(exc[-1])
-
- return error
+ # Function kept for backward compatibility.
+ # Used to try clever things with EnvironmentErrors,
+ # but nowadays str(exception) produces good messages.
+ return prefix + str(exc)
# Needed by 'split_quoted()'
diff -r 3a1db0d2747e Lib/doctest.py
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -326,6 +326,32 @@
else:
return '#'
+def _strip_exception_details(msg):
+ # Support for IGNORE_EXCEPTION_DETAIL.
+ # Get rid of everything except the exception name; in particular, drop
+ # the possibly dotted module path (if any) and the exception message (if
+ # any). We assume that a colon is never part of a dotted name, or of an
+ # exception name.
+ # E.g., given
+ # "foo.bar.MyError: la di da"
+ # return "MyError"
+ # Or for "abc.def" or "abc.def:\n" return "def".
+
+ start, end = 0, len(msg)
+ # The exception name must appear on the first line.
+ i = msg.find("\n")
+ if i >= 0:
+ end = i
+ # retain up to the first colon (if any)
+ i = msg.find(':', 0, end)
+ if i >= 0:
+ end = i
+ # retain just the exception name
+ i = msg.rfind('.', 0, end)
+ if i >= 0:
+ start = i+1
+ return msg[start: end]
+
class _OutputRedirectingPdb(pdb.Pdb):
"""
A specialized version of the python debugger that redirects stdout
@@ -1323,10 +1349,9 @@
# Another chance if they didn't care about the detail.
elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
- m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg)
- m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg)
- if m1 and m2 and check(m1.group(1), m2.group(1),
- self.optionflags):
+ if check(_strip_exception_details(example.exc_msg),
+ _strip_exception_details(exc_msg),
+ self.optionflags):
outcome = SUCCESS
# Report the outcome.
diff -r 3a1db0d2747e Lib/email/generator.py
--- a/Lib/email/generator.py
+++ b/Lib/email/generator.py
@@ -231,9 +231,8 @@
# body-part
self._fp.write(body_part)
# close-delimiter transport-padding
- self._fp.write('\n--' + boundary + '--')
+ self._fp.write('\n--' + boundary + '--' + NL)
if msg.epilogue is not None:
- print >> self._fp
if self._mangle_from_:
epilogue = fcre.sub('>From ', msg.epilogue)
else:
diff -r 3a1db0d2747e Lib/email/test/data/msg_02.txt
--- a/Lib/email/test/data/msg_02.txt
+++ b/Lib/email/test/data/msg_02.txt
@@ -119,6 +119,7 @@
--__--__----
+
--192.168.1.2.889.32614.987812255.500.21814
Content-type: text/plain; charset=us-ascii
Content-description: Digest Footer
diff -r 3a1db0d2747e Lib/email/test/test_email.py
--- a/Lib/email/test/test_email.py
+++ b/Lib/email/test/test_email.py
@@ -267,12 +267,12 @@
msg['From'] = 'Me'
msg['to'] = 'You'
# Check for case insensitivity
- self.assertTrue('from' in msg)
- self.assertTrue('From' in msg)
- self.assertTrue('FROM' in msg)
- self.assertTrue('to' in msg)
- self.assertTrue('To' in msg)
- self.assertTrue('TO' in msg)
+ self.assertIn('from', msg)
+ self.assertIn('From', msg)
+ self.assertIn('FROM', msg)
+ self.assertIn('to', msg)
+ self.assertIn('To', msg)
+ self.assertIn('TO', msg)
def test_as_string(self):
eq = self.assertEqual
@@ -1002,7 +1002,6 @@
def test_add_header(self):
eq = self.assertEqual
- unless = self.assertTrue
self._au.add_header('Content-Disposition', 'attachment',
filename='audiotest.au')
eq(self._au['content-disposition'],
@@ -1013,12 +1012,12 @@
'audiotest.au')
missing = []
eq(self._au.get_param('attachment', header='content-disposition'), '')
- unless(self._au.get_param('foo', failobj=missing,
- header='content-disposition') is missing)
+ self.assertIs(self._au.get_param('foo', failobj=missing,
+ header='content-disposition'), missing)
# Try some missing stuff
- unless(self._au.get_param('foobar', missing) is missing)
- unless(self._au.get_param('attachment', missing,
- header='foobar') is missing)
+ self.assertIs(self._au.get_param('foobar', missing), missing)
+ self.assertIs(self._au.get_param('attachment', missing,
+ header='foobar'), missing)
@@ -1045,7 +1044,6 @@
def test_add_header(self):
eq = self.assertEqual
- unless = self.assertTrue
self._im.add_header('Content-Disposition', 'attachment',
filename='dingusfish.gif')
eq(self._im['content-disposition'],
@@ -1056,12 +1054,12 @@
'dingusfish.gif')
missing = []
eq(self._im.get_param('attachment', header='content-disposition'), '')
- unless(self._im.get_param('foo', failobj=missing,
- header='content-disposition') is missing)
+ self.assertIs(self._im.get_param('foo', failobj=missing,
+ header='content-disposition'), missing)
# Try some missing stuff
- unless(self._im.get_param('foobar', missing) is missing)
- unless(self._im.get_param('attachment', missing,
- header='foobar') is missing)
+ self.assertIs(self._im.get_param('foobar', missing), missing)
+ self.assertIs(self._im.get_param('attachment', missing,
+ header='foobar'), missing)
@@ -1072,17 +1070,16 @@
def test_types(self):
eq = self.assertEqual
- unless = self.assertTrue
eq(self._msg.get_content_type(), 'text/plain')
eq(self._msg.get_param('charset'), 'us-ascii')
missing = []
- unless(self._msg.get_param('foobar', missing) is missing)
- unless(self._msg.get_param('charset', missing, header='foobar')
- is missing)
+ self.assertIs(self._msg.get_param('foobar', missing), missing)
+ self.assertIs(self._msg.get_param('charset', missing, header='foobar'),
+ missing)
def test_payload(self):
self.assertEqual(self._msg.get_payload(), 'hello there')
- self.assertTrue(not self._msg.is_multipart())
+ self.assertFalse(self._msg.is_multipart())
def test_charset(self):
eq = self.assertEqual
@@ -1101,7 +1098,7 @@
msg = MIMEText(u'hello there')
eq(msg.get_charset(), 'us-ascii')
eq(msg['content-type'], 'text/plain; charset="us-ascii"')
- self.assertTrue('hello there' in msg.as_string())
+ self.assertIn('hello there', msg.as_string())
def test_8bit_unicode_input(self):
teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430'
@@ -1162,21 +1159,20 @@
def test_hierarchy(self):
# convenience
eq = self.assertEqual
- unless = self.assertTrue
raises = self.assertRaises
# tests
m = self._msg
- unless(m.is_multipart())
+ self.assertTrue(m.is_multipart())
eq(m.get_content_type(), 'multipart/mixed')
eq(len(m.get_payload()), 2)
raises(IndexError, m.get_payload, 2)
m0 = m.get_payload(0)
m1 = m.get_payload(1)
- unless(m0 is self._txt)
- unless(m1 is self._im)
+ self.assertIs(m0, self._txt)
+ self.assertIs(m1, self._im)
eq(m.get_payload(), [m0, m1])
- unless(not m0.is_multipart())
- unless(not m1.is_multipart())
+ self.assertFalse(m0.is_multipart())
+ self.assertFalse(m1.is_multipart())
def test_empty_multipart_idempotent(self):
text = """\
@@ -1210,7 +1206,8 @@
--BOUNDARY
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_no_parts_in_a_multipart_with_empty_epilogue(self):
outer = MIMEBase('multipart', 'mixed')
@@ -1255,7 +1252,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_empty_preamble(self):
eq = self.ndiffAssertEqual
@@ -1281,7 +1279,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_none_preamble(self):
@@ -1307,7 +1306,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_none_epilogue(self):
@@ -1333,7 +1333,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_empty_epilogue(self):
@@ -1506,23 +1507,22 @@
eq(msg.get_content_subtype(), 'plain')
def test_same_boundary_inner_outer(self):
- unless = self.assertTrue
msg = self._msgobj('msg_15.txt')
# XXX We can probably eventually do better
inner = msg.get_payload(0)
- unless(hasattr(inner, 'defects'))
+ self.assertTrue(hasattr(inner, 'defects'))
self.assertEqual(len(inner.defects), 1)
- unless(isinstance(inner.defects[0],
- Errors.StartBoundaryNotFoundDefect))
+ self.assertIsInstance(inner.defects[0],
+ Errors.StartBoundaryNotFoundDefect)
def test_multipart_no_boundary(self):
- unless = self.assertTrue
msg = self._msgobj('msg_25.txt')
- unless(isinstance(msg.get_payload(), str))
+ self.assertIsInstance(msg.get_payload(), str)
self.assertEqual(len(msg.defects), 2)
- unless(isinstance(msg.defects[0], Errors.NoBoundaryInMultipartDefect))
- unless(isinstance(msg.defects[1],
- Errors.MultipartInvariantViolationDefect))
+ self.assertIsInstance(msg.defects[0],
+ Errors.NoBoundaryInMultipartDefect)
+ self.assertIsInstance(msg.defects[1],
+ Errors.MultipartInvariantViolationDefect)
def test_invalid_content_type(self):
eq = self.assertEqual
@@ -1574,13 +1574,13 @@
""")
def test_lying_multipart(self):
- unless = self.assertTrue
msg = self._msgobj('msg_41.txt')
- unless(hasattr(msg, 'defects'))
+ self.assertTrue(hasattr(msg, 'defects'))
self.assertEqual(len(msg.defects), 2)
- unless(isinstance(msg.defects[0], Errors.NoBoundaryInMultipartDefect))
- unless(isinstance(msg.defects[1],
- Errors.MultipartInvariantViolationDefect))
+ self.assertIsInstance(msg.defects[0],
+ Errors.NoBoundaryInMultipartDefect)
+ self.assertIsInstance(msg.defects[1],
+ Errors.MultipartInvariantViolationDefect)
def test_missing_start_boundary(self):
outer = self._msgobj('msg_42.txt')
@@ -1594,8 +1594,8 @@
# [*] This message is missing its start boundary
bad = outer.get_payload(1).get_payload(0)
self.assertEqual(len(bad.defects), 1)
- self.assertTrue(isinstance(bad.defects[0],
- Errors.StartBoundaryNotFoundDefect))
+ self.assertIsInstance(bad.defects[0],
+ Errors.StartBoundaryNotFoundDefect)
def test_first_line_is_continuation_header(self):
eq = self.assertEqual
@@ -1604,8 +1604,8 @@
eq(msg.keys(), [])
eq(msg.get_payload(), 'Line 2\nLine 3')
eq(len(msg.defects), 1)
- self.assertTrue(isinstance(msg.defects[0],
- Errors.FirstHeaderLineIsContinuationDefect))
+ self.assertIsInstance(msg.defects[0],
+ Errors.FirstHeaderLineIsContinuationDefect)
eq(msg.defects[0].line, ' Line 1\n')
@@ -1687,17 +1687,16 @@
def test_valid_argument(self):
eq = self.assertEqual
- unless = self.assertTrue
subject = 'A sub-message'
m = Message()
m['Subject'] = subject
r = MIMEMessage(m)
eq(r.get_content_type(), 'message/rfc822')
payload = r.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
subpart = payload[0]
- unless(subpart is m)
+ self.assertIs(subpart, m)
eq(subpart['subject'], subject)
def test_bad_multipart(self):
@@ -1731,24 +1730,22 @@
def test_parse_message_rfc822(self):
eq = self.assertEqual
- unless = self.assertTrue
msg = self._msgobj('msg_11.txt')
eq(msg.get_content_type(), 'message/rfc822')
payload = msg.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
submsg = payload[0]
- self.assertTrue(isinstance(submsg, Message))
+ self.assertIsInstance(submsg, Message)
eq(submsg['subject'], 'An enclosed message')
eq(submsg.get_payload(), 'Here is the body of the message.\n')
def test_dsn(self):
eq = self.assertEqual
- unless = self.assertTrue
# msg 16 is a Delivery Status Notification, see RFC 1894
msg = self._msgobj('msg_16.txt')
eq(msg.get_content_type(), 'multipart/report')
- unless(msg.is_multipart())
+ self.assertTrue(msg.is_multipart())
eq(len(msg.get_payload()), 3)
# Subpart 1 is a text/plain, human readable section
subpart = msg.get_payload(0)
@@ -1777,13 +1774,13 @@
# message/delivery-status should treat each block as a bunch of
# headers, i.e. a bunch of Message objects.
dsn1 = subpart.get_payload(0)
- unless(isinstance(dsn1, Message))
+ self.assertIsInstance(dsn1, Message)
eq(dsn1['original-envelope-id'], '0GK500B4HD0888@cougar.noc.ucla.edu')
eq(dsn1.get_param('dns', header='reporting-mta'), '')
# Try a missing one <wink>
eq(dsn1.get_param('nsd', header='reporting-mta'), None)
dsn2 = subpart.get_payload(1)
- unless(isinstance(dsn2, Message))
+ self.assertIsInstance(dsn2, Message)
eq(dsn2['action'], 'failed')
eq(dsn2.get_params(header='original-recipient'),
[('rfc822', ''), ('jangel1@cougar.noc.ucla.edu', '')])
@@ -1792,10 +1789,10 @@
subpart = msg.get_payload(2)
eq(subpart.get_content_type(), 'message/rfc822')
payload = subpart.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
subsubpart = payload[0]
- unless(isinstance(subsubpart, Message))
+ self.assertIsInstance(subsubpart, Message)
eq(subsubpart.get_content_type(), 'text/plain')
eq(subsubpart['message-id'],
'<002001c144a6$8752e060$56104586@oxy.edu>')
@@ -2094,7 +2091,6 @@
def test_content_type(self):
eq = self.assertEqual
- unless = self.assertTrue
# Get a message object and reset the seek pointer for other tests
msg, text = self._msgobj('msg_05.txt')
eq(msg.get_content_type(), 'multipart/report')
@@ -2116,29 +2112,28 @@
eq(msg2.get_payload(), 'Yadda yadda yadda\n')
msg3 = msg.get_payload(2)
eq(msg3.get_content_type(), 'message/rfc822')
- self.assertTrue(isinstance(msg3, Message))
+ self.assertIsInstance(msg3, Message)
payload = msg3.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
msg4 = payload[0]
- unless(isinstance(msg4, Message))
+ self.assertIsInstance(msg4, Message)
eq(msg4.get_payload(), 'Yadda yadda yadda\n')
def test_parser(self):
eq = self.assertEqual
- unless = self.assertTrue
msg, text = self._msgobj('msg_06.txt')
# Check some of the outer headers
eq(msg.get_content_type(), 'message/rfc822')
# Make sure the payload is a list of exactly one sub-Message, and that
# that submessage has a type of text/plain
payload = msg.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
msg1 = payload[0]
- self.assertTrue(isinstance(msg1, Message))
+ self.assertIsInstance(msg1, Message)
eq(msg1.get_content_type(), 'text/plain')
- self.assertTrue(isinstance(msg1.get_payload(), str))
+ self.assertIsInstance(msg1.get_payload(), str)
eq(msg1.get_payload(), '\n')
@@ -2175,7 +2170,6 @@
fp.close()
def test_message_from_string_with_class(self):
- unless = self.assertTrue
fp = openfile('msg_01.txt')
try:
text = fp.read()
@@ -2186,7 +2180,7 @@
pass
msg = email.message_from_string(text, MyMessage)
- unless(isinstance(msg, MyMessage))
+ self.assertIsInstance(msg, MyMessage)
# Try something more complicated
fp = openfile('msg_02.txt')
try:
@@ -2195,10 +2189,9 @@
fp.close()
msg = email.message_from_string(text, MyMessage)
for subpart in msg.walk():
- unless(isinstance(subpart, MyMessage))
+ self.assertIsInstance(subpart, MyMessage)
def test_message_from_file_with_class(self):
- unless = self.assertTrue
# Create a subclass
class MyMessage(Message):
pass
@@ -2208,7 +2201,7 @@
msg = email.message_from_file(fp, MyMessage)
finally:
fp.close()
- unless(isinstance(msg, MyMessage))
+ self.assertIsInstance(msg, MyMessage)
# Try something more complicated
fp = openfile('msg_02.txt')
try:
@@ -2216,7 +2209,7 @@
finally:
fp.close()
for subpart in msg.walk():
- unless(isinstance(subpart, MyMessage))
+ self.assertIsInstance(subpart, MyMessage)
def test__all__(self):
module = __import__('email')
@@ -2591,9 +2584,9 @@
break
om.append(ol)
n1 += 1
- self.assertTrue(n == n1)
- self.assertTrue(len(om) == nt)
- self.assertTrue(''.join([il for il, n in imt]) == ''.join(om))
+ self.assertEqual(n, n1)
+ self.assertEqual(len(om), nt)
+ self.assertEqual(''.join([il for il, n in imt]), ''.join(om))
@@ -2610,7 +2603,7 @@
eq(msg['to'], 'ppp@zzz.org')
eq(msg.get_content_type(), 'multipart/mixed')
self.assertFalse(msg.is_multipart())
- self.assertTrue(isinstance(msg.get_payload(), str))
+ self.assertIsInstance(msg.get_payload(), str)
def test_whitespace_continuation(self):
eq = self.assertEqual
@@ -3027,7 +3020,7 @@
h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.",
maxlinelen=76)
for l in h.encode(splitchars=' ').split('\n '):
- self.assertTrue(len(l) <= 76)
+ self.assertLessEqual(len(l), 76)
def test_multilingual(self):
eq = self.ndiffAssertEqual
@@ -3279,7 +3272,7 @@
'''
msg = email.message_from_string(m)
param = msg.get_param('NAME')
- self.assertFalse(isinstance(param, tuple))
+ self.assertNotIsInstance(param, tuple)
self.assertEqual(
param,
'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')
@@ -3432,7 +3425,7 @@
"""
msg = email.message_from_string(m)
param = msg.get_param('name')
- self.assertFalse(isinstance(param, tuple))
+ self.assertNotIsInstance(param, tuple)
self.assertEqual(param, "Frank's Document")
def test_rfc2231_tick_attack_extended(self):
@@ -3456,7 +3449,7 @@
"""
msg = email.message_from_string(m)
param = msg.get_param('name')
- self.assertFalse(isinstance(param, tuple))
+ self.assertNotIsInstance(param, tuple)
self.assertEqual(param, "us-ascii'en-us'Frank's Document")
def test_rfc2231_no_extended_values(self):
diff -r 3a1db0d2747e Lib/email/test/test_email_renamed.py
--- a/Lib/email/test/test_email_renamed.py
+++ b/Lib/email/test/test_email_renamed.py
@@ -231,12 +231,12 @@
msg['From'] = 'Me'
msg['to'] = 'You'
# Check for case insensitivity
- self.assertTrue('from' in msg)
- self.assertTrue('From' in msg)
- self.assertTrue('FROM' in msg)
- self.assertTrue('to' in msg)
- self.assertTrue('To' in msg)
- self.assertTrue('TO' in msg)
+ self.assertIn('from', msg)
+ self.assertIn('From', msg)
+ self.assertIn('FROM', msg)
+ self.assertIn('to', msg)
+ self.assertIn('To', msg)
+ self.assertIn('TO', msg)
def test_as_string(self):
eq = self.assertEqual
@@ -916,7 +916,6 @@
def test_add_header(self):
eq = self.assertEqual
- unless = self.assertTrue
self._au.add_header('Content-Disposition', 'attachment',
filename='audiotest.au')
eq(self._au['content-disposition'],
@@ -927,12 +926,13 @@
'audiotest.au')
missing = []
eq(self._au.get_param('attachment', header='content-disposition'), '')
- unless(self._au.get_param('foo', failobj=missing,
- header='content-disposition') is missing)
+ self.assertIs(self._au.get_param('foo', failobj=missing,
+ header='content-disposition'),
+ missing)
# Try some missing stuff
- unless(self._au.get_param('foobar', missing) is missing)
- unless(self._au.get_param('attachment', missing,
- header='foobar') is missing)
+ self.assertIs(self._au.get_param('foobar', missing), missing)
+ self.assertIs(self._au.get_param('attachment', missing,
+ header='foobar'), missing)
@@ -959,7 +959,6 @@
def test_add_header(self):
eq = self.assertEqual
- unless = self.assertTrue
self._im.add_header('Content-Disposition', 'attachment',
filename='dingusfish.gif')
eq(self._im['content-disposition'],
@@ -970,12 +969,13 @@
'dingusfish.gif')
missing = []
eq(self._im.get_param('attachment', header='content-disposition'), '')
- unless(self._im.get_param('foo', failobj=missing,
- header='content-disposition') is missing)
+ self.assertIs(self._im.get_param('foo', failobj=missing,
+ header='content-disposition'),
+ missing)
# Try some missing stuff
- unless(self._im.get_param('foobar', missing) is missing)
- unless(self._im.get_param('attachment', missing,
- header='foobar') is missing)
+ self.assertIs(self._im.get_param('foobar', missing), missing)
+ self.assertIs(self._im.get_param('attachment', missing,
+ header='foobar'), missing)
@@ -1035,17 +1035,16 @@
def test_types(self):
eq = self.assertEqual
- unless = self.assertTrue
eq(self._msg.get_content_type(), 'text/plain')
eq(self._msg.get_param('charset'), 'us-ascii')
missing = []
- unless(self._msg.get_param('foobar', missing) is missing)
- unless(self._msg.get_param('charset', missing, header='foobar')
- is missing)
+ self.assertIs(self._msg.get_param('foobar', missing), missing)
+ self.assertIs(self._msg.get_param('charset', missing, header='foobar'),
+ missing)
def test_payload(self):
self.assertEqual(self._msg.get_payload(), 'hello there')
- self.assertTrue(not self._msg.is_multipart())
+ self.assertFalse(self._msg.is_multipart())
def test_charset(self):
eq = self.assertEqual
@@ -1100,21 +1099,20 @@
def test_hierarchy(self):
# convenience
eq = self.assertEqual
- unless = self.assertTrue
raises = self.assertRaises
# tests
m = self._msg
- unless(m.is_multipart())
+ self.assertTrue(m.is_multipart())
eq(m.get_content_type(), 'multipart/mixed')
eq(len(m.get_payload()), 2)
raises(IndexError, m.get_payload, 2)
m0 = m.get_payload(0)
m1 = m.get_payload(1)
- unless(m0 is self._txt)
- unless(m1 is self._im)
+ self.assertIs(m0, self._txt)
+ self.assertIs(m1, self._im)
eq(m.get_payload(), [m0, m1])
- unless(not m0.is_multipart())
- unless(not m1.is_multipart())
+ self.assertFalse(m0.is_multipart())
+ self.assertFalse(m1.is_multipart())
def test_empty_multipart_idempotent(self):
text = """\
@@ -1148,7 +1146,8 @@
--BOUNDARY
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_no_parts_in_a_multipart_with_empty_epilogue(self):
outer = MIMEBase('multipart', 'mixed')
@@ -1193,7 +1192,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_empty_preamble(self):
eq = self.ndiffAssertEqual
@@ -1219,7 +1219,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_none_preamble(self):
@@ -1245,7 +1246,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_none_epilogue(self):
@@ -1271,7 +1273,8 @@
Content-Transfer-Encoding: 7bit
hello world
---BOUNDARY--''')
+--BOUNDARY--
+''')
def test_seq_parts_in_a_multipart_with_empty_epilogue(self):
@@ -1444,23 +1447,22 @@
eq(msg.get_content_subtype(), 'plain')
def test_same_boundary_inner_outer(self):
- unless = self.assertTrue
msg = self._msgobj('msg_15.txt')
# XXX We can probably eventually do better
inner = msg.get_payload(0)
- unless(hasattr(inner, 'defects'))
+ self.assertTrue(hasattr(inner, 'defects'))
self.assertEqual(len(inner.defects), 1)
- unless(isinstance(inner.defects[0],
- errors.StartBoundaryNotFoundDefect))
+ self.assertIsInstance(inner.defects[0],
+ errors.StartBoundaryNotFoundDefect)
def test_multipart_no_boundary(self):
- unless = self.assertTrue
msg = self._msgobj('msg_25.txt')
- unless(isinstance(msg.get_payload(), str))
+ self.assertIsInstance(msg.get_payload(), str)
self.assertEqual(len(msg.defects), 2)
- unless(isinstance(msg.defects[0], errors.NoBoundaryInMultipartDefect))
- unless(isinstance(msg.defects[1],
- errors.MultipartInvariantViolationDefect))
+ self.assertIsInstance(msg.defects[0],
+ errors.NoBoundaryInMultipartDefect)
+ self.assertIsInstance(msg.defects[1],
+ errors.MultipartInvariantViolationDefect)
def test_invalid_content_type(self):
eq = self.assertEqual
@@ -1512,13 +1514,13 @@
""")
def test_lying_multipart(self):
- unless = self.assertTrue
msg = self._msgobj('msg_41.txt')
- unless(hasattr(msg, 'defects'))
+ self.assertTrue(hasattr(msg, 'defects'))
self.assertEqual(len(msg.defects), 2)
- unless(isinstance(msg.defects[0], errors.NoBoundaryInMultipartDefect))
- unless(isinstance(msg.defects[1],
- errors.MultipartInvariantViolationDefect))
+ self.assertIsInstance(msg.defects[0],
+ errors.NoBoundaryInMultipartDefect)
+ self.assertIsInstance(msg.defects[1],
+ errors.MultipartInvariantViolationDefect)
def test_missing_start_boundary(self):
outer = self._msgobj('msg_42.txt')
@@ -1532,8 +1534,8 @@
# [*] This message is missing its start boundary
bad = outer.get_payload(1).get_payload(0)
self.assertEqual(len(bad.defects), 1)
- self.assertTrue(isinstance(bad.defects[0],
- errors.StartBoundaryNotFoundDefect))
+ self.assertIsInstance(bad.defects[0],
+ errors.StartBoundaryNotFoundDefect)
def test_first_line_is_continuation_header(self):
eq = self.assertEqual
@@ -1542,8 +1544,8 @@
eq(msg.keys(), [])
eq(msg.get_payload(), 'Line 2\nLine 3')
eq(len(msg.defects), 1)
- self.assertTrue(isinstance(msg.defects[0],
- errors.FirstHeaderLineIsContinuationDefect))
+ self.assertIsInstance(msg.defects[0],
+ errors.FirstHeaderLineIsContinuationDefect)
eq(msg.defects[0].line, ' Line 1\n')
@@ -1609,17 +1611,16 @@
def test_valid_argument(self):
eq = self.assertEqual
- unless = self.assertTrue
subject = 'A sub-message'
m = Message()
m['Subject'] = subject
r = MIMEMessage(m)
eq(r.get_content_type(), 'message/rfc822')
payload = r.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
subpart = payload[0]
- unless(subpart is m)
+ self.assertIs(subpart, m)
eq(subpart['subject'], subject)
def test_bad_multipart(self):
@@ -1653,24 +1654,22 @@
def test_parse_message_rfc822(self):
eq = self.assertEqual
- unless = self.assertTrue
msg = self._msgobj('msg_11.txt')
eq(msg.get_content_type(), 'message/rfc822')
payload = msg.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
submsg = payload[0]
- self.assertTrue(isinstance(submsg, Message))
+ self.assertIsInstance(submsg, Message)
eq(submsg['subject'], 'An enclosed message')
eq(submsg.get_payload(), 'Here is the body of the message.\n')
def test_dsn(self):
eq = self.assertEqual
- unless = self.assertTrue
# msg 16 is a Delivery Status Notification, see RFC 1894
msg = self._msgobj('msg_16.txt')
eq(msg.get_content_type(), 'multipart/report')
- unless(msg.is_multipart())
+ self.assertTrue(msg.is_multipart())
eq(len(msg.get_payload()), 3)
# Subpart 1 is a text/plain, human readable section
subpart = msg.get_payload(0)
@@ -1699,13 +1698,13 @@
# message/delivery-status should treat each block as a bunch of
# headers, i.e. a bunch of Message objects.
dsn1 = subpart.get_payload(0)
- unless(isinstance(dsn1, Message))
+ self.assertIsInstance(dsn1, Message)
eq(dsn1['original-envelope-id'], '0GK500B4HD0888@cougar.noc.ucla.edu')
eq(dsn1.get_param('dns', header='reporting-mta'), '')
# Try a missing one <wink>
eq(dsn1.get_param('nsd', header='reporting-mta'), None)
dsn2 = subpart.get_payload(1)
- unless(isinstance(dsn2, Message))
+ self.assertIsInstance(dsn2, Message)
eq(dsn2['action'], 'failed')
eq(dsn2.get_params(header='original-recipient'),
[('rfc822', ''), ('jangel1@cougar.noc.ucla.edu', '')])
@@ -1714,10 +1713,10 @@
subpart = msg.get_payload(2)
eq(subpart.get_content_type(), 'message/rfc822')
payload = subpart.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
subsubpart = payload[0]
- unless(isinstance(subsubpart, Message))
+ self.assertIsInstance(subsubpart, Message)
eq(subsubpart.get_content_type(), 'text/plain')
eq(subsubpart['message-id'],
'<002001c144a6$8752e060$56104586@oxy.edu>')
@@ -2013,7 +2012,6 @@
def test_content_type(self):
eq = self.assertEqual
- unless = self.assertTrue
# Get a message object and reset the seek pointer for other tests
msg, text = self._msgobj('msg_05.txt')
eq(msg.get_content_type(), 'multipart/report')
@@ -2035,29 +2033,28 @@
eq(msg2.get_payload(), 'Yadda yadda yadda\n')
msg3 = msg.get_payload(2)
eq(msg3.get_content_type(), 'message/rfc822')
- self.assertTrue(isinstance(msg3, Message))
+ self.assertIsInstance(msg3, Message)
payload = msg3.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
msg4 = payload[0]
- unless(isinstance(msg4, Message))
+ self.assertIsInstance(msg4, Message)
eq(msg4.get_payload(), 'Yadda yadda yadda\n')
def test_parser(self):
eq = self.assertEqual
- unless = self.assertTrue
msg, text = self._msgobj('msg_06.txt')
# Check some of the outer headers
eq(msg.get_content_type(), 'message/rfc822')
# Make sure the payload is a list of exactly one sub-Message, and that
# that submessage has a type of text/plain
payload = msg.get_payload()
- unless(isinstance(payload, list))
+ self.assertIsInstance(payload, list)
eq(len(payload), 1)
msg1 = payload[0]
- self.assertTrue(isinstance(msg1, Message))
+ self.assertIsInstance(msg1, Message)
eq(msg1.get_content_type(), 'text/plain')
- self.assertTrue(isinstance(msg1.get_payload(), str))
+ self.assertIsInstance(msg1.get_payload(), str)
eq(msg1.get_payload(), '\n')
@@ -2094,7 +2091,6 @@
fp.close()
def test_message_from_string_with_class(self):
- unless = self.assertTrue
fp = openfile('msg_01.txt')
try:
text = fp.read()
@@ -2105,7 +2101,7 @@
pass
msg = email.message_from_string(text, MyMessage)
- unless(isinstance(msg, MyMessage))
+ self.assertIsInstance(msg, MyMessage)
# Try something more complicated
fp = openfile('msg_02.txt')
try:
@@ -2114,10 +2110,9 @@
fp.close()
msg = email.message_from_string(text, MyMessage)
for subpart in msg.walk():
- unless(isinstance(subpart, MyMessage))
+ self.assertIsInstance(subpart, MyMessage)
def test_message_from_file_with_class(self):
- unless = self.assertTrue
# Create a subclass
class MyMessage(Message):
pass
@@ -2127,7 +2122,7 @@
msg = email.message_from_file(fp, MyMessage)
finally:
fp.close()
- unless(isinstance(msg, MyMessage))
+ self.assertIsInstance(msg, MyMessage)
# Try something more complicated
fp = openfile('msg_02.txt')
try:
@@ -2135,7 +2130,7 @@
finally:
fp.close()
for subpart in msg.walk():
- unless(isinstance(subpart, MyMessage))
+ self.assertIsInstance(subpart, MyMessage)
def test__all__(self):
module = __import__('email')
@@ -2460,7 +2455,7 @@
eq(msg['to'], 'ppp@zzz.org')
eq(msg.get_content_type(), 'multipart/mixed')
self.assertFalse(msg.is_multipart())
- self.assertTrue(isinstance(msg.get_payload(), str))
+ self.assertIsInstance(msg.get_payload(), str)
def test_whitespace_continuation(self):
eq = self.assertEqual
@@ -2856,7 +2851,7 @@
h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.",
maxlinelen=76)
for l in h.encode(splitchars=' ').split('\n '):
- self.assertTrue(len(l) <= 76)
+ self.assertLessEqual(len(l), 76)
def test_multilingual(self):
eq = self.ndiffAssertEqual
diff -r 3a1db0d2747e Lib/fileinput.py
--- a/Lib/fileinput.py
+++ b/Lib/fileinput.py
@@ -387,9 +387,10 @@
def hook_encoded(encoding):
- import codecs
+ import io
def openhook(filename, mode):
- return codecs.open(filename, mode, encoding)
+ mode = mode.replace('U', '').replace('b', '') or 'r'
+ return io.open(filename, mode, encoding=encoding, newline='')
return openhook
diff -r 3a1db0d2747e Lib/httplib.py
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -565,7 +565,7 @@
# connection, and the user is reading more bytes than will be provided
# (for example, reading in 1k chunks)
s = self.fp.read(amt)
- if not s:
+ if not s and amt:
# Ideally, we would raise IncompleteRead if the content-length
# wasn't satisfied, but it might break compatibility.
self.close()
diff -r 3a1db0d2747e Lib/idlelib/CallTipWindow.py
--- a/Lib/idlelib/CallTipWindow.py
+++ b/Lib/idlelib/CallTipWindow.py
@@ -48,13 +48,7 @@
def showtip(self, text, parenleft, parenright):
"""Show the calltip, bind events which will close it and reposition it.
"""
- # truncate overly long calltip
- if len(text) >= 79:
- textlines = text.splitlines()
- for i, line in enumerate(textlines):
- if len(line) > 79:
- textlines[i] = line[:75] + ' ...'
- text = '\n'.join(textlines)
+ # Only called in CallTips, where lines are truncated
self.text = text
if self.tipwindow or not self.text:
return
diff -r 3a1db0d2747e Lib/idlelib/CallTips.py
--- a/Lib/idlelib/CallTips.py
+++ b/Lib/idlelib/CallTips.py
@@ -5,14 +5,15 @@
which disappear when you type a closing parenthesis.
"""
+import __main__
import re
import sys
+import textwrap
import types
from idlelib import CallTipWindow
from idlelib.HyperParser import HyperParser
-import __main__
class CallTips:
@@ -130,99 +131,83 @@
if rc is not None: return rc
return None
+# The following are used in get_arg_text
+_MAX_COLS = 85
+_MAX_LINES = 5 # enough for bytes
+_INDENT = ' '*4 # for wrapped signatures
+
def get_arg_text(ob):
- """Get a string describing the arguments for the given object,
- only if it is callable."""
- arg_text = ""
- if ob is not None and hasattr(ob, '__call__'):
- arg_offset = 0
- if type(ob) in (types.ClassType, types.TypeType):
- # Look for the highest __init__ in the class chain.
- fob = _find_constructor(ob)
- if fob is None:
- fob = lambda: None
- else:
- arg_offset = 1
- elif type(ob)==types.MethodType:
- # bit of a hack for methods - turn it into a function
- # but we drop the "self" param.
- fob = ob.im_func
+ '''Return a string describing the signature of a callable object, or ''.
+
+ For Python-coded functions and methods, the first line is introspected.
+ Delete 'self' parameter for classes (.__init__) and bound methods.
+ The next lines are the first lines of the doc string up to the first
+ empty line or _MAX_LINES. For builtins, this typically includes
+ the arguments in addition to the return value.
+ '''
+ argspec = ""
+ try:
+ ob_call = ob.__call__
+ except BaseException:
+ if type(ob) is types.ClassType: # old-style
+ ob_call = ob
+ else:
+ return argspec
+
+ arg_offset = 0
+ if type(ob) in (types.ClassType, types.TypeType):
+ # Look for the first __init__ in the class chain with .im_func.
+ # Slot wrappers (builtins, classes defined in funcs) do not.
+ fob = _find_constructor(ob)
+ if fob is None:
+ fob = lambda: None
+ else:
arg_offset = 1
- else:
- fob = ob
- # Try to build one for Python defined functions
- if type(fob) in [types.FunctionType, types.LambdaType]:
- argcount = fob.func_code.co_argcount
- real_args = fob.func_code.co_varnames[arg_offset:argcount]
- defaults = fob.func_defaults or []
- defaults = list(map(lambda name: "=%s" % repr(name), defaults))
- defaults = [""] * (len(real_args) - len(defaults)) + defaults
- items = map(lambda arg, dflt: arg + dflt, real_args, defaults)
- if fob.func_code.co_flags & 0x4:
- items.append("...")
- if fob.func_code.co_flags & 0x8:
- items.append("***")
- arg_text = ", ".join(items)
- arg_text = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", arg_text)
- # See if we can use the docstring
+ elif type(ob) == types.MethodType:
+ # bit of a hack for methods - turn it into a function
+ # and drop the "self" param for bound methods
+ fob = ob.im_func
+ if ob.im_self:
+ arg_offset = 1
+ elif type(ob_call) == types.MethodType:
+ # a callable class instance
+ fob = ob_call.im_func
+ arg_offset = 1
+ else:
+ fob = ob
+ # Try to build one for Python defined functions
+ if type(fob) in [types.FunctionType, types.LambdaType]:
+ argcount = fob.func_code.co_argcount
+ real_args = fob.func_code.co_varnames[arg_offset:argcount]
+ defaults = fob.func_defaults or []
+ defaults = list(map(lambda name: "=%s" % repr(name), defaults))
+ defaults = [""] * (len(real_args) - len(defaults)) + defaults
+ items = map(lambda arg, dflt: arg + dflt, real_args, defaults)
+ if fob.func_code.co_flags & 0x4:
+ items.append("*args")
+ if fob.func_code.co_flags & 0x8:
+ items.append("**kwds")
+ argspec = ", ".join(items)
+ argspec = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", argspec)
+
+ lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT)
+ if len(argspec) > _MAX_COLS else [argspec] if argspec else [])
+
+ if isinstance(ob_call, types.MethodType):
+ doc = ob_call.__doc__
+ else:
doc = getattr(ob, "__doc__", "")
- if doc:
- doc = doc.lstrip()
- pos = doc.find("\n")
- if pos < 0 or pos > 70:
- pos = 70
- if arg_text:
- arg_text += "\n"
- arg_text += doc[:pos]
- return arg_text
+ if doc:
+ for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]:
+ line = line.strip()
+ if not line:
+ break
+ if len(line) > _MAX_COLS:
+ line = line[: _MAX_COLS - 3] + '...'
+ lines.append(line)
+ argspec = '\n'.join(lines)
+ return argspec
-#################################################
-#
-# Test code
-#
-if __name__=='__main__':
-
- def t1(): "()"
- def t2(a, b=None): "(a, b=None)"
- def t3(a, *args): "(a, ...)"
- def t4(*args): "(...)"
- def t5(a, *args): "(a, ...)"
- def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)"
- def t7((a, b), c, (d, e)): "(<tuple>, c, <tuple>)"
-
- class TC(object):
- "(ai=None, ...)"
- def __init__(self, ai=None, *b): "(ai=None, ...)"
- def t1(self): "()"
- def t2(self, ai, b=None): "(ai, b=None)"
- def t3(self, ai, *args): "(ai, ...)"
- def t4(self, *args): "(...)"
- def t5(self, ai, *args): "(ai, ...)"
- def t6(self, ai, b=None, *args, **kw): "(ai, b=None, ..., ***)"
- def t7(self, (ai, b), c, (d, e)): "(<tuple>, c, <tuple>)"
-
- def test(tests):
- ct = CallTips()
- failed=[]
- for t in tests:
- expected = t.__doc__ + "\n" + t.__doc__
- name = t.__name__
- # exercise fetch_tip(), not just get_arg_text()
- try:
- qualified_name = "%s.%s" % (t.im_class.__name__, name)
- except AttributeError:
- qualified_name = name
- arg_text = ct.fetch_tip(qualified_name)
- if arg_text != expected:
- failed.append(t)
- fmt = "%s - expected %s, but got %s"
- print fmt % (t.__name__, expected, get_arg_text(t))
- print "%d of %d tests failed" % (len(failed), len(tests))
-
- tc = TC()
- tests = (t1, t2, t3, t4, t5, t6, t7,
- TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6, tc.t7)
-
- # test(tests)
+if __name__ == '__main__':
from unittest import main
- main('idlelib.idle_test.test_calltips', verbosity=2, exit=False)
+ main('idlelib.idle_test.test_calltips', verbosity=2)
diff -r 3a1db0d2747e Lib/idlelib/Debugger.py
--- a/Lib/idlelib/Debugger.py
+++ b/Lib/idlelib/Debugger.py
@@ -253,8 +253,8 @@
if self.vsource.get():
self.sync_source_line()
- def show_frame(self, (frame, lineno)):
- self.frame = frame
+ def show_frame(self, stackitem):
+ self.frame = stackitem[0] # lineno is stackitem[1]
self.show_variables()
localsviewer = None
diff -r 3a1db0d2747e Lib/idlelib/EditorWindow.py
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -1,5 +1,6 @@
import sys
import os
+from platform import python_version
import re
import imp
from Tkinter import *
@@ -965,11 +966,14 @@
self.undo.reset_undo()
def short_title(self):
+ pyversion = "Python " + python_version() + ": "
filename = self.io.filename
if filename:
filename = os.path.basename(filename)
+ else:
+ filename = "Untitled"
# return unicode string to display non-ASCII chars correctly
- return self._filename_to_unicode(filename)
+ return pyversion + self._filename_to_unicode(filename)
def long_title(self):
# return unicode string to display non-ASCII chars correctly
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle.ico
Binary file Lib/idlelib/Icons/idle.ico has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle_16.gif
Binary file Lib/idlelib/Icons/idle_16.gif has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle_16.png
Binary file Lib/idlelib/Icons/idle_16.png has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle_32.gif
Binary file Lib/idlelib/Icons/idle_32.gif has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle_32.png
Binary file Lib/idlelib/Icons/idle_32.png has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle_48.gif
Binary file Lib/idlelib/Icons/idle_48.gif has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/idle_48.png
Binary file Lib/idlelib/Icons/idle_48.png has changed
diff -r 3a1db0d2747e Lib/idlelib/Icons/python.gif
Binary file Lib/idlelib/Icons/python.gif has changed
diff -r 3a1db0d2747e Lib/idlelib/PyShell.py
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -15,7 +15,7 @@
import linecache
from code import InteractiveInterpreter
-from platform import python_version
+from platform import python_version, system
try:
from Tkinter import *
@@ -1338,8 +1338,16 @@
def write(self, s):
if self.closed:
raise ValueError("write to closed file")
- if not isinstance(s, (basestring, bytearray)):
- raise TypeError('must be string, not ' + type(s).__name__)
+ if type(s) not in (unicode, str, bytearray):
+ # See issue #19481
+ if isinstance(s, unicode):
+ s = unicode.__getslice__(s, None, None)
+ elif isinstance(s, str):
+ s = str.__str__(s)
+ elif isinstance(s, bytearray):
+ s = bytearray.__str__(s)
+ else:
+ raise TypeError('must be string, not ' + type(s).__name__)
return self.shell.write(s, self.tags)
@@ -1385,6 +1393,9 @@
line = self._line_buffer or self.shell.readline()
if size < 0:
size = len(line)
+ eol = line.find('\n', 0, size)
+ if eol >= 0:
+ size = eol + 1
self._line_buffer = line[size:]
return line[:size]
@@ -1525,6 +1536,18 @@
# start editor and/or shell windows:
root = Tk(className="Idle")
+ # set application icon
+ icondir = os.path.join(os.path.dirname(__file__), 'Icons')
+ if system() == 'Windows':
+ iconfile = os.path.join(icondir, 'idle.ico')
+ root.wm_iconbitmap(default=iconfile)
+ elif TkVersion >= 8.5:
+ ext = '.png' if TkVersion >= 8.6 else '.gif'
+ iconfiles = [os.path.join(icondir, 'idle_%d%s' % (size, ext))
+ for size in (16, 32, 48)]
+ icons = [PhotoImage(file=iconfile) for iconfile in iconfiles]
+ root.tk.call('wm', 'iconphoto', str(root), "-default", *icons)
+
fixwordbreaks(root)
root.withdraw()
flist = PyShellFileList(root)
@@ -1538,20 +1561,22 @@
args.remove(filename)
if not args:
flist.new()
+
if enable_shell:
shell = flist.open_shell()
if not shell:
return # couldn't open shell
-
if macosxSupport.runningAsOSXApp() and flist.dict:
# On OSX: when the user has double-clicked on a file that causes
# IDLE to be launched the shell window will open just in front of
# the file she wants to see. Lower the interpreter window when
# there are open files.
shell.top.lower()
+ else:
+ shell = flist.pyshell
- shell = flist.pyshell
- # handle remaining options:
+ # Handle remaining options. If any of these are set, enable_shell
+ # was set also, so shell must be true to reach here.
if debug:
shell.open_debugger()
if startup:
@@ -1559,7 +1584,7 @@
os.environ.get("PYTHONSTARTUP")
if filename and os.path.isfile(filename):
shell.interp.execfile(filename)
- if shell and cmd or script:
+ if cmd or script:
shell.interp.runcommand("""if 1:
import sys as _sys
_sys.argv = %r
@@ -1570,13 +1595,14 @@
elif script:
shell.interp.prepend_syspath(script)
shell.interp.execfile(script)
-
- # Check for problematic OS X Tk versions and print a warning message
- # in the IDLE shell window; this is less intrusive than always opening
- # a separate window.
- tkversionwarning = macosxSupport.tkVersionWarning(root)
- if tkversionwarning:
- shell.interp.runcommand(''.join(("print('", tkversionwarning, "')")))
+ elif shell:
+ # If there is a shell window and no cmd or script in progress,
+ # check for problematic OS X Tk versions and print a warning
+ # message in the IDLE shell window; this is less intrusive
+ # than always opening a separate window.
+ tkversionwarning = macosxSupport.tkVersionWarning(root)
+ if tkversionwarning:
+ shell.interp.runcommand("print('%s')" % tkversionwarning)
while flist.inversedict: # keep IDLE running while files are open.
root.mainloop()
diff -r 3a1db0d2747e Lib/idlelib/SearchEngine.py
--- a/Lib/idlelib/SearchEngine.py
+++ b/Lib/idlelib/SearchEngine.py
@@ -83,11 +83,9 @@
try:
prog = re.compile(pat, flags)
except re.error as what:
- try:
- msg, col = what
- except:
- msg = str(what)
- col = -1
+ args = what.args
+ msg = args[0]
+ col = arg[1] if len(args) >= 2 else -1
self.report_error(pat, msg, col)
return None
return prog
@@ -231,6 +229,6 @@
return line, col
if __name__ == "__main__":
- from test import support; support.use_resources = ['gui']
+ from test import test_support; test_support.use_resources = ['gui']
import unittest
unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False)
diff -r 3a1db0d2747e Lib/idlelib/configDialog.py
--- a/Lib/idlelib/configDialog.py
+++ b/Lib/idlelib/configDialog.py
@@ -78,9 +78,10 @@
else:
paddingArgs={'padx':6, 'pady':3}
- self.buttonHelp = Button(frameActionButtons,text='Help',
- command=self.Help,takefocus=FALSE,
- **paddingArgs)
+# Comment out button creation and packing until implement self.Help
+## self.buttonHelp = Button(frameActionButtons,text='Help',
+## command=self.Help,takefocus=FALSE,
+## **paddingArgs)
self.buttonOk = Button(frameActionButtons,text='Ok',
command=self.Ok,takefocus=FALSE,
**paddingArgs)
@@ -94,7 +95,7 @@
self.CreatePageHighlight()
self.CreatePageKeys()
self.CreatePageGeneral()
- self.buttonHelp.pack(side=RIGHT,padx=5)
+## self.buttonHelp.pack(side=RIGHT,padx=5)
self.buttonOk.pack(side=LEFT,padx=5)
self.buttonApply.pack(side=LEFT,padx=5)
self.buttonCancel.pack(side=LEFT,padx=5)
diff -r 3a1db0d2747e Lib/idlelib/idle_test/README.txt
--- a/Lib/idlelib/idle_test/README.txt
+++ b/Lib/idlelib/idle_test/README.txt
@@ -41,9 +41,10 @@
screen, gui tests must be 'guarded' by "requires('gui')" in a setUp
function or method. This will typically be setUpClass.
-All gui objects must be destroyed by the end of the test, perhaps in a tearDown
-function. Creating the Tk root directly in a setUp allows a reference to be saved
-so it can be properly destroyed in the corresponding tearDown.
+To avoid interfering with other gui tests, all gui objects must be destroyed
+and deleted by the end of the test. If a widget, such as a Tk root, is created
+in a setUpX function, destroy it in the corresponding tearDownX. For module
+and class attributes, also delete the widget.
---
@classmethod
def setUpClass(cls):
@@ -53,6 +54,7 @@
@classmethod
def tearDownClass(cls):
cls.root.destroy()
+ del cls.root
---
Support.requires('gui') returns true if it is either called in a main module
@@ -105,4 +107,4 @@
To run an individual Testcase or test method, extend the dotted name given to
unittest on the command line. (But gui tests will not this way.)
-python -m unittest -v idlelib.idle_test.text_xyz.Test_case.test_meth
+python -m unittest -v idlelib.idle_test.test_xyz.Test_case.test_meth
diff -r 3a1db0d2747e Lib/idlelib/idle_test/test_calltips.py
--- a/Lib/idlelib/idle_test/test_calltips.py
+++ b/Lib/idlelib/idle_test/test_calltips.py
@@ -1,6 +1,157 @@
import unittest
import idlelib.CallTips as ct
-CTi = ct.CallTips()
+CTi = ct.CallTips() # needed for get_entity test in 2.7
+import textwrap
+import types
+import warnings
+
+default_tip = ''
+
+# Test Class TC is used in multiple get_argspec test methods
+class TC(object):
+ 'doc'
+ tip = "(ai=None, *args)"
+ def __init__(self, ai=None, *b): 'doc'
+ __init__.tip = "(self, ai=None, *args)"
+ def t1(self): 'doc'
+ t1.tip = "(self)"
+ def t2(self, ai, b=None): 'doc'
+ t2.tip = "(self, ai, b=None)"
+ def t3(self, ai, *args): 'doc'
+ t3.tip = "(self, ai, *args)"
+ def t4(self, *args): 'doc'
+ t4.tip = "(self, *args)"
+ def t5(self, ai, b=None, *args, **kw): 'doc'
+ t5.tip = "(self, ai, b=None, *args, **kwds)"
+ def t6(no, self): 'doc'
+ t6.tip = "(no, self)"
+ def __call__(self, ci): 'doc'
+ __call__.tip = "(self, ci)"
+ # attaching .tip to wrapped methods does not work
+ @classmethod
+ def cm(cls, a): 'doc'
+ @staticmethod
+ def sm(b): 'doc'
+
+tc = TC()
+
+signature = ct.get_arg_text # 2.7 and 3.x use different functions
+class Get_signatureTest(unittest.TestCase):
+ # The signature function must return a string, even if blank.
+ # Test a variety of objects to be sure that none cause it to raise
+ # (quite aside from getting as correct an answer as possible).
+ # The tests of builtins may break if the docstrings change,
+ # but a red buildbot is better than a user crash (as has happened).
+ # For a simple mismatch, change the expected output to the actual.
+
+ def test_builtins(self):
+ # 2.7 puts '()\n' where 3.x does not, other minor differences
+
+ # Python class that inherits builtin methods
+ class List(list): "List() doc"
+ # Simulate builtin with no docstring for default argspec test
+ class SB: __call__ = None
+
+ def gtest(obj, out):
+ self.assertEqual(signature(obj), out)
+
+ gtest(List, '()\n' + List.__doc__)
+ gtest(list.__new__,
+ 'T.__new__(S, ...) -> a new object with type S, a subtype of T')
+ gtest(list.__init__,
+ 'x.__init__(...) initializes x; see help(type(x)) for signature')
+ append_doc = "L.append(object) -- append object to end"
+ gtest(list.append, append_doc)
+ gtest([].append, append_doc)
+ gtest(List.append, append_doc)
+
+ gtest(types.MethodType, '()\ninstancemethod(function, instance, class)')
+ gtest(SB(), default_tip)
+
+ def test_signature_wrap(self):
+ # This is also a test of an old-style class
+ self.assertEqual(signature(textwrap.TextWrapper), '''\
+(width=70, initial_indent='', subsequent_indent='', expand_tabs=True,
+ replace_whitespace=True, fix_sentence_endings=False, break_long_words=True,
+ drop_whitespace=True, break_on_hyphens=True)''')
+
+ def test_docline_truncation(self):
+ def f(): pass
+ f.__doc__ = 'a'*300
+ self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...')
+
+ def test_multiline_docstring(self):
+ # Test fewer lines than max.
+ self.assertEqual(signature(list),
+ "()\nlist() -> new empty list\n"
+ "list(iterable) -> new list initialized from iterable's items")
+
+ # Test max lines and line (currently) too long.
+ def f():
+ pass
+ s = 'a\nb\nc\nd\n'
+ f.__doc__ = s + 300 * 'e' + 'f'
+ self.assertEqual(signature(f),
+ '()\n' + s + (ct._MAX_COLS - 3) * 'e' + '...')
+
+ def test_functions(self):
+ def t1(): 'doc'
+ t1.tip = "()"
+ def t2(a, b=None): 'doc'
+ t2.tip = "(a, b=None)"
+ def t3(a, *args): 'doc'
+ t3.tip = "(a, *args)"
+ def t4(*args): 'doc'
+ t4.tip = "(*args)"
+ def t5(a, b=None, *args, **kwds): 'doc'
+ t5.tip = "(a, b=None, *args, **kwds)"
+
+ for func in (t1, t2, t3, t4, t5, TC):
+ self.assertEqual(signature(func), func.tip + '\ndoc')
+
+ def test_methods(self):
+ for meth in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.__call__):
+ self.assertEqual(signature(meth), meth.tip + "\ndoc")
+ self.assertEqual(signature(TC.cm), "(a)\ndoc")
+ self.assertEqual(signature(TC.sm), "(b)\ndoc")
+
+ def test_bound_methods(self):
+ # test that first parameter is correctly removed from argspec
+ for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"),
+ (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),):
+ self.assertEqual(signature(meth), mtip + "\ndoc")
+
+ def test_starred_parameter(self):
+ # test that starred first parameter is *not* removed from argspec
+ class C:
+ def m1(*args): pass
+ def m2(**kwds): pass
+ c = C()
+ for meth, mtip in ((C.m1, '(*args)'), (c.m1, "(*args)"),
+ (C.m2, "(**kwds)"), (c.m2, "(**kwds)"),):
+ self.assertEqual(signature(meth), mtip)
+
+ def test_no_docstring(self):
+ def nd(s): pass
+ TC.nd = nd
+ self.assertEqual(signature(nd), "(s)")
+ self.assertEqual(signature(TC.nd), "(s)")
+ self.assertEqual(signature(tc.nd), "()")
+
+ def test_attribute_exception(self):
+ class NoCall(object):
+ def __getattr__(self, name):
+ raise BaseException
+ class Call(NoCall):
+ def __call__(self, ci):
+ pass
+ for meth, mtip in ((NoCall, '()'), (Call, '()'),
+ (NoCall(), ''), (Call(), '(ci)')):
+ self.assertEqual(signature(meth), mtip)
+
+ def test_non_callables(self):
+ for obj in (0, 0.0, '0', b'0', [], {}):
+ self.assertEqual(signature(obj), '')
class Get_entityTest(unittest.TestCase):
# In 3.x, get_entity changed from 'instance method' to module function
@@ -12,9 +163,12 @@
class Py2Test(unittest.TestCase):
def test_paramtuple_float(self):
- # 18539: (a,b) becomes '.0' in code object; change that but not float
- def f((a,b), c=0.0): pass
- self.assertEqual(ct.get_arg_text(f), '(<tuple>, c=0.0)')
+ # 18539: (a,b) becomes '.0' in code object; change that but not 0.0
+ with warnings.catch_warnings():
+ # Suppess message of py3 deprecation of parameter unpacking
+ warnings.simplefilter("ignore")
+ exec "def f((a,b), c=0.0): pass"
+ self.assertEqual(signature(f), '(<tuple>, c=0.0)')
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
diff -r 3a1db0d2747e Lib/idlelib/idle_test/test_formatparagraph.py
--- a/Lib/idlelib/idle_test/test_formatparagraph.py
+++ b/Lib/idlelib/idle_test/test_formatparagraph.py
@@ -277,6 +277,9 @@
@classmethod
def tearDownClass(cls):
cls.root.destroy()
+ del cls.root
+ del cls.text
+ del cls.formatter
def test_short_line(self):
self.text.insert('1.0', "Short line\n")
diff -r 3a1db0d2747e Lib/idlelib/idle_test/test_idlehistory.py
--- a/Lib/idlelib/idle_test/test_idlehistory.py
+++ b/Lib/idlelib/idle_test/test_idlehistory.py
@@ -80,6 +80,7 @@
@classmethod
def tearDownClass(cls):
cls.root.destroy()
+ del cls.root
def fetch_test(self, reverse, line, prefix, index, bell=False):
# Perform one fetch as invoked by Alt-N or Alt-P
diff -r 3a1db0d2747e Lib/idlelib/idle_test/test_searchengine.py
--- a/Lib/idlelib/idle_test/test_searchengine.py
+++ b/Lib/idlelib/idle_test/test_searchengine.py
@@ -64,6 +64,7 @@
## @classmethod
## def tearDownClass(cls):
## cls.root.destroy()
+## del cls.root
def test_get_selection(self):
# text = Text(master=self.root)
@@ -219,6 +220,7 @@
## @classmethod
## def tearDownClass(cls):
## cls.root.destroy()
+## del cls.root
def test_search(self):
Equal = self.assertEqual
@@ -261,6 +263,7 @@
## @classmethod
## def tearDownClass(cls):
## cls.root.destroy()
+## del cls.root
@classmethod
def setUpClass(cls):
diff -r 3a1db0d2747e Lib/idlelib/idle_test/test_text.py
--- a/Lib/idlelib/idle_test/test_text.py
+++ b/Lib/idlelib/idle_test/test_text.py
@@ -221,6 +221,7 @@
@classmethod
def tearDownClass(cls):
cls.root.destroy()
+ del cls.root
if __name__ == '__main__':
diff -r 3a1db0d2747e Lib/imaplib.py
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -35,6 +35,15 @@
IMAP4_SSL_PORT = 993
AllowedVersions = ('IMAP4REV1', 'IMAP4') # Most recent first
+# Maximal line length when calling readline(). This is to prevent
+# reading arbitrary length lines. RFC 3501 and 2060 (IMAP 4rev1)
+# don't specify a line length. RFC 2683 however suggests limiting client
+# command lines to 1000 octets and server command lines to 8000 octets.
+# We have selected 10000 for some extra margin and since that is supposedly
+# also what UW and Panda IMAP does.
+_MAXLINE = 10000
+
+
# Commands
Commands = {
@@ -237,7 +246,10 @@
def readline(self):
"""Read line from remote."""
- return self.file.readline()
+ line = self.file.readline(_MAXLINE + 1)
+ if len(line) > _MAXLINE:
+ raise self.error("got more than %d bytes" % _MAXLINE)
+ return line
def send(self, data):
@@ -990,6 +1002,11 @@
del self.tagged_commands[tag]
return result
+ # If we've seen a BYE at this point, the socket will be
+ # closed, so report the BYE now.
+
+ self._check_bye()
+
# Some have reported "unexpected response" exceptions.
# Note that ignoring them here causes loops.
# Instead, send me details of the unexpected response and
diff -r 3a1db0d2747e Lib/imghdr.py
--- a/Lib/imghdr.py
+++ b/Lib/imghdr.py
@@ -7,18 +7,16 @@
#-------------------------#
def what(file, h=None):
- if h is None:
- if isinstance(file, basestring):
- f = open(file, 'rb')
- h = f.read(32)
- else:
- location = file.tell()
- h = file.read(32)
- file.seek(location)
- f = None
- else:
- f = None
+ f = None
try:
+ if h is None:
+ if isinstance(file, basestring):
+ f = open(file, 'rb')
+ h = f.read(32)
+ else:
+ location = file.tell()
+ h = file.read(32)
+ file.seek(location)
for tf in tests:
res = tf(h, f)
if res:
diff -r 3a1db0d2747e Lib/json/decoder.py
--- a/Lib/json/decoder.py
+++ b/Lib/json/decoder.py
@@ -62,6 +62,16 @@
DEFAULT_ENCODING = "utf-8"
+def _decode_uXXXX(s, pos):
+ esc = s[pos + 1:pos + 5]
+ if len(esc) == 4 and esc[1] not in 'xX':
+ try:
+ return int(esc, 16)
+ except ValueError:
+ pass
+ msg = "Invalid \\uXXXX escape"
+ raise ValueError(errmsg(msg, s, pos))
+
def py_scanstring(s, end, encoding=None, strict=True,
_b=BACKSLASH, _m=STRINGCHUNK.match):
"""Scan the string s for a JSON string. End is the index of the
@@ -116,25 +126,16 @@
end += 1
else:
# Unicode escape sequence
- esc = s[end + 1:end + 5]
- next_end = end + 5
- if len(esc) != 4:
- msg = "Invalid \\uXXXX escape"
- raise ValueError(errmsg(msg, s, end))
- uni = int(esc, 16)
+ uni = _decode_uXXXX(s, end)
+ end += 5
# Check for surrogate pair on UCS-4 systems
- if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535:
- msg = "Invalid \\uXXXX\\uXXXX surrogate pair"
- if not s[end + 5:end + 7] == '\\u':
- raise ValueError(errmsg(msg, s, end))
- esc2 = s[end + 7:end + 11]
- if len(esc2) != 4:
- raise ValueError(errmsg(msg, s, end))
- uni2 = int(esc2, 16)
- uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
- next_end += 6
+ if sys.maxunicode > 65535 and \
+ 0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u':
+ uni2 = _decode_uXXXX(s, end + 1)
+ if 0xdc00 <= uni2 <= 0xdfff:
+ uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
+ end += 6
char = unichr(uni)
- end = next_end
# Append the unescaped character
_append(char)
return u''.join(chunks), end
diff -r 3a1db0d2747e Lib/json/tests/test_scanstring.py
--- a/Lib/json/tests/test_scanstring.py
+++ b/Lib/json/tests/test_scanstring.py
@@ -5,10 +5,6 @@
class TestScanstring(object):
def test_scanstring(self):
scanstring = self.json.decoder.scanstring
- self.assertEqual(
- scanstring('"z\\ud834\\udd20x"', 1, None, True),
- (u'z\U0001d120x', 16))
-
if sys.maxunicode == 65535:
self.assertEqual(
scanstring(u'"z\U0001d120x"', 1, None, True),
@@ -94,6 +90,58 @@
scanstring('["Bad value", truth]', 2, None, True),
(u'Bad value', 12))
+ def test_surrogates(self):
+ scanstring = self.json.decoder.scanstring
+ def assertScan(given, expect):
+ self.assertEqual(scanstring(given, 1, None, True),
+ (expect, len(given)))
+ if not isinstance(given, unicode):
+ given = unicode(given)
+ self.assertEqual(scanstring(given, 1, None, True),
+ (expect, len(given)))
+
+ surrogates = unichr(0xd834) + unichr(0xdd20)
+ assertScan('"z\\ud834\\u0079x"', u'z\ud834yx')
+ assertScan('"z\\ud834\\udd20x"', u'z\U0001d120x')
+ assertScan('"z\\ud834\\ud834\\udd20x"', u'z\ud834\U0001d120x')
+ assertScan('"z\\ud834x"', u'z\ud834x')
+ assertScan(u'"z\\ud834\udd20x12345"', u'z%sx12345' % surrogates)
+ assertScan('"z\\udd20x"', u'z\udd20x')
+ assertScan(u'"z\ud834\udd20x"', u'z\ud834\udd20x')
+ assertScan(u'"z\ud834\\udd20x"', u'z%sx' % surrogates)
+ assertScan(u'"z\ud834x"', u'z\ud834x')
+
+ def test_bad_escapes(self):
+ scanstring = self.json.decoder.scanstring
+ bad_escapes = [
+ '"\\"',
+ '"\\x"',
+ '"\\u"',
+ '"\\u0"',
+ '"\\u01"',
+ '"\\u012"',
+ '"\\uz012"',
+ '"\\u0z12"',
+ '"\\u01z2"',
+ '"\\u012z"',
+ '"\\u0x12"',
+ '"\\u0X12"',
+ '"\\ud834\\"',
+ '"\\ud834\\u"',
+ '"\\ud834\\ud"',
+ '"\\ud834\\udd"',
+ '"\\ud834\\udd2"',
+ '"\\ud834\\uzdd2"',
+ '"\\ud834\\udzd2"',
+ '"\\ud834\\uddz2"',
+ '"\\ud834\\udd2z"',
+ '"\\ud834\\u0x20"',
+ '"\\ud834\\u0X20"',
+ ]
+ for s in bad_escapes:
+ with self.assertRaises(ValueError):
+ scanstring(s, 1, None, True)
+
def test_issue3623(self):
self.assertRaises(ValueError, self.json.decoder.scanstring, b"xxx", 1,
"xxx")
diff -r 3a1db0d2747e Lib/lib-tk/Tix.py
--- a/Lib/lib-tk/Tix.py
+++ b/Lib/lib-tk/Tix.py
@@ -122,13 +122,9 @@
elif cnf:
cnf = _cnfmerge(cnf)
if cnf is None:
- cnf = {}
- for x in self.tk.split(self.tk.call('tix', 'configure')):
- cnf[x[0][1:]] = (x[0][1:],) + x[1:]
- return cnf
+ return self._getconfigure('tix', 'configure')
if isinstance(cnf, StringType):
- x = self.tk.split(self.tk.call('tix', 'configure', '-'+cnf))
- return (x[0][1:],) + x[1:]
+ return self._getconfigure1('tix', 'configure', '-'+cnf)
return self.tk.call(('tix', 'configure') + self._options(cnf))
def tix_filedialog(self, dlgclass=None):
@@ -380,7 +376,7 @@
"""Return the name of all subwidgets."""
try:
x = self.tk.call(self._w, 'subwidgets', '-all')
- return self.tk.split(x)
+ return self.tk.splitlist(x)
except TclError:
return None
@@ -473,13 +469,6 @@
self.tk.call('destroy', self._w)
-# Useful func. to split Tcl lists and return as a dict. From Tkinter.py
-def _lst2dict(lst):
- dict = {}
- for x in lst:
- dict[x[0][1:]] = (x[0][1:],) + x[1:]
- return dict
-
# Useful class to create a display style - later shared by many items.
# Contributed by Steffen Kremser
class DisplayStyle:
@@ -515,10 +504,8 @@
self.tk.call(self.stylename, 'configure', '-%s'%key, value)
def config(self, cnf={}, **kw):
- return _lst2dict(
- self.tk.split(
- self.tk.call(
- self.stylename, 'configure', *self._options(cnf,kw))))
+ return self._getconfigure(
+ self.stylename, 'configure', *self._options(cnf,kw))
def __getitem__(self,key):
return self.tk.call(self.stylename, 'cget', '-%s'%key)
@@ -928,9 +915,7 @@
def header_configure(self, col, cnf={}, **kw):
if cnf is None:
- return _lst2dict(
- self.tk.split(
- self.tk.call(self._w, 'header', 'configure', col)))
+ return self._getconfigure(self._w, 'header', 'configure', col)
self.tk.call(self._w, 'header', 'configure', col,
*self._options(cnf, kw))
@@ -955,9 +940,8 @@
def indicator_configure(self, entry, cnf={}, **kw):
if cnf is None:
- return _lst2dict(
- self.tk.split(
- self.tk.call(self._w, 'indicator', 'configure', entry)))
+ return self._getconfigure(
+ self._w, 'indicator', 'configure', entry)
self.tk.call(
self._w, 'indicator', 'configure', entry, *self._options(cnf, kw))
@@ -1017,9 +1001,7 @@
def item_configure(self, entry, col, cnf={}, **kw):
if cnf is None:
- return _lst2dict(
- self.tk.split(
- self.tk.call(self._w, 'item', 'configure', entry, col)))
+ return self._getconfigure(self._w, 'item', 'configure', entry, col)
self.tk.call(self._w, 'item', 'configure', entry, col,
*self._options(cnf, kw))
@@ -1038,9 +1020,7 @@
def entryconfigure(self, entry, cnf={}, **kw):
if cnf is None:
- return _lst2dict(
- self.tk.split(
- self.tk.call(self._w, 'entryconfigure', entry)))
+ return self._getconfigure(self._w, 'entryconfigure', entry)
self.tk.call(self._w, 'entryconfigure', entry,
*self._options(cnf, kw))
@@ -1255,9 +1235,7 @@
def paneconfigure(self, entry, cnf={}, **kw):
if cnf is None:
- return _lst2dict(
- self.tk.split(
- self.tk.call(self._w, 'paneconfigure', entry)))
+ return self._getconfigure(self._w, 'paneconfigure', entry)
self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
def panes(self):
diff -r 3a1db0d2747e Lib/lib-tk/Tkinter.py
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -76,9 +76,9 @@
else:
value = '{%s}' % _join(value)
else:
- if isinstance(value, basestring):
- value = unicode(value)
- else:
+ if isinstance(value, str):
+ value = unicode(value, 'utf-8')
+ elif not isinstance(value, unicode):
value = str(value)
if not value:
value = '{}'
@@ -223,11 +223,13 @@
_varnum += 1
if value is not None:
self.set(value)
- elif not self._tk.call("info", "exists", self._name):
+ elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)):
self.set(self._default)
def __del__(self):
"""Unset the variable in Tcl."""
- self._tk.globalunsetvar(self._name)
+ if (self._tk is not None and
+ self._tk.getboolean(self._tk.call("info", "exists", self._name))):
+ self._tk.globalunsetvar(self._name)
def __str__(self):
"""Return the name of the variable in Tcl."""
return self._name
@@ -1234,6 +1236,19 @@
exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
root = self._root()
root.report_callback_exception(exc, val, tb)
+
+ def _getconfigure(self, *args):
+ """Call Tcl configure command and return the result as a dict."""
+ cnf = {}
+ for x in self.tk.splitlist(self.tk.call(*args)):
+ x = self.tk.splitlist(x)
+ cnf[x[0][1:]] = (x[0][1:],) + x[1:]
+ return cnf
+
+ def _getconfigure1(self, *args):
+ x = self.tk.splitlist(self.tk.call(*args))
+ return (x[0][1:],) + x[1:]
+
def _configure(self, cmd, cnf, kw):
"""Internal function."""
if kw:
@@ -1241,15 +1256,9 @@
elif cnf:
cnf = _cnfmerge(cnf)
if cnf is None:
- cnf = {}
- for x in self.tk.split(
- self.tk.call(_flatten((self._w, cmd)))):
- cnf[x[0][1:]] = (x[0][1:],) + x[1:]
- return cnf
+ return self._getconfigure(_flatten((self._w, cmd)))
if type(cnf) is StringType:
- x = self.tk.split(
- self.tk.call(_flatten((self._w, cmd, '-'+cnf))))
- return (x[0][1:],) + x[1:]
+ return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf)))
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
# These used to be defined in Widget:
def configure(self, cnf=None, **kw):
@@ -1271,8 +1280,8 @@
raise TypeError("Tkinter objects don't support 'in' tests.")
def keys(self):
"""Return a list of all resource names of this widget."""
- return map(lambda x: x[0][1:],
- self.tk.split(self.tk.call(self._w, 'configure')))
+ return [x[0][1:] for x in
+ self.tk.splitlist(self.tk.call(self._w, 'configure'))]
def __str__(self):
"""Return the window path name of this widget."""
return self._w
@@ -1327,6 +1336,21 @@
return self._getints(self.tk.call(*args)) or None
bbox = grid_bbox
+
+ def _gridconvvalue(self, value):
+ if isinstance(value, (str, _tkinter.Tcl_Obj)):
+ try:
+ svalue = str(value)
+ if not svalue:
+ return None
+ elif '.' in svalue:
+ return getdouble(svalue)
+ else:
+ return getint(svalue)
+ except ValueError:
+ pass
+ return value
+
def _grid_configure(self, command, index, cnf, kw):
"""Internal function."""
if type(cnf) is StringType and not kw:
@@ -1345,22 +1369,14 @@
for i in range(0, len(words), 2):
key = words[i][1:]
value = words[i+1]
- if not value:
- value = None
- elif '.' in str(value):
- value = getdouble(value)
- else:
- value = getint(value)
- dict[key] = value
+ dict[key] = self._gridconvvalue(value)
return dict
res = self.tk.call(
('grid', command, self._w, index)
+ options)
if len(options) == 1:
- if not res: return None
- # In Tk 7.5, -width can be a float
- if '.' in res: return getdouble(res)
- return getint(res)
+ return self._gridconvvalue(res)
+
def grid_columnconfigure(self, index, cnf={}, **kw):
"""Configure column INDEX of a grid.
@@ -1447,11 +1463,11 @@
def image_names(self):
"""Return a list of all existing image names."""
- return self.tk.call('image', 'names')
+ return self.tk.splitlist(self.tk.call('image', 'names'))
def image_types(self):
"""Return a list of all available image types (e.g. phote bitmap)."""
- return self.tk.call('image', 'types')
+ return self.tk.splitlist(self.tk.call('image', 'types'))
class CallWrapper:
@@ -1565,7 +1581,10 @@
if len(wlist) > 1:
wlist = (wlist,) # Tk needs a list of windows here
args = ('wm', 'colormapwindows', self._w) + wlist
- return map(self._nametowidget, self.tk.call(args))
+ if wlist:
+ self.tk.call(args)
+ else:
+ return map(self._nametowidget, self.tk.splitlist(self.tk.call(args)))
colormapwindows = wm_colormapwindows
def wm_command(self, value=None):
"""Store VALUE in WM_COMMAND property. It is the command
@@ -2908,8 +2927,9 @@
def debug(self, boolean=None):
"""Turn on the internal consistency checks of the B-Tree inside the text
widget according to BOOLEAN."""
- return self.tk.getboolean(self.tk.call(
- self._w, 'debug', boolean))
+ if boolean is None:
+ return self.tk.getboolean(self.tk.call(self._w, 'debug'))
+ self.tk.call(self._w, 'debug', boolean)
def delete(self, index1, index2=None):
"""Delete the characters between INDEX1 and INDEX2 (not included)."""
self.tk.call(self._w, 'delete', index1, index2)
@@ -3364,8 +3384,11 @@
Valid resource names: background, data, file, foreground, maskdata, maskfile."""
Image.__init__(self, 'bitmap', name, cnf, master, **kw)
-def image_names(): return _default_root.tk.call('image', 'names')
-def image_types(): return _default_root.tk.call('image', 'types')
+def image_names():
+ return _default_root.tk.splitlist(_default_root.tk.call('image', 'names'))
+
+def image_types():
+ return _default_root.tk.splitlist(_default_root.tk.call('image', 'types'))
class Spinbox(Widget, XView):
@@ -3411,7 +3434,7 @@
bounding box may refer to a region outside the
visible area of the window.
"""
- return self.tk.call(self._w, 'bbox', index)
+ return self._getints(self.tk.call(self._w, 'bbox', index)) or None
def delete(self, first, last=None):
"""Delete one or more elements of the spinbox.
@@ -3724,23 +3747,17 @@
"""
if cnf is None and not kw:
- cnf = {}
- for x in self.tk.split(
- self.tk.call(self._w,
- 'paneconfigure', tagOrId)):
- cnf[x[0][1:]] = (x[0][1:],) + x[1:]
- return cnf
+ return self._getconfigure(self._w, 'paneconfigure', tagOrId)
if type(cnf) == StringType and not kw:
- x = self.tk.split(self.tk.call(
- self._w, 'paneconfigure', tagOrId, '-'+cnf))
- return (x[0][1:],) + x[1:]
+ return self._getconfigure1(
+ self._w, 'paneconfigure', tagOrId, '-'+cnf)
self.tk.call((self._w, 'paneconfigure', tagOrId) +
self._options(cnf, kw))
paneconfig = paneconfigure
def panes(self):
"""Returns an ordered list of the child panes."""
- return self.tk.call(self._w, 'panes')
+ return self.tk.splitlist(self.tk.call(self._w, 'panes'))
######################################################################
# Extensions:
diff -r 3a1db0d2747e Lib/lib-tk/test/test_tkinter/test_text.py
--- a/Lib/lib-tk/test/test_tkinter/test_text.py
+++ b/Lib/lib-tk/test/test_tkinter/test_text.py
@@ -14,6 +14,17 @@
def tearDown(self):
self.text.destroy()
+ def test_debug(self):
+ text = self.text
+ olddebug = text.debug()
+ try:
+ text.debug(0)
+ self.assertEqual(text.debug(), 0)
+ text.debug(1)
+ self.assertEqual(text.debug(), 1)
+ finally:
+ text.debug(olddebug)
+ self.assertEqual(text.debug(), olddebug)
def test_search(self):
text = self.text
diff -r 3a1db0d2747e Lib/lib-tk/test/test_tkinter/test_variables.py
--- /dev/null
+++ b/Lib/lib-tk/test/test_tkinter/test_variables.py
@@ -0,0 +1,166 @@
+import unittest
+
+from Tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tk, TclError
+
+
+class TestBase(unittest.TestCase):
+
+ def setUp(self):
+ self.root = Tk()
+
+ def tearDown(self):
+ self.root.destroy()
+
+
+class TestVariable(TestBase):
+
+ def info_exists(self, *args):
+ return self.root.getboolean(self.root.call("info", "exists", *args))
+
+ def test_default(self):
+ v = Variable(self.root)
+ self.assertEqual("", v.get())
+ self.assertRegexpMatches(str(v), r"^PY_VAR(\d+)$")
+
+ def test_name_and_value(self):
+ v = Variable(self.root, "sample string", "varname")
+ self.assertEqual("sample string", v.get())
+ self.assertEqual("varname", str(v))
+
+ def test___del__(self):
+ self.assertFalse(self.info_exists("varname"))
+ v = Variable(self.root, "sample string", "varname")
+ self.assertTrue(self.info_exists("varname"))
+ del v
+ self.assertFalse(self.info_exists("varname"))
+
+ def test_dont_unset_not_existing(self):
+ self.assertFalse(self.info_exists("varname"))
+ v1 = Variable(self.root, name="name")
+ v2 = Variable(self.root, name="name")
+ del v1
+ self.assertFalse(self.info_exists("name"))
+ # shouldn't raise exception
+ del v2
+ self.assertFalse(self.info_exists("name"))
+
+ def test___eq__(self):
+ # values doesn't matter, only class and name are checked
+ v1 = Variable(self.root, name="abc")
+ v2 = Variable(self.root, name="abc")
+ self.assertEqual(v1, v2)
+
+ v3 = Variable(self.root, name="abc")
+ v4 = StringVar(self.root, name="abc")
+ self.assertNotEqual(v3, v4)
+
+ def test_invalid_name(self):
+ with self.assertRaises(TypeError):
+ Variable(self.root, name=123)
+
+ def test_null_in_name(self):
+ with self.assertRaises(ValueError):
+ Variable(self.root, name='var\x00name')
+ with self.assertRaises(ValueError):
+ self.root.globalsetvar('var\x00name', "value")
+ with self.assertRaises(ValueError):
+ self.root.setvar('var\x00name', "value")
+
+
+class TestStringVar(TestBase):
+
+ def test_default(self):
+ v = StringVar(self.root)
+ self.assertEqual("", v.get())
+
+ def test_get(self):
+ v = StringVar(self.root, "abc", "name")
+ self.assertEqual("abc", v.get())
+ self.root.globalsetvar("name", "value")
+ self.assertEqual("value", v.get())
+
+ def test_get_null(self):
+ v = StringVar(self.root, "abc\x00def", "name")
+ self.assertEqual("abc\x00def", v.get())
+ self.root.globalsetvar("name", "val\x00ue")
+ self.assertEqual("val\x00ue", v.get())
+
+
+class TestIntVar(TestBase):
+
+ def test_default(self):
+ v = IntVar(self.root)
+ self.assertEqual(0, v.get())
+
+ def test_get(self):
+ v = IntVar(self.root, 123, "name")
+ self.assertEqual(123, v.get())
+ self.root.globalsetvar("name", "345")
+ self.assertEqual(345, v.get())
+
+ def test_invalid_value(self):
+ v = IntVar(self.root, name="name")
+ self.root.globalsetvar("name", "value")
+ with self.assertRaises(ValueError):
+ v.get()
+ self.root.globalsetvar("name", "345.0")
+ with self.assertRaises(ValueError):
+ v.get()
+
+
+class TestDoubleVar(TestBase):
+
+ def test_default(self):
+ v = DoubleVar(self.root)
+ self.assertEqual(0.0, v.get())
+
+ def test_get(self):
+ v = DoubleVar(self.root, 1.23, "name")
+ self.assertAlmostEqual(1.23, v.get())
+ self.root.globalsetvar("name", "3.45")
+ self.assertAlmostEqual(3.45, v.get())
+
+ def test_get_from_int(self):
+ v = DoubleVar(self.root, 1.23, "name")
+ self.assertAlmostEqual(1.23, v.get())
+ self.root.globalsetvar("name", "3.45")
+ self.assertAlmostEqual(3.45, v.get())
+ self.root.globalsetvar("name", "456")
+ self.assertAlmostEqual(456, v.get())
+
+ def test_invalid_value(self):
+ v = DoubleVar(self.root, name="name")
+ self.root.globalsetvar("name", "value")
+ with self.assertRaises(ValueError):
+ v.get()
+
+
+class TestBooleanVar(TestBase):
+
+ def test_default(self):
+ v = BooleanVar(self.root)
+ self.assertEqual(False, v.get())
+
+ def test_get(self):
+ v = BooleanVar(self.root, True, "name")
+ self.assertAlmostEqual(True, v.get())
+ self.root.globalsetvar("name", "0")
+ self.assertAlmostEqual(False, v.get())
+
+ def test_invalid_value_domain(self):
+ v = BooleanVar(self.root, name="name")
+ self.root.globalsetvar("name", "value")
+ with self.assertRaises(TclError):
+ v.get()
+ self.root.globalsetvar("name", "1.0")
+ with self.assertRaises(TclError):
+ v.get()
+
+
+tests_gui = (TestVariable, TestStringVar, TestIntVar,
+ TestDoubleVar, TestBooleanVar)
+
+
+if __name__ == "__main__":
+ from test.support import run_unittest
+ run_unittest(*tests_gui)
diff -r 3a1db0d2747e Lib/lib-tk/test/test_tkinter/test_widgets.py
--- /dev/null
+++ b/Lib/lib-tk/test/test_tkinter/test_widgets.py
@@ -0,0 +1,952 @@
+import unittest
+import Tkinter
+import os
+import sys
+from test.test_support import requires, run_unittest
+
+from test_ttk.support import (tcl_version, requires_tcl, get_tk_patchlevel,
+ widget_eq)
+from widget_tests import (
+ add_standard_options, noconv, noconv_meth, int_round, pixels_round,
+ AbstractWidgetTest, StandardOptionsTests,
+ IntegerSizeTests, PixelSizeTests,
+ setUpModule)
+
+requires('gui')
+
+
+class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
+ _conv_pad_pixels = noconv_meth
+
+ def test_class(self):
+ widget = self.create()
+ self.assertEqual(widget['class'],
+ widget.__class__.__name__.title())
+ self.checkInvalidParam(widget, 'class', 'Foo',
+ errmsg="can't modify -class option after widget is created")
+ widget2 = self.create(class_='Foo')
+ self.assertEqual(widget2['class'], 'Foo')
+
+ def test_colormap(self):
+ widget = self.create()
+ self.assertEqual(widget['colormap'], '')
+ self.checkInvalidParam(widget, 'colormap', 'new',
+ errmsg="can't modify -colormap option after widget is created")
+ widget2 = self.create(colormap='new')
+ self.assertEqual(widget2['colormap'], 'new')
+
+ def test_container(self):
+ widget = self.create()
+ self.assertEqual(widget['container'], 0 if self.wantobjects else '0')
+ self.checkInvalidParam(widget, 'container', 1,
+ errmsg="can't modify -container option after widget is created")
+ widget2 = self.create(container=True)
+ self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')
+
+ def test_visual(self):
+ widget = self.create()
+ self.assertEqual(widget['visual'], '')
+ self.checkInvalidParam(widget, 'visual', 'default',
+ errmsg="can't modify -visual option after widget is created")
+ widget2 = self.create(visual='default')
+ self.assertEqual(widget2['visual'], 'default')
+
+
+@add_standard_options(StandardOptionsTests)
+class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'borderwidth',
+ 'class', 'colormap', 'container', 'cursor', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'menu', 'padx', 'pady', 'relief', 'screen',
+ 'takefocus', 'use', 'visual', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Toplevel(self.root, **kwargs)
+
+ def test_menu(self):
+ widget = self.create()
+ menu = Tkinter.Menu(self.root)
+ self.checkParam(widget, 'menu', menu, eq=widget_eq)
+ self.checkParam(widget, 'menu', '')
+
+ def test_screen(self):
+ widget = self.create()
+ self.assertEqual(widget['screen'], '')
+ try:
+ display = os.environ['DISPLAY']
+ except KeyError:
+ self.skipTest('No $DISPLAY set.')
+ self.checkInvalidParam(widget, 'screen', display,
+ errmsg="can't modify -screen option after widget is created")
+ widget2 = self.create(screen=display)
+ self.assertEqual(widget2['screen'], display)
+
+ def test_use(self):
+ widget = self.create()
+ self.assertEqual(widget['use'], '')
+ parent = self.create(container=True)
+ wid = parent.winfo_id()
+ widget2 = self.create(use=wid)
+ self.assertEqual(int(widget2['use']), wid)
+
+
+@add_standard_options(StandardOptionsTests)
+class FrameTest(AbstractToplevelTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'borderwidth',
+ 'class', 'colormap', 'container', 'cursor', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'relief', 'takefocus', 'visual', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Frame(self.root, **kwargs)
+
+
+@add_standard_options(StandardOptionsTests)
+class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'borderwidth',
+ 'class', 'colormap', 'container', 'cursor',
+ 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'labelanchor', 'labelwidget', 'padx', 'pady', 'relief',
+ 'takefocus', 'text', 'visual', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.LabelFrame(self.root, **kwargs)
+
+ def test_labelanchor(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'labelanchor',
+ 'e', 'en', 'es', 'n', 'ne', 'nw',
+ 's', 'se', 'sw', 'w', 'wn', 'ws')
+ self.checkInvalidParam(widget, 'labelanchor', 'center')
+
+ def test_labelwidget(self):
+ widget = self.create()
+ label = Tkinter.Label(self.root, text='Mupp', name='foo')
+ self.checkParam(widget, 'labelwidget', label, expected='.foo')
+ label.destroy()
+
+
+class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):
+ _conv_pixels = noconv_meth
+
+ def test_highlightthickness(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'highlightthickness',
+ 0, 1.3, 2.6, 6, -2, '10p')
+
+
+@add_standard_options(StandardOptionsTests)
+class LabelTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activeforeground', 'anchor',
+ 'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
+ 'disabledforeground', 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'image', 'justify', 'padx', 'pady', 'relief', 'state',
+ 'takefocus', 'text', 'textvariable',
+ 'underline', 'width', 'wraplength',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Label(self.root, **kwargs)
+
+
+@add_standard_options(StandardOptionsTests)
+class ButtonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activeforeground', 'anchor',
+ 'background', 'bitmap', 'borderwidth',
+ 'command', 'compound', 'cursor', 'default',
+ 'disabledforeground', 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'image', 'justify', 'overrelief', 'padx', 'pady', 'relief',
+ 'repeatdelay', 'repeatinterval',
+ 'state', 'takefocus', 'text', 'textvariable',
+ 'underline', 'width', 'wraplength')
+
+ def _create(self, **kwargs):
+ return Tkinter.Button(self.root, **kwargs)
+
+ def test_default(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')
+
+
+@add_standard_options(StandardOptionsTests)
+class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activeforeground', 'anchor',
+ 'background', 'bitmap', 'borderwidth',
+ 'command', 'compound', 'cursor',
+ 'disabledforeground', 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'image', 'indicatoron', 'justify',
+ 'offrelief', 'offvalue', 'onvalue', 'overrelief',
+ 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
+ 'takefocus', 'text', 'textvariable',
+ 'tristateimage', 'tristatevalue',
+ 'underline', 'variable', 'width', 'wraplength',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Checkbutton(self.root, **kwargs)
+
+
+ def test_offvalue(self):
+ widget = self.create()
+ self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
+
+ def test_onvalue(self):
+ widget = self.create()
+ self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
+
+
+@add_standard_options(StandardOptionsTests)
+class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activeforeground', 'anchor',
+ 'background', 'bitmap', 'borderwidth',
+ 'command', 'compound', 'cursor',
+ 'disabledforeground', 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'image', 'indicatoron', 'justify', 'offrelief', 'overrelief',
+ 'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
+ 'takefocus', 'text', 'textvariable',
+ 'tristateimage', 'tristatevalue',
+ 'underline', 'value', 'variable', 'width', 'wraplength',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Radiobutton(self.root, **kwargs)
+
+ def test_value(self):
+ widget = self.create()
+ self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
+
+
+@add_standard_options(StandardOptionsTests)
+class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activeforeground', 'anchor',
+ 'background', 'bitmap', 'borderwidth',
+ 'compound', 'cursor', 'direction',
+ 'disabledforeground', 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'image', 'indicatoron', 'justify', 'menu',
+ 'padx', 'pady', 'relief', 'state',
+ 'takefocus', 'text', 'textvariable',
+ 'underline', 'width', 'wraplength',
+ )
+ _conv_pixels = staticmethod(pixels_round)
+
+ def _create(self, **kwargs):
+ return Tkinter.Menubutton(self.root, **kwargs)
+
+ def test_direction(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'direction',
+ 'above', 'below', 'flush', 'left', 'right')
+
+ def test_height(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
+
+ test_highlightthickness = StandardOptionsTests.test_highlightthickness.im_func
+
+ @unittest.skipIf(sys.platform == 'darwin',
+ 'crashes with Cocoa Tk (issue19733)')
+ def test_image(self):
+ widget = self.create()
+ image = Tkinter.PhotoImage('image1')
+ self.checkParam(widget, 'image', image, conv=str)
+ errmsg = 'image "spam" doesn\'t exist'
+ with self.assertRaises(Tkinter.TclError) as cm:
+ widget['image'] = 'spam'
+ if errmsg is not None:
+ self.assertEqual(str(cm.exception), errmsg)
+ with self.assertRaises(Tkinter.TclError) as cm:
+ widget.configure({'image': 'spam'})
+ if errmsg is not None:
+ self.assertEqual(str(cm.exception), errmsg)
+
+ def test_menu(self):
+ widget = self.create()
+ menu = Tkinter.Menu(widget, name='menu')
+ self.checkParam(widget, 'menu', menu, eq=widget_eq)
+ menu.destroy()
+
+ def test_padx(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')
+ self.checkParam(widget, 'padx', -2, expected=0)
+
+ def test_pady(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')
+ self.checkParam(widget, 'pady', -2, expected=0)
+
+ def test_width(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
+
+
+class OptionMenuTest(MenubuttonTest, unittest.TestCase):
+
+ def _create(self, default='b', values=('a', 'b', 'c'), **kwargs):
+ return Tkinter.OptionMenu(self.root, None, default, *values, **kwargs)
+
+
+@add_standard_options(IntegerSizeTests, StandardOptionsTests)
+class EntryTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'borderwidth', 'cursor',
+ 'disabledbackground', 'disabledforeground',
+ 'exportselection', 'font', 'foreground',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'insertbackground', 'insertborderwidth',
+ 'insertofftime', 'insertontime', 'insertwidth',
+ 'invalidcommand', 'justify', 'readonlybackground', 'relief',
+ 'selectbackground', 'selectborderwidth', 'selectforeground',
+ 'show', 'state', 'takefocus', 'textvariable',
+ 'validate', 'validatecommand', 'width', 'xscrollcommand',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Entry(self.root, **kwargs)
+
+ def test_disabledbackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'disabledbackground')
+
+ def test_insertborderwidth(self):
+ widget = self.create(insertwidth=100)
+ self.checkPixelsParam(widget, 'insertborderwidth',
+ 0, 1.3, 2.6, 6, -2, '10p')
+ # insertborderwidth is bounded above by a half of insertwidth.
+ self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)
+
+ def test_insertwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
+ self.checkParam(widget, 'insertwidth', 0.1, expected=2)
+ self.checkParam(widget, 'insertwidth', -2, expected=2)
+ if pixels_round(0.9) <= 0:
+ self.checkParam(widget, 'insertwidth', 0.9, expected=2)
+ else:
+ self.checkParam(widget, 'insertwidth', 0.9, expected=1)
+
+ def test_invalidcommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'invalidcommand')
+ self.checkCommandParam(widget, 'invcmd')
+
+ def test_readonlybackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'readonlybackground')
+
+ def test_show(self):
+ widget = self.create()
+ self.checkParam(widget, 'show', '*')
+ self.checkParam(widget, 'show', '')
+ self.checkParam(widget, 'show', ' ')
+
+ def test_state(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'state',
+ 'disabled', 'normal', 'readonly')
+
+ def test_validate(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'validate',
+ 'all', 'key', 'focus', 'focusin', 'focusout', 'none')
+
+ def test_validatecommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'validatecommand')
+ self.checkCommandParam(widget, 'vcmd')
+
+
+@add_standard_options(StandardOptionsTests)
+class SpinboxTest(EntryTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'background', 'borderwidth',
+ 'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief',
+ 'command', 'cursor', 'disabledbackground', 'disabledforeground',
+ 'exportselection', 'font', 'foreground', 'format', 'from',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'increment',
+ 'insertbackground', 'insertborderwidth',
+ 'insertofftime', 'insertontime', 'insertwidth',
+ 'invalidcommand', 'justify', 'relief', 'readonlybackground',
+ 'repeatdelay', 'repeatinterval',
+ 'selectbackground', 'selectborderwidth', 'selectforeground',
+ 'state', 'takefocus', 'textvariable', 'to',
+ 'validate', 'validatecommand', 'values',
+ 'width', 'wrap', 'xscrollcommand',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Spinbox(self.root, **kwargs)
+
+ test_show = None
+
+ def test_buttonbackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'buttonbackground')
+
+ def test_buttoncursor(self):
+ widget = self.create()
+ self.checkCursorParam(widget, 'buttoncursor')
+
+ def test_buttondownrelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'buttondownrelief')
+
+ def test_buttonuprelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'buttonuprelief')
+
+ def test_format(self):
+ widget = self.create()
+ self.checkParam(widget, 'format', '%2f')
+ self.checkParam(widget, 'format', '%2.2f')
+ self.checkParam(widget, 'format', '%.2f')
+ self.checkParam(widget, 'format', '%2.f')
+ self.checkInvalidParam(widget, 'format', '%2e-1f')
+ self.checkInvalidParam(widget, 'format', '2.2')
+ self.checkInvalidParam(widget, 'format', '%2.-2f')
+ self.checkParam(widget, 'format', '%-2.02f')
+ self.checkParam(widget, 'format', '% 2.02f')
+ self.checkParam(widget, 'format', '% -2.200f')
+ self.checkParam(widget, 'format', '%09.200f')
+ self.checkInvalidParam(widget, 'format', '%d')
+
+ def test_from(self):
+ widget = self.create()
+ self.checkParam(widget, 'to', 100.0)
+ self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)
+ self.checkInvalidParam(widget, 'from', 200,
+ errmsg='-to value must be greater than -from value')
+
+ def test_increment(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)
+
+ def test_to(self):
+ widget = self.create()
+ self.checkParam(widget, 'from', -100.0)
+ self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)
+ self.checkInvalidParam(widget, 'to', -200,
+ errmsg='-to value must be greater than -from value')
+
+ def test_values(self):
+ # XXX
+ widget = self.create()
+ self.assertEqual(widget['values'], '')
+ self.checkParam(widget, 'values', 'mon tue wed thur')
+ self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'),
+ expected='mon tue wed thur')
+ self.checkParam(widget, 'values', (42, 3.14, '', 'any string'),
+ expected='42 3.14 {} {any string}')
+ self.checkParam(widget, 'values', '')
+
+ def test_wrap(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'wrap')
+
+ def test_bbox(self):
+ widget = self.create()
+ bbox = widget.bbox(0)
+ self.assertEqual(len(bbox), 4)
+ for item in bbox:
+ self.assertIsInstance(item, int)
+
+ self.assertRaises(Tkinter.TclError, widget.bbox, 'noindex')
+ self.assertRaises(Tkinter.TclError, widget.bbox, None)
+ self.assertRaises(TypeError, widget.bbox)
+ self.assertRaises(TypeError, widget.bbox, 0, 1)
+
+
+@add_standard_options(StandardOptionsTests)
+class TextTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'autoseparators', 'background', 'blockcursor', 'borderwidth',
+ 'cursor', 'endline', 'exportselection',
+ 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'inactiveselectbackground', 'insertbackground', 'insertborderwidth',
+ 'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth',
+ 'maxundo', 'padx', 'pady', 'relief',
+ 'selectbackground', 'selectborderwidth', 'selectforeground',
+ 'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state',
+ 'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap',
+ 'xscrollcommand', 'yscrollcommand',
+ )
+ if tcl_version < (8, 5):
+ wantobjects = False
+
+ def _create(self, **kwargs):
+ return Tkinter.Text(self.root, **kwargs)
+
+ def test_autoseparators(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'autoseparators')
+
+ @requires_tcl(8, 5)
+ def test_blockcursor(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'blockcursor')
+
+ @requires_tcl(8, 5)
+ def test_endline(self):
+ widget = self.create()
+ text = '\n'.join('Line %d' for i in range(100))
+ widget.insert('end', text)
+ self.checkParam(widget, 'endline', 200, expected='')
+ self.checkParam(widget, 'endline', -10, expected='')
+ self.checkInvalidParam(widget, 'endline', 'spam',
+ errmsg='expected integer but got "spam"')
+ self.checkParam(widget, 'endline', 50)
+ self.checkParam(widget, 'startline', 15)
+ self.checkInvalidParam(widget, 'endline', 10,
+ errmsg='-startline must be less than or equal to -endline')
+
+ def test_height(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
+ self.checkParam(widget, 'height', -100, expected=1)
+ self.checkParam(widget, 'height', 0, expected=1)
+
+ def test_maxundo(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)
+
+ @requires_tcl(8, 5)
+ def test_inactiveselectbackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'inactiveselectbackground')
+
+ @requires_tcl(8, 6)
+ def test_insertunfocussed(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'insertunfocussed',
+ 'hollow', 'none', 'solid')
+
+ def test_selectborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'selectborderwidth',
+ 1.3, 2.6, -2, '10p', conv=noconv,
+ keep_orig=tcl_version >= (8, 5))
+
+ def test_spacing1(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
+ self.checkParam(widget, 'spacing1', -5, expected=0)
+
+ def test_spacing2(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
+ self.checkParam(widget, 'spacing2', -1, expected=0)
+
+ def test_spacing3(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
+ self.checkParam(widget, 'spacing3', -10, expected=0)
+
+ @requires_tcl(8, 5)
+ def test_startline(self):
+ widget = self.create()
+ text = '\n'.join('Line %d' for i in range(100))
+ widget.insert('end', text)
+ self.checkParam(widget, 'startline', 200, expected='')
+ self.checkParam(widget, 'startline', -10, expected='')
+ self.checkInvalidParam(widget, 'startline', 'spam',
+ errmsg='expected integer but got "spam"')
+ self.checkParam(widget, 'startline', 10)
+ self.checkParam(widget, 'endline', 50)
+ self.checkInvalidParam(widget, 'startline', 70,
+ errmsg='-startline must be less than or equal to -endline')
+
+ def test_state(self):
+ widget = self.create()
+ if tcl_version < (8, 5):
+ self.checkParams(widget, 'state', 'disabled', 'normal')
+ else:
+ self.checkEnumParam(widget, 'state', 'disabled', 'normal')
+
+ def test_tabs(self):
+ widget = self.create()
+ if get_tk_patchlevel() < (8, 5, 11):
+ self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'),
+ expected=('10.2', '20.7', '1i', '2i'))
+ else:
+ self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'))
+ self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i',
+ expected=('10.2', '20.7', '1i', '2i'))
+ self.checkParam(widget, 'tabs', '2c left 4c 6c center',
+ expected=('2c', 'left', '4c', '6c', 'center'))
+ self.checkInvalidParam(widget, 'tabs', 'spam',
+ errmsg='bad screen distance "spam"',
+ keep_orig=tcl_version >= (8, 5))
+
+ @requires_tcl(8, 5)
+ def test_tabstyle(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')
+
+ def test_undo(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'undo')
+
+ def test_width(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'width', 402)
+ self.checkParam(widget, 'width', -402, expected=1)
+ self.checkParam(widget, 'width', 0, expected=1)
+
+ def test_wrap(self):
+ widget = self.create()
+ if tcl_version < (8, 5):
+ self.checkParams(widget, 'wrap', 'char', 'none', 'word')
+ else:
+ self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word')
+
+ def test_bbox(self):
+ widget = self.create()
+ bbox = widget.bbox('1.1')
+ self.assertEqual(len(bbox), 4)
+ for item in bbox:
+ self.assertIsInstance(item, int)
+
+ self.assertIsNone(widget.bbox('end'))
+ self.assertRaises(Tkinter.TclError, widget.bbox, 'noindex')
+ self.assertRaises(Tkinter.TclError, widget.bbox, None)
+ self.assertRaises(Tkinter.TclError, widget.bbox)
+ self.assertRaises(Tkinter.TclError, widget.bbox, '1.1', 'end')
+
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class CanvasTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'borderwidth',
+ 'closeenough', 'confine', 'cursor', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'insertbackground', 'insertborderwidth',
+ 'insertofftime', 'insertontime', 'insertwidth',
+ 'relief', 'scrollregion',
+ 'selectbackground', 'selectborderwidth', 'selectforeground',
+ 'state', 'takefocus',
+ 'xscrollcommand', 'xscrollincrement',
+ 'yscrollcommand', 'yscrollincrement', 'width',
+ )
+
+ _conv_pixels = staticmethod(int_round)
+ wantobjects = False
+
+ def _create(self, **kwargs):
+ return Tkinter.Canvas(self.root, **kwargs)
+
+ def test_closeenough(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,
+ conv=float)
+
+ def test_confine(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'confine')
+
+ def test_scrollregion(self):
+ widget = self.create()
+ self.checkParam(widget, 'scrollregion', '0 0 200 150')
+ self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),
+ expected='0 0 200 150')
+ self.checkParam(widget, 'scrollregion', '')
+ self.checkInvalidParam(widget, 'scrollregion', 'spam',
+ errmsg='bad scrollRegion "spam"')
+ self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam'))
+ self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))
+ self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))
+
+ def test_state(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'state', 'disabled', 'normal',
+ errmsg='bad state value "{}": must be normal or disabled')
+
+ def test_xscrollincrement(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'xscrollincrement',
+ 40, 0, 41.2, 43.6, -40, '0.5i')
+
+ def test_yscrollincrement(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'yscrollincrement',
+ 10, 0, 11.2, 13.6, -10, '0.1i')
+
+
+@add_standard_options(IntegerSizeTests, StandardOptionsTests)
+class ListboxTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'activestyle', 'background', 'borderwidth', 'cursor',
+ 'disabledforeground', 'exportselection',
+ 'font', 'foreground', 'height',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'listvariable', 'relief',
+ 'selectbackground', 'selectborderwidth', 'selectforeground',
+ 'selectmode', 'setgrid', 'state',
+ 'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',
+ )
+
+ def _create(self, **kwargs):
+ return Tkinter.Listbox(self.root, **kwargs)
+
+ def test_activestyle(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'activestyle',
+ 'dotbox', 'none', 'underline')
+
+ def test_listvariable(self):
+ widget = self.create()
+ var = Tkinter.DoubleVar()
+ self.checkVariableParam(widget, 'listvariable', var)
+
+ def test_selectmode(self):
+ widget = self.create()
+ self.checkParam(widget, 'selectmode', 'single')
+ self.checkParam(widget, 'selectmode', 'browse')
+ self.checkParam(widget, 'selectmode', 'multiple')
+ self.checkParam(widget, 'selectmode', 'extended')
+
+ def test_state(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'state', 'disabled', 'normal')
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class ScaleTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'background', 'bigincrement', 'borderwidth',
+ 'command', 'cursor', 'digits', 'font', 'foreground', 'from',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'label', 'length', 'orient', 'relief',
+ 'repeatdelay', 'repeatinterval',
+ 'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state',
+ 'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width',
+ )
+ default_orient = 'vertical'
+
+ def _create(self, **kwargs):
+ return Tkinter.Scale(self.root, **kwargs)
+
+ def test_bigincrement(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)
+
+ def test_digits(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'digits', 5, 0)
+
+ def test_from(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=round)
+
+ def test_label(self):
+ widget = self.create()
+ self.checkParam(widget, 'label', 'any string')
+ self.checkParam(widget, 'label', '')
+
+ def test_length(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
+
+ def test_resolution(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)
+
+ def test_showvalue(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'showvalue')
+
+ def test_sliderlength(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'sliderlength',
+ 10, 11.2, 15.6, -3, '3m')
+
+ def test_sliderrelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'sliderrelief')
+
+ def test_tickinterval(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,
+ conv=round)
+ self.checkParam(widget, 'tickinterval', -2, expected=2,
+ conv=round)
+
+ def test_to(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,
+ conv=round)
+
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activerelief',
+ 'background', 'borderwidth',
+ 'command', 'cursor', 'elementborderwidth',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'jump', 'orient', 'relief',
+ 'repeatdelay', 'repeatinterval',
+ 'takefocus', 'troughcolor', 'width',
+ )
+ _conv_pixels = staticmethod(int_round)
+ wantobjects = False
+ default_orient = 'vertical'
+
+ def _create(self, **kwargs):
+ return Tkinter.Scrollbar(self.root, **kwargs)
+
+ def test_activerelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'activerelief')
+
+ def test_elementborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
+
+ def test_orient(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',
+ errmsg='bad orientation "{}": must be vertical or horizontal')
+
+
+@add_standard_options(StandardOptionsTests)
+class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'borderwidth', 'cursor',
+ 'handlepad', 'handlesize', 'height',
+ 'opaqueresize', 'orient', 'relief',
+ 'sashcursor', 'sashpad', 'sashrelief', 'sashwidth',
+ 'showhandle', 'width',
+ )
+ default_orient = 'horizontal'
+
+ def _create(self, **kwargs):
+ return Tkinter.PanedWindow(self.root, **kwargs)
+
+ def test_handlepad(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')
+
+ def test_handlesize(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
+ conv=noconv)
+
+ def test_height(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
+ conv=noconv)
+
+ def test_opaqueresize(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'opaqueresize')
+
+ def test_sashcursor(self):
+ widget = self.create()
+ self.checkCursorParam(widget, 'sashcursor')
+
+ def test_sashpad(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')
+
+ def test_sashrelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'sashrelief')
+
+ def test_sashwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
+ conv=noconv)
+
+ def test_showhandle(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'showhandle')
+
+ def test_width(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
+ conv=noconv)
+
+
+@add_standard_options(StandardOptionsTests)
+class MenuTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'activebackground', 'activeborderwidth', 'activeforeground',
+ 'background', 'borderwidth', 'cursor',
+ 'disabledforeground', 'font', 'foreground',
+ 'postcommand', 'relief', 'selectcolor', 'takefocus',
+ 'tearoff', 'tearoffcommand', 'title', 'type',
+ )
+ _conv_pixels = noconv_meth
+
+ def _create(self, **kwargs):
+ return Tkinter.Menu(self.root, **kwargs)
+
+ def test_postcommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'postcommand')
+
+ def test_tearoff(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'tearoff')
+
+ def test_tearoffcommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'tearoffcommand')
+
+ def test_title(self):
+ widget = self.create()
+ self.checkParam(widget, 'title', 'any string')
+
+ def test_type(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'type',
+ 'normal', 'tearoff', 'menubar')
+
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class MessageTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'anchor', 'aspect', 'background', 'borderwidth',
+ 'cursor', 'font', 'foreground',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'justify', 'padx', 'pady', 'relief',
+ 'takefocus', 'text', 'textvariable', 'width',
+ )
+ _conv_pad_pixels = noconv_meth
+
+ def _create(self, **kwargs):
+ return Tkinter.Message(self.root, **kwargs)
+
+ def test_aspect(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'aspect', 250, 0, -300)
+
+
+tests_gui = [
+ ButtonTest, CanvasTest, CheckbuttonTest, EntryTest,
+ FrameTest, LabelFrameTest,LabelTest, ListboxTest,
+ MenubuttonTest, MenuTest, MessageTest, OptionMenuTest,
+ PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest,
+ SpinboxTest, TextTest, ToplevelTest,
+]
+
+if __name__ == '__main__':
+ run_unittest(*tests_gui)
diff -r 3a1db0d2747e Lib/lib-tk/test/test_ttk/support.py
--- a/Lib/lib-tk/test/test_ttk/support.py
+++ b/Lib/lib-tk/test/test_ttk/support.py
@@ -1,3 +1,4 @@
+import unittest
import Tkinter
def get_tk_root():
@@ -31,3 +32,57 @@
widget.event_generate('<Motion>', x=x, y=y)
widget.event_generate('<ButtonPress-1>', x=x, y=y)
widget.event_generate('<ButtonRelease-1>', x=x, y=y)
+
+
+import _tkinter
+tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
+
+def requires_tcl(*version):
+ return unittest.skipUnless(tcl_version >= version,
+ 'requires Tcl version >= ' + '.'.join(map(str, version)))
+
+_tk_patchlevel = None
+def get_tk_patchlevel():
+ global _tk_patchlevel
+ if _tk_patchlevel is None:
+ tcl = Tkinter.Tcl()
+ patchlevel = []
+ for x in tcl.call('info', 'patchlevel').split('.'):
+ try:
+ x = int(x, 10)
+ except ValueError:
+ x = -1
+ patchlevel.append(x)
+ _tk_patchlevel = tuple(patchlevel)
+ return _tk_patchlevel
+
+units = {
+ 'c': 72 / 2.54, # centimeters
+ 'i': 72, # inches
+ 'm': 72 / 25.4, # millimeters
+ 'p': 1, # points
+}
+
+def pixels_conv(value):
+ return float(value[:-1]) * units[value[-1:]]
+
+def tcl_obj_eq(actual, expected):
+ if actual == expected:
+ return True
+ if isinstance(actual, _tkinter.Tcl_Obj):
+ if isinstance(expected, str):
+ return str(actual) == expected
+ if isinstance(actual, tuple):
+ if isinstance(expected, tuple):
+ return (len(actual) == len(expected) and
+ all(tcl_obj_eq(act, exp)
+ for act, exp in zip(actual, expected)))
+ return False
+
+def widget_eq(actual, expected):
+ if actual == expected:
+ return True
+ if isinstance(actual, (str, Tkinter.Widget)):
+ if isinstance(expected, (str, Tkinter.Widget)):
+ return str(actual) == str(expected)
+ return False
diff -r 3a1db0d2747e Lib/lib-tk/test/test_ttk/test_extensions.py
--- a/Lib/lib-tk/test/test_ttk/test_extensions.py
+++ b/Lib/lib-tk/test/test_ttk/test_extensions.py
@@ -29,7 +29,10 @@
name = myvar._name
x = ttk.LabeledScale(variable=myvar)
x.destroy()
- self.assertEqual(x.tk.globalgetvar(name), myvar.get())
+ if x.tk.wantobjects():
+ self.assertEqual(x.tk.globalgetvar(name), myvar.get())
+ else:
+ self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get())
del myvar
self.assertRaises(Tkinter.TclError, x.tk.globalgetvar, name)
@@ -45,7 +48,7 @@
# it tries calling instance attributes not yet defined.
ttk.LabeledScale(variable=myvar)
if hasattr(sys, 'last_type'):
- self.assertFalse(sys.last_type == Tkinter.TclError)
+ self.assertNotEqual(sys.last_type, Tkinter.TclError)
def test_initialization(self):
@@ -59,8 +62,10 @@
x.destroy()
# variable initialization/passing
- passed_expected = ((2.5, 2), ('0', 0), (0, 0), (10, 10),
+ passed_expected = (('0', 0), (0, 0), (10, 10),
(-1, -1), (sys.maxint + 1, sys.maxint + 1))
+ if x.tk.wantobjects():
+ passed_expected += ((2.5, 2),)
for pair in passed_expected:
x = ttk.LabeledScale(from_=pair[0])
self.assertEqual(x.value, pair[1])
@@ -120,14 +125,14 @@
# at the same time this shouldn't affect test outcome
lscale.update()
curr_xcoord = lscale.scale.coords()[0]
- self.assertTrue(prev_xcoord != curr_xcoord)
+ self.assertNotEqual(prev_xcoord, curr_xcoord)
# the label widget should have been repositioned too
linfo_2 = lscale.label.place_info()
- self.assertEqual(lscale.label['text'], 0)
+ self.assertEqual(lscale.label['text'], 0 if lscale.tk.wantobjects() else '0')
self.assertEqual(curr_xcoord, int(linfo_2['x']))
# change the range back
lscale.scale.configure(from_=0, to=10)
- self.assertTrue(prev_xcoord != curr_xcoord)
+ self.assertNotEqual(prev_xcoord, curr_xcoord)
self.assertEqual(prev_xcoord, int(linfo_1['x']))
lscale.destroy()
@@ -145,15 +150,20 @@
# The following update is needed since the test doesn't use mainloop,
# at the same time this shouldn't affect test outcome
x.update()
- self.assertEqual(x.label['text'], newval)
- self.assertTrue(x.scale.coords()[0] > curr_xcoord)
+ self.assertEqual(x.label['text'],
+ newval if x.tk.wantobjects() else str(newval))
+ self.assertGreater(x.scale.coords()[0], curr_xcoord)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
# value outside range
- x.value = x.scale['to'] + 1 # no changes shouldn't happen
+ if x.tk.wantobjects():
+ conv = lambda x: x
+ else:
+ conv = int
+ x.value = conv(x.scale['to']) + 1 # no changes shouldn't happen
x.update()
- self.assertEqual(x.label['text'], newval)
+ self.assertEqual(conv(x.label['text']), newval)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
@@ -238,7 +248,7 @@
if last == curr:
# no more menu entries
break
- self.assertFalse(curr == default)
+ self.assertNotEqual(curr, default)
i += 1
self.assertEqual(i, len(items))
diff -r 3a1db0d2747e Lib/lib-tk/test/test_ttk/test_functions.py
--- a/Lib/lib-tk/test/test_ttk/test_functions.py
+++ b/Lib/lib-tk/test/test_ttk/test_functions.py
@@ -394,8 +394,10 @@
('name', 'no_minus', 'value'))
self.assertRaises(ValueError, ttk._list_from_layouttuple,
('something', '-children')) # no children
- self.assertRaises(ValueError, ttk._list_from_layouttuple,
- ('something', '-children', 'value')) # invalid children
+ import Tkinter
+ if not Tkinter._default_root or Tkinter._default_root.wantobjects():
+ self.assertRaises(ValueError, ttk._list_from_layouttuple,
+ ('something', '-children', 'value')) # invalid children
def test_val_or_dict(self):
diff -r 3a1db0d2747e Lib/lib-tk/test/test_ttk/test_style.py
--- a/Lib/lib-tk/test/test_ttk/test_style.py
+++ b/Lib/lib-tk/test/test_ttk/test_style.py
@@ -18,15 +18,16 @@
style.configure('TButton', background='yellow')
self.assertEqual(style.configure('TButton', 'background'),
'yellow')
- self.assertTrue(isinstance(style.configure('TButton'), dict))
+ self.assertIsInstance(style.configure('TButton'), dict)
def test_map(self):
style = self.style
style.map('TButton', background=[('active', 'background', 'blue')])
self.assertEqual(style.map('TButton', 'background'),
- [('active', 'background', 'blue')])
- self.assertTrue(isinstance(style.map('TButton'), dict))
+ [('active', 'background', 'blue')] if style.tk.wantobjects() else
+ [('active background', 'blue')])
+ self.assertIsInstance(style.map('TButton'), dict)
def test_lookup(self):
@@ -57,7 +58,7 @@
self.assertEqual(style.layout('Treeview'), tv_style)
# should return a list
- self.assertTrue(isinstance(style.layout('TButton'), list))
+ self.assertIsInstance(style.layout('TButton'), list)
# correct layout, but "option" doesn't exist as option
self.assertRaises(Tkinter.TclError, style.layout, 'Treeview',
diff -r 3a1db0d2747e Lib/lib-tk/test/test_ttk/test_widgets.py
--- a/Lib/lib-tk/test/test_ttk/test_widgets.py
+++ b/Lib/lib-tk/test/test_ttk/test_widgets.py
@@ -6,9 +6,54 @@
import support
from test_functions import MockTclObj, MockStateSpec
+from support import tcl_version, get_tk_patchlevel
+from widget_tests import (add_standard_options, noconv, noconv_meth,
+ AbstractWidgetTest, StandardOptionsTests,
+ IntegerSizeTests, PixelSizeTests,
+ setUpModule)
requires('gui')
+
+class StandardTtkOptionsTests(StandardOptionsTests):
+
+ def test_class(self):
+ widget = self.create()
+ self.assertEqual(widget['class'], '')
+ errmsg='attempt to change read-only option'
+ if get_tk_patchlevel() < (8, 6, 0): # actually this was changed in 8.6b3
+ errmsg='Attempt to change read-only option'
+ self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg)
+ widget2 = self.create(class_='Foo')
+ self.assertEqual(widget2['class'], 'Foo')
+
+ def test_padding(self):
+ widget = self.create()
+ self.checkParam(widget, 'padding', 0, expected=('0',))
+ self.checkParam(widget, 'padding', 5, expected=('5',))
+ self.checkParam(widget, 'padding', (5, 6), expected=('5', '6'))
+ self.checkParam(widget, 'padding', (5, 6, 7),
+ expected=('5', '6', '7'))
+ self.checkParam(widget, 'padding', (5, 6, 7, 8),
+ expected=('5', '6', '7', '8'))
+ self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p'))
+ self.checkParam(widget, 'padding', (), expected='')
+
+ def test_style(self):
+ widget = self.create()
+ self.assertEqual(widget['style'], '')
+ errmsg = 'Layout Foo not found'
+ if hasattr(self, 'default_orient'):
+ errmsg = ('Layout %s.Foo not found' %
+ getattr(self, 'default_orient').title())
+ self.checkInvalidParam(widget, 'style', 'Foo',
+ errmsg=errmsg)
+ widget2 = self.create(class_='Foo')
+ self.assertEqual(widget2['class'], 'Foo')
+ # XXX
+ pass
+
+
class WidgetTest(unittest.TestCase):
"""Tests methods available in every ttk widget."""
@@ -72,7 +117,112 @@
self.assertEqual(self.widget.state(), ('active', ))
-class ButtonTest(unittest.TestCase):
+class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
+ _conv_pixels = noconv_meth
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class FrameTest(AbstractToplevelTest, unittest.TestCase):
+ OPTIONS = (
+ 'borderwidth', 'class', 'cursor', 'height',
+ 'padding', 'relief', 'style', 'takefocus',
+ 'width',
+ )
+
+ def _create(self, **kwargs):
+ return ttk.Frame(self.root, **kwargs)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
+ OPTIONS = (
+ 'borderwidth', 'class', 'cursor', 'height',
+ 'labelanchor', 'labelwidget',
+ 'padding', 'relief', 'style', 'takefocus',
+ 'text', 'underline', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return ttk.LabelFrame(self.root, **kwargs)
+
+ def test_labelanchor(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'labelanchor',
+ 'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws',
+ errmsg='Bad label anchor specification {}')
+ self.checkInvalidParam(widget, 'labelanchor', 'center')
+
+ def test_labelwidget(self):
+ widget = self.create()
+ label = ttk.Label(self.root, text='Mupp', name='foo')
+ self.checkParam(widget, 'labelwidget', label, expected='.foo')
+ label.destroy()
+
+
+class AbstractLabelTest(AbstractWidgetTest):
+
+ def checkImageParam(self, widget, name):
+ image = Tkinter.PhotoImage('image1')
+ image2 = Tkinter.PhotoImage('image2')
+ self.checkParam(widget, name, image, expected=('image1',))
+ self.checkParam(widget, name, 'image1', expected=('image1',))
+ self.checkParam(widget, name, (image,), expected=('image1',))
+ self.checkParam(widget, name, (image, 'active', image2),
+ expected=('image1', 'active', 'image2'))
+ self.checkParam(widget, name, 'image1 active image2',
+ expected=('image1', 'active', 'image2'))
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='image "spam" doesn\'t exist')
+
+ def test_compound(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'compound',
+ 'none', 'text', 'image', 'center',
+ 'top', 'bottom', 'left', 'right')
+
+ def test_state(self):
+ widget = self.create()
+ self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
+
+ def test_width(self):
+ widget = self.create()
+ self.checkParams(widget, 'width', 402, -402, 0)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class LabelTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'anchor', 'background',
+ 'class', 'compound', 'cursor', 'font', 'foreground',
+ 'image', 'justify', 'padding', 'relief', 'state', 'style',
+ 'takefocus', 'text', 'textvariable',
+ 'underline', 'width', 'wraplength',
+ )
+ _conv_pixels = noconv_meth
+
+ def _create(self, **kwargs):
+ return ttk.Label(self.root, **kwargs)
+
+ def test_font(self):
+ widget = self.create()
+ self.checkParam(widget, 'font',
+ '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class ButtonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'command', 'compound', 'cursor', 'default',
+ 'image', 'state', 'style', 'takefocus', 'text', 'textvariable',
+ 'underline', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return ttk.Button(self.root, **kwargs)
+
+ def test_default(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled')
def test_invoke(self):
success = []
@@ -81,7 +231,27 @@
self.assertTrue(success)
-class CheckbuttonTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'command', 'compound', 'cursor',
+ 'image',
+ 'offvalue', 'onvalue',
+ 'state', 'style',
+ 'takefocus', 'text', 'textvariable',
+ 'underline', 'variable', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return ttk.Checkbutton(self.root, **kwargs)
+
+ def test_offvalue(self):
+ widget = self.create()
+ self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
+
+ def test_onvalue(self):
+ widget = self.create()
+ self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
def test_invoke(self):
success = []
@@ -104,21 +274,40 @@
cbtn['command'] = ''
res = cbtn.invoke()
- self.assertEqual(str(res), '')
- self.assertFalse(len(success) > 1)
+ self.assertFalse(str(res))
+ self.assertLessEqual(len(success), 1)
self.assertEqual(cbtn['offvalue'],
cbtn.tk.globalgetvar(cbtn['variable']))
-class ComboboxTest(unittest.TestCase):
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'cursor', 'exportselection', 'height',
+ 'justify', 'postcommand', 'state', 'style',
+ 'takefocus', 'textvariable', 'values', 'width',
+ )
def setUp(self):
+ super(ComboboxTest, self).setUp()
support.root_deiconify()
- self.combo = ttk.Combobox()
+ self.combo = self.create()
def tearDown(self):
self.combo.destroy()
support.root_withdraw()
+ super(ComboboxTest, self).tearDown()
+
+ def _create(self, **kwargs):
+ return ttk.Combobox(self.root, **kwargs)
+
+ def test_height(self):
+ widget = self.create()
+ self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
+
+ def test_state(self):
+ widget = self.create()
+ self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
def _show_drop_down_listbox(self):
width = self.combo.winfo_width()
@@ -166,8 +355,16 @@
self.assertEqual(self.combo.get(), getval)
self.assertEqual(self.combo.current(), currval)
+ self.assertEqual(self.combo['values'],
+ () if tcl_version < (8, 5) else '')
check_get_current('', -1)
+ self.checkParam(self.combo, 'values', 'mon tue wed thur',
+ expected=('mon', 'tue', 'wed', 'thur'))
+ self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
+ self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
+ self.checkParam(self.combo, 'values', () if tcl_version < (8, 5) else '')
+
self.combo['values'] = ['a', 1, 'c']
self.combo.set('c')
@@ -186,15 +383,21 @@
# testing values with empty string set through configure
self.combo.configure(values=[1, '', 2])
- self.assertEqual(self.combo['values'], ('1', '', '2'))
+ self.assertEqual(self.combo['values'],
+ ('1', '', '2') if self.wantobjects else
+ '1 {} 2')
# testing values with spaces
self.combo['values'] = ['a b', 'a\tb', 'a\nb']
- self.assertEqual(self.combo['values'], ('a b', 'a\tb', 'a\nb'))
+ self.assertEqual(self.combo['values'],
+ ('a b', 'a\tb', 'a\nb') if self.wantobjects else
+ '{a b} {a\tb} {a\nb}')
# testing values with special characters
self.combo['values'] = [r'a\tb', '"a"', '} {']
- self.assertEqual(self.combo['values'], (r'a\tb', '"a"', '} {'))
+ self.assertEqual(self.combo['values'],
+ (r'a\tb', '"a"', '} {') if self.wantobjects else
+ r'a\\tb {"a"} \}\ \{')
# out of range
self.assertRaises(Tkinter.TclError, self.combo.current,
@@ -204,25 +407,63 @@
# testing creating combobox with empty string in values
combo2 = ttk.Combobox(values=[1, 2, ''])
- self.assertEqual(combo2['values'], ('1', '2', ''))
+ self.assertEqual(combo2['values'],
+ ('1', '2', '') if self.wantobjects else '1 2 {}')
combo2.destroy()
-class EntryTest(unittest.TestCase):
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class EntryTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'class', 'cursor',
+ 'exportselection', 'font',
+ 'invalidcommand', 'justify',
+ 'show', 'state', 'style', 'takefocus', 'textvariable',
+ 'validate', 'validatecommand', 'width', 'xscrollcommand',
+ )
def setUp(self):
+ super(EntryTest, self).setUp()
support.root_deiconify()
- self.entry = ttk.Entry()
+ self.entry = self.create()
def tearDown(self):
self.entry.destroy()
support.root_withdraw()
+ super(EntryTest, self).tearDown()
+
+ def _create(self, **kwargs):
+ return ttk.Entry(self.root, **kwargs)
+
+ def test_invalidcommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'invalidcommand')
+
+ def test_show(self):
+ widget = self.create()
+ self.checkParam(widget, 'show', '*')
+ self.checkParam(widget, 'show', '')
+ self.checkParam(widget, 'show', ' ')
+
+ def test_state(self):
+ widget = self.create()
+ self.checkParams(widget, 'state',
+ 'disabled', 'normal', 'readonly')
+
+ def test_validate(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'validate',
+ 'all', 'key', 'focus', 'focusin', 'focusout', 'none')
+
+ def test_validatecommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'validatecommand')
def test_bbox(self):
self.assertEqual(len(self.entry.bbox(0)), 4)
for item in self.entry.bbox(0):
- self.assertTrue(isinstance(item, int))
+ self.assertIsInstance(item, int)
self.assertRaises(Tkinter.TclError, self.entry.bbox, 'noindex')
self.assertRaises(Tkinter.TclError, self.entry.bbox, None)
@@ -312,16 +553,36 @@
self.assertEqual(self.entry.state(), ())
-class PanedwindowTest(unittest.TestCase):
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'cursor', 'height',
+ 'orient', 'style', 'takefocus', 'width',
+ )
def setUp(self):
+ super(PanedWindowTest, self).setUp()
support.root_deiconify()
- self.paned = ttk.Panedwindow()
+ self.paned = self.create()
def tearDown(self):
self.paned.destroy()
support.root_withdraw()
+ super(PanedWindowTest, self).tearDown()
+ def _create(self, **kwargs):
+ return ttk.PanedWindow(self.root, **kwargs)
+
+ def test_orient(self):
+ widget = self.create()
+ self.assertEqual(str(widget['orient']), 'vertical')
+ errmsg='attempt to change read-only option'
+ if get_tk_patchlevel() < (8, 6, 0): # actually this was changed in 8.6b3
+ errmsg='Attempt to change read-only option'
+ self.checkInvalidParam(widget, 'orient', 'horizontal',
+ errmsg=errmsg)
+ widget2 = self.create(orient='horizontal')
+ self.assertEqual(str(widget2['orient']), 'horizontal')
def test_add(self):
# attempt to add a child that is not a direct child of the paned window
@@ -400,10 +661,12 @@
child = ttk.Label()
self.paned.add(child)
- self.assertTrue(isinstance(self.paned.pane(0), dict))
- self.assertEqual(self.paned.pane(0, weight=None), 0)
+ self.assertIsInstance(self.paned.pane(0), dict)
+ self.assertEqual(self.paned.pane(0, weight=None),
+ 0 if self.wantobjects else '0')
# newer form for querying a single option
- self.assertEqual(self.paned.pane(0, 'weight'), 0)
+ self.assertEqual(self.paned.pane(0, 'weight'),
+ 0 if self.wantobjects else '0')
self.assertEqual(self.paned.pane(0), self.paned.pane(str(child)))
self.assertRaises(Tkinter.TclError, self.paned.pane, 0,
@@ -427,11 +690,26 @@
curr_pos = self.paned.sashpos(0)
self.paned.sashpos(0, 1000)
- self.assertTrue(curr_pos != self.paned.sashpos(0))
- self.assertTrue(isinstance(self.paned.sashpos(0), int))
+ self.assertNotEqual(curr_pos, self.paned.sashpos(0))
+ self.assertIsInstance(self.paned.sashpos(0), int)
-class RadiobuttonTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'command', 'compound', 'cursor',
+ 'image',
+ 'state', 'style',
+ 'takefocus', 'text', 'textvariable',
+ 'underline', 'value', 'variable', 'width',
+ )
+
+ def _create(self, **kwargs):
+ return ttk.Radiobutton(self.root, **kwargs)
+
+ def test_value(self):
+ widget = self.create()
+ self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
def test_invoke(self):
success = []
@@ -443,37 +721,91 @@
cbtn = ttk.Radiobutton(command=cb_test, variable=myvar, value=0)
cbtn2 = ttk.Radiobutton(command=cb_test, variable=myvar, value=1)
+ if self.wantobjects:
+ conv = lambda x: x
+ else:
+ conv = int
+
res = cbtn.invoke()
self.assertEqual(res, "cb test called")
- self.assertEqual(cbtn['value'], myvar.get())
+ self.assertEqual(conv(cbtn['value']), myvar.get())
self.assertEqual(myvar.get(),
- cbtn.tk.globalgetvar(cbtn['variable']))
+ conv(cbtn.tk.globalgetvar(cbtn['variable'])))
self.assertTrue(success)
cbtn2['command'] = ''
res = cbtn2.invoke()
self.assertEqual(str(res), '')
- self.assertFalse(len(success) > 1)
- self.assertEqual(cbtn2['value'], myvar.get())
+ self.assertLessEqual(len(success), 1)
+ self.assertEqual(conv(cbtn2['value']), myvar.get())
self.assertEqual(myvar.get(),
- cbtn.tk.globalgetvar(cbtn['variable']))
+ conv(cbtn.tk.globalgetvar(cbtn['variable'])))
self.assertEqual(str(cbtn['variable']), str(cbtn2['variable']))
+class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'compound', 'cursor', 'direction',
+ 'image', 'menu', 'state', 'style',
+ 'takefocus', 'text', 'textvariable',
+ 'underline', 'width',
+ )
-class ScaleTest(unittest.TestCase):
+ def _create(self, **kwargs):
+ return ttk.Menubutton(self.root, **kwargs)
+
+ def test_direction(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'direction',
+ 'above', 'below', 'left', 'right', 'flush')
+
+ def test_menu(self):
+ widget = self.create()
+ menu = Tkinter.Menu(widget, name='menu')
+ self.checkParam(widget, 'menu', menu, conv=str)
+ menu.destroy()
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class ScaleTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'command', 'cursor', 'from', 'length',
+ 'orient', 'style', 'takefocus', 'to', 'value', 'variable',
+ )
+ _conv_pixels = noconv_meth
+ default_orient = 'horizontal'
def setUp(self):
+ super(ScaleTest, self).setUp()
support.root_deiconify()
- self.scale = ttk.Scale()
+ self.scale = self.create()
self.scale.pack()
self.scale.update()
def tearDown(self):
self.scale.destroy()
support.root_withdraw()
+ super(ScaleTest, self).tearDown()
+ def _create(self, **kwargs):
+ return ttk.Scale(self.root, **kwargs)
+
+ def test_from(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False)
+
+ def test_length(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
+
+ def test_to(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False)
+
+ def test_value(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False)
def test_custom_event(self):
failure = [1, 1, 1] # will need to be empty
@@ -495,10 +827,15 @@
def test_get(self):
+ if self.wantobjects:
+ conv = lambda x: x
+ else:
+ conv = float
+
scale_width = self.scale.winfo_width()
self.assertEqual(self.scale.get(scale_width, 0), self.scale['to'])
- self.assertEqual(self.scale.get(0, 0), self.scale['from'])
+ self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from']))
self.assertEqual(self.scale.get(), self.scale['value'])
self.scale['value'] = 30
self.assertEqual(self.scale.get(), self.scale['value'])
@@ -508,41 +845,99 @@
def test_set(self):
+ if self.wantobjects:
+ conv = lambda x: x
+ else:
+ conv = float
+
# set restricts the max/min values according to the current range
- max = self.scale['to']
+ max = conv(self.scale['to'])
new_max = max + 10
self.scale.set(new_max)
- self.assertEqual(self.scale.get(), max)
- min = self.scale['from']
+ self.assertEqual(conv(self.scale.get()), max)
+ min = conv(self.scale['from'])
self.scale.set(min - 1)
- self.assertEqual(self.scale.get(), min)
+ self.assertEqual(conv(self.scale.get()), min)
# changing directly the variable doesn't impose this limitation tho
var = Tkinter.DoubleVar()
self.scale['variable'] = var
var.set(max + 5)
- self.assertEqual(self.scale.get(), var.get())
- self.assertEqual(self.scale.get(), max + 5)
+ self.assertEqual(conv(self.scale.get()), var.get())
+ self.assertEqual(conv(self.scale.get()), max + 5)
del var
# the same happens with the value option
self.scale['value'] = max + 10
- self.assertEqual(self.scale.get(), max + 10)
- self.assertEqual(self.scale.get(), self.scale['value'])
+ self.assertEqual(conv(self.scale.get()), max + 10)
+ self.assertEqual(conv(self.scale.get()), conv(self.scale['value']))
# nevertheless, note that the max/min values we can get specifying
# x, y coords are the ones according to the current range
- self.assertEqual(self.scale.get(0, 0), min)
- self.assertEqual(self.scale.get(self.scale.winfo_width(), 0), max)
+ self.assertEqual(conv(self.scale.get(0, 0)), min)
+ self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max)
self.assertRaises(Tkinter.TclError, self.scale.set, None)
-class NotebookTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'cursor', 'orient', 'length',
+ 'mode', 'maximum', 'phase',
+ 'style', 'takefocus', 'value', 'variable',
+ )
+ _conv_pixels = noconv_meth
+ default_orient = 'horizontal'
+
+ def _create(self, **kwargs):
+ return ttk.Progressbar(self.root, **kwargs)
+
+ def test_length(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i')
+
+ def test_maximum(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False)
+
+ def test_mode(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate')
+
+ def test_phase(self):
+ # XXX
+ pass
+
+ def test_value(self):
+ widget = self.create()
+ self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10,
+ conv=False)
+
+
+@unittest.skipIf(sys.platform == 'darwin',
+ 'ttk.Scrollbar is special on MacOSX')
+@add_standard_options(StandardTtkOptionsTests)
+class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'command', 'cursor', 'orient', 'style', 'takefocus',
+ )
+ default_orient = 'vertical'
+
+ def _create(self, **kwargs):
+ return ttk.Scrollbar(self.root, **kwargs)
+
+
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class NotebookTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'cursor', 'height', 'padding', 'style', 'takefocus',
+ )
def setUp(self):
+ super(NotebookTest, self).setUp()
support.root_deiconify()
- self.nb = ttk.Notebook(padding=0)
+ self.nb = self.create(padding=0)
self.child1 = ttk.Label()
self.child2 = ttk.Label()
self.nb.add(self.child1, text='a')
@@ -553,7 +948,10 @@
self.child2.destroy()
self.nb.destroy()
support.root_withdraw()
+ super(NotebookTest, self).tearDown()
+ def _create(self, **kwargs):
+ return ttk.Notebook(self.root, **kwargs)
def test_tab_identifiers(self):
self.nb.forget(0)
@@ -610,7 +1008,7 @@
self.nb.add(self.child2)
self.assertEqual(self.nb.tabs(), tabs)
self.assertEqual(self.nb.index(self.child2), child2_index)
- self.assertTrue(str(self.child2) == self.nb.tabs()[child2_index])
+ self.assertEqual(str(self.child2), self.nb.tabs()[child2_index])
# but the tab next to it (not hidden) is the one selected now
self.assertEqual(self.nb.index('current'), curr + 1)
@@ -623,19 +1021,19 @@
tabs = self.nb.tabs()
child1_index = self.nb.index(self.child1)
self.nb.forget(self.child1)
- self.assertFalse(str(self.child1) in self.nb.tabs())
+ self.assertNotIn(str(self.child1), self.nb.tabs())
self.assertEqual(len(tabs) - 1, len(self.nb.tabs()))
self.nb.add(self.child1)
self.assertEqual(self.nb.index(self.child1), 1)
- self.assertFalse(child1_index == self.nb.index(self.child1))
+ self.assertNotEqual(child1_index, self.nb.index(self.child1))
def test_index(self):
self.assertRaises(Tkinter.TclError, self.nb.index, -1)
self.assertRaises(Tkinter.TclError, self.nb.index, None)
- self.assertTrue(isinstance(self.nb.index('end'), int))
+ self.assertIsInstance(self.nb.index('end'), int)
self.assertEqual(self.nb.index(self.child1), 0)
self.assertEqual(self.nb.index(self.child2), 1)
self.assertEqual(self.nb.index('end'), 2)
@@ -699,7 +1097,7 @@
self.assertRaises(Tkinter.TclError, self.nb.tab, 'notab')
self.assertRaises(Tkinter.TclError, self.nb.tab, None)
- self.assertTrue(isinstance(self.nb.tab(self.child1), dict))
+ self.assertIsInstance(self.nb.tab(self.child1), dict)
self.assertEqual(self.nb.tab(self.child1, text=None), 'a')
# newer form for querying a single option
self.assertEqual(self.nb.tab(self.child1, 'text'), 'a')
@@ -745,16 +1143,68 @@
self.assertEqual(self.nb.select(), str(self.child1))
-class TreeviewTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'columns', 'cursor', 'displaycolumns',
+ 'height', 'padding', 'selectmode', 'show',
+ 'style', 'takefocus', 'xscrollcommand', 'yscrollcommand',
+ )
def setUp(self):
+ super(TreeviewTest, self).setUp()
support.root_deiconify()
- self.tv = ttk.Treeview(padding=0)
+ self.tv = self.create(padding=0)
def tearDown(self):
self.tv.destroy()
support.root_withdraw()
+ super(TreeviewTest, self).tearDown()
+ def _create(self, **kwargs):
+ return ttk.Treeview(self.root, **kwargs)
+
+ def test_columns(self):
+ widget = self.create()
+ self.checkParam(widget, 'columns', 'a b c',
+ expected=('a', 'b', 'c'))
+ self.checkParam(widget, 'columns', ('a', 'b', 'c'))
+ self.checkParam(widget, 'columns', () if tcl_version < (8, 5) else '')
+
+ def test_displaycolumns(self):
+ widget = self.create()
+ widget['columns'] = ('a', 'b', 'c')
+ self.checkParam(widget, 'displaycolumns', 'b a c',
+ expected=('b', 'a', 'c'))
+ self.checkParam(widget, 'displaycolumns', ('b', 'a', 'c'))
+ self.checkParam(widget, 'displaycolumns', '#all',
+ expected=('#all',))
+ self.checkParam(widget, 'displaycolumns', (2, 1, 0))
+ self.checkInvalidParam(widget, 'displaycolumns', ('a', 'b', 'd'),
+ errmsg='Invalid column index d')
+ self.checkInvalidParam(widget, 'displaycolumns', (1, 2, 3),
+ errmsg='Column index 3 out of bounds')
+ self.checkInvalidParam(widget, 'displaycolumns', (1, -2),
+ errmsg='Column index -2 out of bounds')
+
+ def test_height(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
+ self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv)
+
+ def test_selectmode(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'selectmode',
+ 'none', 'browse', 'extended')
+
+ def test_show(self):
+ widget = self.create()
+ self.checkParam(widget, 'show', 'tree headings',
+ expected=('tree', 'headings'))
+ self.checkParam(widget, 'show', ('tree', 'headings'))
+ self.checkParam(widget, 'show', ('headings', 'tree'))
+ self.checkParam(widget, 'show', 'tree', expected=('tree',))
+ self.checkParam(widget, 'show', 'headings', expected=('headings',))
def test_bbox(self):
self.tv.pack()
@@ -768,7 +1218,7 @@
bbox = self.tv.bbox(children[0])
self.assertEqual(len(bbox), 4)
- self.assertTrue(isinstance(bbox, tuple))
+ self.assertIsInstance(bbox, tuple)
for item in bbox:
if not isinstance(item, int):
self.fail("Invalid bounding box: %s" % bbox)
@@ -779,6 +1229,8 @@
self.tv.column('test', width=50)
bbox_column0 = self.tv.bbox(children[0], 0)
root_width = self.tv.column('#0', width=None)
+ if not self.wantobjects:
+ root_width = int(root_width)
self.assertEqual(bbox_column0[0], bbox[0] + root_width)
# verify that bbox of a closed item is the empty string
@@ -791,7 +1243,7 @@
self.assertEqual(self.tv.get_children(), ())
item_id = self.tv.insert('', 'end')
- self.assertTrue(isinstance(self.tv.get_children(), tuple))
+ self.assertIsInstance(self.tv.get_children(), tuple)
self.assertEqual(self.tv.get_children()[0], item_id)
# add item_id and child3 as children of child2
@@ -816,14 +1268,17 @@
def test_column(self):
# return a dict with all options/values
- self.assertTrue(isinstance(self.tv.column('#0'), dict))
+ self.assertIsInstance(self.tv.column('#0'), dict)
# return a single value of the given option
- self.assertTrue(isinstance(self.tv.column('#0', width=None), int))
+ if self.wantobjects:
+ self.assertIsInstance(self.tv.column('#0', width=None), int)
# set a new value for an option
self.tv.column('#0', width=10)
# testing new way to get option value
- self.assertEqual(self.tv.column('#0', 'width'), 10)
- self.assertEqual(self.tv.column('#0', width=None), 10)
+ self.assertEqual(self.tv.column('#0', 'width'),
+ 10 if self.wantobjects else '10')
+ self.assertEqual(self.tv.column('#0', width=None),
+ 10 if self.wantobjects else '10')
# check read-only option
self.assertRaises(Tkinter.TclError, self.tv.column, '#0', id='X')
@@ -931,7 +1386,7 @@
def test_heading(self):
# check a dict is returned
- self.assertTrue(isinstance(self.tv.heading('#0'), dict))
+ self.assertIsInstance(self.tv.heading('#0'), dict)
# check a value is returned
self.tv.heading('#0', text='hi')
@@ -945,12 +1400,10 @@
self.assertRaises(Tkinter.TclError, self.tv.heading, '#0',
anchor=1)
- # XXX skipping for now; should be fixed to work with newer ttk
- @unittest.skip("skipping pending resolution of Issue #10734")
def test_heading_callback(self):
def simulate_heading_click(x, y):
support.simulate_mouse_click(self.tv, x, y)
- self.tv.update_idletasks()
+ self.tv.update()
success = [] # no success for now
@@ -1038,13 +1491,16 @@
# unicode values
value = u'\xe1ba'
item = self.tv.insert('', 'end', values=(value, ))
- self.assertEqual(self.tv.item(item, 'values'), (value, ))
- self.assertEqual(self.tv.item(item, values=None), (value, ))
+ self.assertEqual(self.tv.item(item, 'values'),
+ (value,) if self.wantobjects else value)
+ self.assertEqual(self.tv.item(item, values=None),
+ (value,) if self.wantobjects else value)
- self.tv.item(item, values=list(self.tv.item(item, values=None)))
- self.assertEqual(self.tv.item(item, values=None), (value, ))
+ self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None)))
+ self.assertEqual(self.tv.item(item, values=None),
+ (value,) if self.wantobjects else value)
- self.assertTrue(isinstance(self.tv.item(item), dict))
+ self.assertIsInstance(self.tv.item(item), dict)
# erase item values
self.tv.item(item, values='')
@@ -1052,17 +1508,21 @@
# item tags
item = self.tv.insert('', 'end', tags=[1, 2, value])
- self.assertEqual(self.tv.item(item, tags=None), ('1', '2', value))
+ self.assertEqual(self.tv.item(item, tags=None),
+ ('1', '2', value) if self.wantobjects else
+ '1 2 %s' % value)
self.tv.item(item, tags=[])
self.assertFalse(self.tv.item(item, tags=None))
self.tv.item(item, tags=(1, 2))
- self.assertEqual(self.tv.item(item, tags=None), ('1', '2'))
+ self.assertEqual(self.tv.item(item, tags=None),
+ ('1', '2') if self.wantobjects else '1 2')
# values with spaces
item = self.tv.insert('', 'end', values=('a b c',
'%s %s' % (value, value)))
self.assertEqual(self.tv.item(item, values=None),
- ('a b c', '%s %s' % (value, value)))
+ ('a b c', '%s %s' % (value, value)) if self.wantobjects else
+ '{a b c} {%s %s}' % (value, value))
# text
self.assertEqual(self.tv.item(
@@ -1079,19 +1539,24 @@
self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'})
self.tv.set(item, 'B', 'a')
- self.assertEqual(self.tv.item(item, values=None), ('a', 'a'))
+ self.assertEqual(self.tv.item(item, values=None),
+ ('a', 'a') if self.wantobjects else 'a a')
self.tv['columns'] = ['B']
self.assertEqual(self.tv.set(item), {'B': 'a'})
self.tv.set(item, 'B', 'b')
self.assertEqual(self.tv.set(item, column='B'), 'b')
- self.assertEqual(self.tv.item(item, values=None), ('b', 'a'))
+ self.assertEqual(self.tv.item(item, values=None),
+ ('b', 'a') if self.wantobjects else 'b a')
self.tv.set(item, 'B', 123)
- self.assertEqual(self.tv.set(item, 'B'), 123)
- self.assertEqual(self.tv.item(item, values=None), (123, 'a'))
- self.assertEqual(self.tv.set(item), {'B': 123})
+ self.assertEqual(self.tv.set(item, 'B'),
+ 123 if self.wantobjects else '123')
+ self.assertEqual(self.tv.item(item, values=None),
+ (123, 'a') if self.wantobjects else '123 a')
+ self.assertEqual(self.tv.set(item),
+ {'B': 123} if self.wantobjects else {'B': '123'})
# inexistent column
self.assertRaises(Tkinter.TclError, self.tv.set, item, 'A')
@@ -1145,13 +1610,38 @@
'blue')
self.assertEqual(str(self.tv.tag_configure('test', foreground=None)),
'blue')
- self.assertTrue(isinstance(self.tv.tag_configure('test'), dict))
+ self.assertIsInstance(self.tv.tag_configure('test'), dict)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class SeparatorTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'cursor', 'orient', 'style', 'takefocus',
+ # 'state'?
+ )
+ default_orient = 'horizontal'
+
+ def _create(self, **kwargs):
+ return ttk.Separator(self.root, **kwargs)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class SizegripTest(AbstractWidgetTest, unittest.TestCase):
+ OPTIONS = (
+ 'class', 'cursor', 'style', 'takefocus',
+ # 'state'?
+ )
+
+ def _create(self, **kwargs):
+ return ttk.Sizegrip(self.root, **kwargs)
tests_gui = (
- WidgetTest, ButtonTest, CheckbuttonTest, RadiobuttonTest,
- ComboboxTest, EntryTest, PanedwindowTest, ScaleTest, NotebookTest,
- TreeviewTest
+ ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest,
+ FrameTest, LabelFrameTest, LabelTest, MenubuttonTest,
+ NotebookTest, PanedWindowTest, ProgressbarTest,
+ RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest,
+ SizegripTest, TreeviewTest, WidgetTest,
)
if __name__ == "__main__":
diff -r 3a1db0d2747e Lib/lib-tk/test/widget_tests.py
--- /dev/null
+++ b/Lib/lib-tk/test/widget_tests.py
@@ -0,0 +1,526 @@
+# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
+
+import unittest
+import sys
+import Tkinter
+from ttk import setup_master, Scale
+from test_ttk.support import (tcl_version, requires_tcl, get_tk_patchlevel,
+ pixels_conv, tcl_obj_eq)
+import test.test_support
+
+
+noconv = noconv_meth = False
+if get_tk_patchlevel() < (8, 5, 11):
+ noconv = str
+noconv_meth = noconv and staticmethod(noconv)
+
+def int_round(x):
+ return int(round(x))
+
+pixels_round = int_round
+if get_tk_patchlevel()[:3] == (8, 5, 11):
+ # Issue #19085: Workaround a bug in Tk
+ # http://core.tcl.tk/tk/info/3497848
+ pixels_round = int
+
+
+_sentinel = object()
+
+class AbstractWidgetTest(object):
+ _conv_pixels = staticmethod(pixels_round)
+ _conv_pad_pixels = None
+ wantobjects = True
+
+ def setUp(self):
+ self.root = setup_master()
+ self.scaling = float(self.root.call('tk', 'scaling'))
+ if not self.root.wantobjects():
+ self.wantobjects = False
+
+ def create(self, **kwargs):
+ widget = self._create(**kwargs)
+ self.addCleanup(widget.destroy)
+ return widget
+
+ def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__):
+ if eq(actual, expected):
+ return
+ self.assertEqual(actual, expected, msg)
+
+ def checkParam(self, widget, name, value, expected=_sentinel,
+ conv=False, eq=None):
+ widget[name] = value
+ if expected is _sentinel:
+ expected = value
+ if conv:
+ expected = conv(expected)
+ if not self.wantobjects:
+ if isinstance(expected, tuple):
+ expected = Tkinter._join(expected)
+ else:
+ expected = str(expected)
+ if eq is None:
+ eq = tcl_obj_eq
+ self.assertEqual2(widget[name], expected, eq=eq)
+ self.assertEqual2(widget.cget(name), expected, eq=eq)
+ # XXX
+ if not isinstance(widget, Scale):
+ t = widget.configure(name)
+ self.assertEqual(len(t), 5)
+ self.assertEqual2(t[4], expected, eq=eq)
+
+ def checkInvalidParam(self, widget, name, value, errmsg=None,
+ keep_orig=True):
+ orig = widget[name]
+ if errmsg is not None:
+ errmsg = errmsg.format(value)
+ with self.assertRaises(Tkinter.TclError) as cm:
+ widget[name] = value
+ if errmsg is not None:
+ self.assertEqual(str(cm.exception), errmsg)
+ if keep_orig:
+ self.assertEqual(widget[name], orig)
+ else:
+ widget[name] = orig
+ with self.assertRaises(Tkinter.TclError) as cm:
+ widget.configure({name: value})
+ if errmsg is not None:
+ self.assertEqual(str(cm.exception), errmsg)
+ if keep_orig:
+ self.assertEqual(widget[name], orig)
+ else:
+ widget[name] = orig
+
+ def checkParams(self, widget, name, *values, **kwargs):
+ for value in values:
+ self.checkParam(widget, name, value, **kwargs)
+
+ def checkIntegerParam(self, widget, name, *values, **kwargs):
+ self.checkParams(widget, name, *values, **kwargs)
+ self.checkInvalidParam(widget, name, '',
+ errmsg='expected integer but got ""')
+ self.checkInvalidParam(widget, name, '10p',
+ errmsg='expected integer but got "10p"')
+ self.checkInvalidParam(widget, name, 3.2,
+ errmsg='expected integer but got "3.2"')
+
+ def checkFloatParam(self, widget, name, *values, **kwargs):
+ if 'conv' in kwargs:
+ conv = kwargs.pop('conv')
+ else:
+ conv = float
+ for value in values:
+ self.checkParam(widget, name, value, conv=conv, **kwargs)
+ self.checkInvalidParam(widget, name, '',
+ errmsg='expected floating-point number but got ""')
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='expected floating-point number but got "spam"')
+
+ def checkBooleanParam(self, widget, name):
+ for value in (False, 0, 'false', 'no', 'off'):
+ self.checkParam(widget, name, value, expected=0)
+ for value in (True, 1, 'true', 'yes', 'on'):
+ self.checkParam(widget, name, value, expected=1)
+ self.checkInvalidParam(widget, name, '',
+ errmsg='expected boolean value but got ""')
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='expected boolean value but got "spam"')
+
+ def checkColorParam(self, widget, name, allow_empty=None, **kwargs):
+ self.checkParams(widget, name,
+ '#ff0000', '#00ff00', '#0000ff', '#123456',
+ 'red', 'green', 'blue', 'white', 'black', 'grey',
+ **kwargs)
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='unknown color name "spam"')
+
+ def checkCursorParam(self, widget, name, **kwargs):
+ self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs)
+ if tcl_version >= (8, 5):
+ self.checkParam(widget, name, 'none')
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='bad cursor spec "spam"')
+
+ def checkCommandParam(self, widget, name):
+ def command(*args):
+ pass
+ widget[name] = command
+ self.assertTrue(widget[name])
+ self.checkParams(widget, name, '')
+
+ def checkEnumParam(self, widget, name, *values, **kwargs):
+ if 'errmsg' in kwargs:
+ errmsg = kwargs.pop('errmsg')
+ else:
+ errmsg = None
+ self.checkParams(widget, name, *values, **kwargs)
+ if errmsg is None:
+ errmsg2 = ' %s "{}": must be %s%s or %s' % (
+ name,
+ ', '.join(values[:-1]),
+ ',' if len(values) > 2 else '',
+ values[-1])
+ self.checkInvalidParam(widget, name, '',
+ errmsg='ambiguous' + errmsg2)
+ errmsg = 'bad' + errmsg2
+ self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
+
+ def checkPixelsParam(self, widget, name, *values, **kwargs):
+ if 'conv' in kwargs:
+ conv = kwargs.pop('conv')
+ else:
+ conv = None
+ if conv is None:
+ conv = self._conv_pixels
+ if 'keep_orig' in kwargs:
+ keep_orig = kwargs.pop('keep_orig')
+ else:
+ keep_orig = True
+ for value in values:
+ expected = _sentinel
+ conv1 = conv
+ if isinstance(value, str):
+ if conv1 and conv1 is not str:
+ expected = pixels_conv(value) * self.scaling
+ conv1 = int_round
+ self.checkParam(widget, name, value, expected=expected,
+ conv=conv1, **kwargs)
+ self.checkInvalidParam(widget, name, '6x',
+ errmsg='bad screen distance "6x"', keep_orig=keep_orig)
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='bad screen distance "spam"', keep_orig=keep_orig)
+
+ def checkReliefParam(self, widget, name):
+ self.checkParams(widget, name,
+ 'flat', 'groove', 'raised', 'ridge', 'solid', 'sunken')
+ errmsg='bad relief "spam": must be '\
+ 'flat, groove, raised, ridge, solid, or sunken'
+ if tcl_version < (8, 6):
+ errmsg = None
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg=errmsg)
+
+ def checkImageParam(self, widget, name):
+ image = Tkinter.PhotoImage('image1')
+ self.checkParam(widget, name, image, conv=str)
+ self.checkInvalidParam(widget, name, 'spam',
+ errmsg='image "spam" doesn\'t exist')
+ widget[name] = ''
+
+ def checkVariableParam(self, widget, name, var):
+ self.checkParam(widget, name, var, conv=str)
+
+
+class StandardOptionsTests(object):
+ STANDARD_OPTIONS = (
+ 'activebackground', 'activeborderwidth', 'activeforeground', 'anchor',
+ 'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
+ 'disabledforeground', 'exportselection', 'font', 'foreground',
+ 'highlightbackground', 'highlightcolor', 'highlightthickness',
+ 'image', 'insertbackground', 'insertborderwidth',
+ 'insertofftime', 'insertontime', 'insertwidth',
+ 'jump', 'justify', 'orient', 'padx', 'pady', 'relief',
+ 'repeatdelay', 'repeatinterval',
+ 'selectbackground', 'selectborderwidth', 'selectforeground',
+ 'setgrid', 'takefocus', 'text', 'textvariable', 'troughcolor',
+ 'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand',
+ )
+
+ def test_activebackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'activebackground')
+
+ def test_activeborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'activeborderwidth',
+ 0, 1.3, 2.9, 6, -2, '10p')
+
+ def test_activeforeground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'activeforeground')
+
+ def test_anchor(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'anchor',
+ 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
+
+ def test_background(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'background')
+ if 'bg' in self.OPTIONS:
+ self.checkColorParam(widget, 'bg')
+
+ def test_bitmap(self):
+ widget = self.create()
+ self.checkParam(widget, 'bitmap', 'questhead')
+ self.checkParam(widget, 'bitmap', 'gray50')
+ filename = test.test_support.findfile('python.xbm', subdir='imghdrdata')
+ self.checkParam(widget, 'bitmap', '@' + filename)
+ # Cocoa Tk widgets don't detect invalid -bitmap values
+ # See https://core.tcl.tk/tk/info/31cd33dbf0
+ if not ('aqua' in self.root.tk.call('tk', 'windowingsystem') and
+ 'AppKit' in self.root.winfo_server()):
+ self.checkInvalidParam(widget, 'bitmap', 'spam',
+ errmsg='bitmap "spam" not defined')
+
+ def test_borderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'borderwidth',
+ 0, 1.3, 2.6, 6, -2, '10p')
+ if 'bd' in self.OPTIONS:
+ self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, -2, '10p')
+
+ def test_compound(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'compound',
+ 'bottom', 'center', 'left', 'none', 'right', 'top')
+
+ def test_cursor(self):
+ widget = self.create()
+ self.checkCursorParam(widget, 'cursor')
+
+ def test_disabledforeground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'disabledforeground')
+
+ def test_exportselection(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'exportselection')
+
+ def test_font(self):
+ widget = self.create()
+ self.checkParam(widget, 'font',
+ '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
+ self.checkInvalidParam(widget, 'font', '',
+ errmsg='font "" doesn\'t exist')
+
+ def test_foreground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'foreground')
+ if 'fg' in self.OPTIONS:
+ self.checkColorParam(widget, 'fg')
+
+ def test_highlightbackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'highlightbackground')
+
+ def test_highlightcolor(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'highlightcolor')
+
+ def test_highlightthickness(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'highlightthickness',
+ 0, 1.3, 2.6, 6, '10p')
+ self.checkParam(widget, 'highlightthickness', -2, expected=0,
+ conv=self._conv_pixels)
+
+ @unittest.skipIf(sys.platform == 'darwin',
+ 'crashes with Cocoa Tk (issue19733)')
+ def test_image(self):
+ widget = self.create()
+ self.checkImageParam(widget, 'image')
+
+ def test_insertbackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'insertbackground')
+
+ def test_insertborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'insertborderwidth',
+ 0, 1.3, 2.6, 6, -2, '10p')
+
+ def test_insertofftime(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'insertofftime', 100)
+
+ def test_insertontime(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'insertontime', 100)
+
+ def test_insertwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
+
+ def test_jump(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'jump')
+
+ def test_justify(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'justify', 'left', 'right', 'center',
+ errmsg='bad justification "{}": must be '
+ 'left, right, or center')
+ self.checkInvalidParam(widget, 'justify', '',
+ errmsg='ambiguous justification "": must be '
+ 'left, right, or center')
+
+ def test_orient(self):
+ widget = self.create()
+ self.assertEqual(str(widget['orient']), self.default_orient)
+ self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical')
+
+ def test_padx(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m',
+ conv=self._conv_pad_pixels)
+
+ def test_pady(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m',
+ conv=self._conv_pad_pixels)
+
+ def test_relief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'relief')
+
+ def test_repeatdelay(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'repeatdelay', -500, 500)
+
+ def test_repeatinterval(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'repeatinterval', -500, 500)
+
+ def test_selectbackground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'selectbackground')
+
+ def test_selectborderwidth(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
+
+ def test_selectforeground(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'selectforeground')
+
+ def test_setgrid(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'setgrid')
+
+ def test_state(self):
+ widget = self.create()
+ self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal')
+
+ def test_takefocus(self):
+ widget = self.create()
+ self.checkParams(widget, 'takefocus', '0', '1', '')
+
+ def test_text(self):
+ widget = self.create()
+ self.checkParams(widget, 'text', '', 'any string')
+
+ def test_textvariable(self):
+ widget = self.create()
+ var = Tkinter.StringVar()
+ self.checkVariableParam(widget, 'textvariable', var)
+
+ def test_troughcolor(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'troughcolor')
+
+ def test_underline(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'underline', 0, 1, 10)
+
+ def test_wraplength(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'wraplength', 100)
+
+ def test_xscrollcommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'xscrollcommand')
+
+ def test_yscrollcommand(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'yscrollcommand')
+
+ # non-standard but common options
+
+ def test_command(self):
+ widget = self.create()
+ self.checkCommandParam(widget, 'command')
+
+ def test_indicatoron(self):
+ widget = self.create()
+ self.checkBooleanParam(widget, 'indicatoron')
+
+ def test_offrelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'offrelief')
+
+ def test_overrelief(self):
+ widget = self.create()
+ self.checkReliefParam(widget, 'overrelief')
+
+ def test_selectcolor(self):
+ widget = self.create()
+ self.checkColorParam(widget, 'selectcolor')
+
+ def test_selectimage(self):
+ widget = self.create()
+ self.checkImageParam(widget, 'selectimage')
+
+ @requires_tcl(8, 5)
+ def test_tristateimage(self):
+ widget = self.create()
+ self.checkImageParam(widget, 'tristateimage')
+
+ @requires_tcl(8, 5)
+ def test_tristatevalue(self):
+ widget = self.create()
+ self.checkParam(widget, 'tristatevalue', 'unknowable')
+
+ def test_variable(self):
+ widget = self.create()
+ var = Tkinter.DoubleVar()
+ self.checkVariableParam(widget, 'variable', var)
+
+
+class IntegerSizeTests(object):
+ def test_height(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'height', 100, -100, 0)
+
+ def test_width(self):
+ widget = self.create()
+ self.checkIntegerParam(widget, 'width', 402, -402, 0)
+
+
+class PixelSizeTests(object):
+ def test_height(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
+
+ def test_width(self):
+ widget = self.create()
+ self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i')
+
+
+def add_standard_options(*source_classes):
+ # This decorator adds test_xxx methods from source classes for every xxx
+ # option in the OPTIONS class attribute if they are not defined explicitly.
+ def decorator(cls):
+ for option in cls.OPTIONS:
+ methodname = 'test_' + option
+ if not hasattr(cls, methodname):
+ for source_class in source_classes:
+ if hasattr(source_class, methodname):
+ setattr(cls, methodname,
+ getattr(source_class, methodname).im_func)
+ break
+ else:
+ def test(self, option=option):
+ widget = self.create()
+ widget[option]
+ raise AssertionError('Option "%s" is not tested in %s' %
+ (option, cls.__name__))
+ test.__name__ = methodname
+ setattr(cls, methodname, test)
+ return cls
+ return decorator
+
+def setUpModule():
+ if test.test_support.verbose:
+ tcl = Tkinter.Tcl()
+ print 'patchlevel =', tcl.call('info', 'patchlevel')
diff -r 3a1db0d2747e Lib/lib-tk/ttk.py
--- a/Lib/lib-tk/ttk.py
+++ b/Lib/lib-tk/ttk.py
@@ -295,6 +295,9 @@
indx += 2
if opt == 'children':
+ if (Tkinter._default_root and
+ not Tkinter._default_root.wantobjects()):
+ val = Tkinter._default_root.splitlist(val)
val = _list_from_layouttuple(val)
opts[opt] = val
@@ -315,6 +318,8 @@
if len(options) % 2: # option specified without a value, return its value
return res
+ if Tkinter._default_root:
+ res = Tkinter._default_root.splitlist(res)
return _dict_from_tcltuple(res)
def _convert_stringval(value):
@@ -327,6 +332,14 @@
return value
+def _to_number(x):
+ if isinstance(x, str):
+ if '.' in x:
+ x = float(x)
+ else:
+ x = int(x)
+ return x
+
def tclobjs_to_py(adict):
"""Returns adict with its values converted from Tcl objects to Python
objects."""
@@ -397,8 +410,8 @@
or something else of your preference. A statespec is compound of
one or more states and then a value."""
if query_opt is not None:
- return _list_from_statespec(
- self.tk.call(self._name, "map", style, '-%s' % query_opt))
+ return _list_from_statespec(self.tk.splitlist(
+ self.tk.call(self._name, "map", style, '-%s' % query_opt)))
return _dict_from_tcltuple(
self.tk.call(self._name, "map", style, *(_format_mapdict(kw))))
@@ -455,8 +468,8 @@
lspec = "null" # could be any other word, but this may make sense
# when calling layout(style) later
- return _list_from_layouttuple(
- self.tk.call(self._name, "layout", style, lspec))
+ return _list_from_layouttuple(self.tk.splitlist(
+ self.tk.call(self._name, "layout", style, lspec)))
def element_create(self, elementname, etype, *args, **kw):
@@ -468,12 +481,12 @@
def element_names(self):
"""Returns the list of elements defined in the current theme."""
- return self.tk.call(self._name, "element", "names")
+ return self.tk.splitlist(self.tk.call(self._name, "element", "names"))
def element_options(self, elementname):
"""Return the list of elementname's options."""
- return self.tk.call(self._name, "element", "options", elementname)
+ return self.tk.splitlist(self.tk.call(self._name, "element", "options", elementname))
def theme_create(self, themename, parent=None, settings=None):
@@ -507,7 +520,7 @@
def theme_names(self):
"""Returns a list of all known themes."""
- return self.tk.call(self._name, "theme", "names")
+ return self.tk.splitlist(self.tk.call(self._name, "theme", "names"))
def theme_use(self, themename=None):
@@ -570,7 +583,8 @@
matches statespec and False otherwise. If callback is specified,
then it will be invoked with *args, **kw if the widget state
matches statespec. statespec is expected to be a sequence."""
- ret = self.tk.call(self._w, "instate", ' '.join(statespec))
+ ret = self.tk.getboolean(
+ self.tk.call(self._w, "instate", ' '.join(statespec)))
if ret and callback:
return callback(*args, **kw)
@@ -669,7 +683,7 @@
def bbox(self, index):
"""Return a tuple of (x, y, width, height) which describes the
bounding box of the character given by index."""
- return self.tk.call(self._w, "bbox", index)
+ return self._getints(self.tk.call(self._w, "bbox", index))
def identify(self, x, y):
@@ -682,7 +696,7 @@
"""Force revalidation, independent of the conditions specified
by the validate option. Returns False if validation fails, True
if it succeeds. Sets or clears the invalid state accordingly."""
- return bool(self.tk.call(self._w, "validate"))
+ return bool(self.tk.getboolean(self.tk.call(self._w, "validate")))
class Combobox(Entry):
@@ -709,6 +723,8 @@
element at position newindex in the list of values. Otherwise,
returns the index of the current value in the list of values
or -1 if the current value does not appear in the list."""
+ if newindex is None:
+ return self.tk.getint(self.tk.call(self._w, "current"))
return self.tk.call(self._w, "current", newindex)
@@ -863,7 +879,7 @@
def index(self, tab_id):
"""Returns the numeric index of the tab specified by tab_id, or
the total number of tabs if tab_id is the string "end"."""
- return self.tk.call(self._w, "index", tab_id)
+ return self.tk.getint(self.tk.call(self._w, "index", tab_id))
def insert(self, pos, child, **kw):
@@ -898,7 +914,7 @@
def tabs(self):
"""Returns a list of windows managed by the notebook."""
- return self.tk.call(self._w, "tabs") or ()
+ return self.tk.splitlist(self.tk.call(self._w, "tabs") or ())
def enable_traversal(self):
@@ -981,7 +997,7 @@
constrained to be between 0 and the total size of the widget.
Returns the new position of sash number index."""
- return self.tk.call(self._w, "sashpos", index, newpos)
+ return self.tk.getint(self.tk.call(self._w, "sashpos", index, newpos))
PanedWindow = Panedwindow # Tkinter name compatibility
@@ -1181,14 +1197,15 @@
If column is specified, returns the bounding box of that cell.
If the item is not visible (i.e., if it is a descendant of a
closed item or is scrolled offscreen), returns an empty string."""
- return self.tk.call(self._w, "bbox", item, column)
+ return self._getints(self.tk.call(self._w, "bbox", item, column)) or ''
def get_children(self, item=None):
"""Returns a tuple of children belonging to item.
If item is not specified, returns root children."""
- return self.tk.call(self._w, "children", item or '') or ()
+ return self.tk.splitlist(
+ self.tk.call(self._w, "children", item or '') or ())
def set_children(self, item, *newchildren):
@@ -1229,7 +1246,7 @@
def exists(self, item):
"""Returns True if the specified item is present in the tree,
False otherwise."""
- return bool(self.tk.call(self._w, "exists", item))
+ return bool(self.tk.getboolean(self.tk.call(self._w, "exists", item)))
def focus(self, item=None):
@@ -1311,7 +1328,7 @@
def index(self, item):
"""Returns the integer index of item within its parent's list
of children."""
- return self.tk.call(self._w, "index", item)
+ return self.tk.getint(self.tk.call(self._w, "index", item))
def insert(self, parent, index, iid=None, **kw):
@@ -1420,7 +1437,7 @@
value of given column in given item to the specified value."""
res = self.tk.call(self._w, "set", item, column, value)
if column is None and value is None:
- return _dict_from_tcltuple(res, False)
+ return _dict_from_tcltuple(self.tk.splitlist(res), False)
else:
return res
@@ -1451,7 +1468,8 @@
all items which have the specified tag.
* Availability: Tk 8.6"""
- return self.tk.call(self._w, "tag", "has", tagname, item)
+ return self.tk.getboolean(
+ self.tk.call(self._w, "tag", "has", tagname, item))
# Extensions
@@ -1523,7 +1541,8 @@
self.label.place_configure(x=x, y=y)
- from_, to = self.scale['from'], self.scale['to']
+ from_ = _to_number(self.scale['from'])
+ to = _to_number(self.scale['to'])
if to < from_:
from_, to = to, from_
newval = self._variable.get()
diff -r 3a1db0d2747e Lib/lib-tk/turtle.py
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -835,7 +835,7 @@
if isinstance(data, list):
data = tuple(data)
elif type_ == "image":
- if isinstance(data, str):
+ if isinstance(data, basestring):
if data.lower().endswith(".gif") and isfile(data):
data = TurtleScreen._image(data)
# else data assumed to be Photoimage
@@ -1098,7 +1098,7 @@
"""
if len(color) == 1:
color = color[0]
- if isinstance(color, str):
+ if isinstance(color, basestring):
if self._iscolorstring(color) or color == "":
return color
else:
@@ -2602,7 +2602,7 @@
def _cc(self, args):
"""Convert colortriples to hexstrings.
"""
- if isinstance(args, str):
+ if isinstance(args, basestring):
return args
try:
r, g, b = args
@@ -3228,7 +3228,7 @@
"""
#print "dot-1:", size, color
if not color:
- if isinstance(size, (str, tuple)):
+ if isinstance(size, (basestring, tuple)):
color = self._colorstr(size)
size = self._pensize + max(self._pensize, 4)
else:
@@ -3913,7 +3913,7 @@
down()
# some text
write("startstart", 1)
- write("start", 1)
+ write(u"start", 1)
color("red")
# staircase
for i in range(5):
@@ -3988,7 +3988,7 @@
tri = getturtle()
tri.resizemode("auto")
turtle = Turtle()
- turtle.resizemode("auto")
+ turtle.resizemode(u"auto")
turtle.shape("turtle")
turtle.reset()
turtle.left(90)
@@ -3998,7 +3998,7 @@
turtle.lt(30)
turtle.down()
turtle.speed(6)
- turtle.color("blue","orange")
+ turtle.color("blue",u"orange")
turtle.pensize(2)
tri.speed(6)
setheading(towards(turtle))
@@ -4013,9 +4013,9 @@
tri.stamp()
switchpen()
count += 1
- tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
+ tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align=u"right")
tri.pencolor("black")
- tri.pencolor("red")
+ tri.pencolor(u"red")
def baba(xdummy, ydummy):
clearscreen()
diff -r 3a1db0d2747e Lib/lib2to3/fixes/fix_import.py
--- a/Lib/lib2to3/fixes/fix_import.py
+++ b/Lib/lib2to3/fixes/fix_import.py
@@ -32,7 +32,7 @@
elif node.type == syms.dotted_as_names:
pending.extend(node.children[::-2])
else:
- raise AssertionError("unkown node type")
+ raise AssertionError("unknown node type")
class FixImport(fixer_base.BaseFix):
diff -r 3a1db0d2747e Lib/lib2to3/pgen2/tokenize.py
--- a/Lib/lib2to3/pgen2/tokenize.py
+++ b/Lib/lib2to3/pgen2/tokenize.py
@@ -252,7 +252,7 @@
def detect_encoding(readline):
"""
The detect_encoding() function is used to detect the encoding that should
- be used to decode a Python source file. It requires one argment, readline,
+ be used to decode a Python source file. It requires one argument, readline,
in the same way as the tokenize() generator.
It will call readline a maximum of twice, and return the encoding used
@@ -343,7 +343,7 @@
def generate_tokens(readline):
"""
- The generate_tokens() generator requires one argment, readline, which
+ The generate_tokens() generator requires one argument, readline, which
must be a callable object which provides the same interface as the
readline() method of built-in file objects. Each call to the function
should return one line of input as a string. Alternately, readline
diff -r 3a1db0d2747e Lib/lib2to3/tests/test_fixers.py
--- a/Lib/lib2to3/tests/test_fixers.py
+++ b/Lib/lib2to3/tests/test_fixers.py
@@ -41,7 +41,7 @@
def warns(self, before, after, message, unchanged=False):
tree = self._check(before, after)
- self.assertTrue(message in "".join(self.fixer_log))
+ self.assertIn(message, "".join(self.fixer_log))
if not unchanged:
self.assertTrue(tree.was_changed)
diff -r 3a1db0d2747e Lib/lib2to3/tests/test_main.py
--- a/Lib/lib2to3/tests/test_main.py
+++ b/Lib/lib2to3/tests/test_main.py
@@ -59,9 +59,9 @@
ret = self.run_2to3_capture(["-"], input_stream, out_enc, err)
self.assertEqual(ret, 0)
output = out.getvalue()
- self.assertTrue("-print 'nothing'" in output)
- self.assertTrue("WARNING: couldn't encode <stdin>'s diff for "
- "your terminal" in err.getvalue())
+ self.assertIn("-print 'nothing'", output)
+ self.assertIn("WARNING: couldn't encode <stdin>'s diff for "
+ "your terminal", err.getvalue())
def setup_test_source_trees(self):
"""Setup a test source tree and output destination tree."""
diff -r 3a1db0d2747e Lib/lib2to3/tests/test_parser.py
--- a/Lib/lib2to3/tests/test_parser.py
+++ b/Lib/lib2to3/tests/test_parser.py
@@ -165,8 +165,8 @@
for filepath in support.all_project_files():
with open(filepath, "rb") as fp:
encoding = tokenize.detect_encoding(fp.readline)[0]
- self.assertTrue(encoding is not None,
- "can't detect encoding for %s" % filepath)
+ self.assertIsNotNone(encoding,
+ "can't detect encoding for %s" % filepath)
with open(filepath, "r") as fp:
source = fp.read()
source = source.decode(encoding)
diff -r 3a1db0d2747e Lib/lib2to3/tests/test_pytree.py
--- a/Lib/lib2to3/tests/test_pytree.py
+++ b/Lib/lib2to3/tests/test_pytree.py
@@ -160,12 +160,12 @@
l3 = pytree.Leaf(100, "bar")
n1 = pytree.Node(1000, [l1, l2, l3])
self.assertEqual(n1.children, [l1, l2, l3])
- self.assertTrue(isinstance(n1.children, list))
+ self.assertIsInstance(n1.children, list)
self.assertFalse(n1.was_changed)
l2new = pytree.Leaf(100, "-")
l2.replace(l2new)
self.assertEqual(n1.children, [l1, l2new, l3])
- self.assertTrue(isinstance(n1.children, list))
+ self.assertIsInstance(n1.children, list)
self.assertTrue(n1.was_changed)
def test_replace_with_list(self):
@@ -176,7 +176,7 @@
l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")])
self.assertEqual(str(n1), "foo**bar")
- self.assertTrue(isinstance(n1.children, list))
+ self.assertIsInstance(n1.children, list)
def test_leaves(self):
l1 = pytree.Leaf(100, "foo")
@@ -347,7 +347,7 @@
n2 = pytree.Node(1000, [])
p1 = pytree.Node(1000, [n1, n2])
- self.assertTrue(n1.next_sibling is n2)
+ self.assertIs(n1.next_sibling, n2)
self.assertEqual(n2.next_sibling, None)
self.assertEqual(p1.next_sibling, None)
@@ -356,7 +356,7 @@
l2 = pytree.Leaf(100, "b")
p1 = pytree.Node(1000, [l1, l2])
- self.assertTrue(l1.next_sibling is l2)
+ self.assertIs(l1.next_sibling, l2)
self.assertEqual(l2.next_sibling, None)
self.assertEqual(p1.next_sibling, None)
@@ -365,7 +365,7 @@
n2 = pytree.Node(1000, [])
p1 = pytree.Node(1000, [n1, n2])
- self.assertTrue(n2.prev_sibling is n1)
+ self.assertIs(n2.prev_sibling, n1)
self.assertEqual(n1.prev_sibling, None)
self.assertEqual(p1.prev_sibling, None)
@@ -374,7 +374,7 @@
l2 = pytree.Leaf(100, "b")
p1 = pytree.Node(1000, [l1, l2])
- self.assertTrue(l2.prev_sibling is l1)
+ self.assertIs(l2.prev_sibling, l1)
self.assertEqual(l1.prev_sibling, None)
self.assertEqual(p1.prev_sibling, None)
@@ -447,7 +447,7 @@
r = {}
self.assertTrue(pw.match_seq([l1, l3], r))
self.assertEqual(r, {"pl": l3, "pw": [l1, l3]})
- self.assertTrue(r["pl"] is l3)
+ self.assertIs(r["pl"], l3)
r = {}
def test_generate_matches(self):
diff -r 3a1db0d2747e Lib/lib2to3/tests/test_refactor.py
--- a/Lib/lib2to3/tests/test_refactor.py
+++ b/Lib/lib2to3/tests/test_refactor.py
@@ -49,9 +49,9 @@
def test_print_function_option(self):
rt = self.rt({"print_function" : True})
- self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement)
- self.assertTrue(rt.driver.grammar is
- pygram.python_grammar_no_print_statement)
+ self.assertIs(rt.grammar, pygram.python_grammar_no_print_statement)
+ self.assertIs(rt.driver.grammar,
+ pygram.python_grammar_no_print_statement)
def test_write_unchanged_files_option(self):
rt = self.rt()
diff -r 3a1db0d2747e Lib/locale.py
--- a/Lib/locale.py
+++ b/Lib/locale.py
@@ -344,6 +344,22 @@
for x in range(256)
)
+def _replace_encoding(code, encoding):
+ if '.' in code:
+ langname = code[:code.index('.')]
+ else:
+ langname = code
+ # Convert the encoding to a C lib compatible encoding string
+ norm_encoding = encodings.normalize_encoding(encoding)
+ #print('norm encoding: %r' % norm_encoding)
+ norm_encoding = encodings.aliases.aliases.get(norm_encoding,
+ norm_encoding)
+ #print('aliased encoding: %r' % norm_encoding)
+ encoding = locale_encoding_alias.get(norm_encoding,
+ norm_encoding)
+ #print('found encoding %r' % encoding)
+ return langname + '.' + encoding
+
def normalize(localename):
""" Returns a normalized locale code for the given locale
@@ -360,57 +376,73 @@
does.
"""
- # Normalize the locale name and extract the encoding
+ # Normalize the locale name and extract the encoding and modifier
if isinstance(localename, _unicode):
localename = localename.encode('ascii')
- fullname = localename.translate(_ascii_lower_map)
- if ':' in fullname:
+ code = localename.translate(_ascii_lower_map)
+ if ':' in code:
# ':' is sometimes used as encoding delimiter.
- fullname = fullname.replace(':', '.')
- if '.' in fullname:
- langname, encoding = fullname.split('.')[:2]
- fullname = langname + '.' + encoding
+ code = code.replace(':', '.')
+ if '@' in code:
+ code, modifier = code.split('@', 1)
else:
- langname = fullname
+ modifier = ''
+ if '.' in code:
+ langname, encoding = code.split('.')[:2]
+ else:
+ langname = code
encoding = ''
- # First lookup: fullname (possibly with encoding)
- norm_encoding = encoding.replace('-', '')
- norm_encoding = norm_encoding.replace('_', '')
- lookup_name = langname + '.' + encoding
+ # First lookup: fullname (possibly with encoding and modifier)
+ lang_enc = langname
+ if encoding:
+ norm_encoding = encoding.replace('-', '')
+ norm_encoding = norm_encoding.replace('_', '')
+ lang_enc += '.' + norm_encoding
+ lookup_name = lang_enc
+ if modifier:
+ lookup_name += '@' + modifier
code = locale_alias.get(lookup_name, None)
if code is not None:
return code
- #print 'first lookup failed'
+ #print('first lookup failed')
- # Second try: langname (without encoding)
- code = locale_alias.get(langname, None)
- if code is not None:
- #print 'langname lookup succeeded'
- if '.' in code:
- langname, defenc = code.split('.')
- else:
- langname = code
- defenc = ''
- if encoding:
- # Convert the encoding to a C lib compatible encoding string
- norm_encoding = encodings.normalize_encoding(encoding)
- #print 'norm encoding: %r' % norm_encoding
- norm_encoding = encodings.aliases.aliases.get(norm_encoding,
- norm_encoding)
- #print 'aliased encoding: %r' % norm_encoding
- encoding = locale_encoding_alias.get(norm_encoding,
- norm_encoding)
- else:
- encoding = defenc
- #print 'found encoding %r' % encoding
- if encoding:
- return langname + '.' + encoding
- else:
- return langname
+ if modifier:
+ # Second try: fullname without modifier (possibly with encoding)
+ code = locale_alias.get(lang_enc, None)
+ if code is not None:
+ #print('lookup without modifier succeeded')
+ if '@' not in code:
+ return code + '@' + modifier
+ if code.split('@', 1)[1].translate(_ascii_lower_map) == modifier:
+ return code
+ #print('second lookup failed')
- else:
- return localename
+ if encoding:
+ # Third try: langname (without encoding, possibly with modifier)
+ lookup_name = langname
+ if modifier:
+ lookup_name += '@' + modifier
+ code = locale_alias.get(lookup_name, None)
+ if code is not None:
+ #print('lookup without encoding succeeded')
+ if '@' not in code:
+ return _replace_encoding(code, encoding)
+ code, modifier = code.split('@', 1)
+ return _replace_encoding(code, encoding) + '@' + modifier
+
+ if modifier:
+ # Fourth try: langname (without encoding and modifier)
+ code = locale_alias.get(langname, None)
+ if code is not None:
+ #print('lookup without modifier and encoding succeeded')
+ if '@' not in code:
+ return _replace_encoding(code, encoding) + '@' + modifier
+ code, defmod = code.split('@', 1)
+ if defmod.translate(_ascii_lower_map) == modifier:
+ return _replace_encoding(code, encoding) + '@' + defmod
+
+ return localename
def _parse_localename(localename):
@@ -429,7 +461,7 @@
code = normalize(localename)
if '@' in code:
# Deal with locale modifiers
- code, modifier = code.split('@')
+ code, modifier = code.split('@', 1)
if modifier == 'euro' and '.' not in code:
# Assume Latin-9 for @euro locales. This is bogus,
# since some systems may use other encodings for these
@@ -734,11 +766,30 @@
# updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8'
# updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8'
#
+# SS 2013-12-20:
+# Updated alias mapping to most recent locale.alias file
+# from X.org distribution using makelocalealias.py.
+#
+# These are the differences compared to the old mapping (Python 2.7.6
+# and older):
+#
+# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C'
+# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C'
+# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C'
+# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2'
+# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
+# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
+# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8'
+# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin'
+# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8'
+# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin'
+# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin'
locale_alias = {
- 'a3': 'a3_AZ.KOI8-C',
- 'a3_az': 'a3_AZ.KOI8-C',
- 'a3_az.koi8c': 'a3_AZ.KOI8-C',
+ 'a3': 'az_AZ.KOI8-C',
+ 'a3_az': 'az_AZ.KOI8-C',
+ 'a3_az.koi8c': 'az_AZ.KOI8-C',
+ 'a3_az.koic': 'az_AZ.KOI8-C',
'af': 'af_ZA.ISO8859-1',
'af_za': 'af_ZA.ISO8859-1',
'af_za.iso88591': 'af_ZA.ISO8859-1',
@@ -757,6 +808,7 @@
'ar_dz.iso88596': 'ar_DZ.ISO8859-6',
'ar_eg': 'ar_EG.ISO8859-6',
'ar_eg.iso88596': 'ar_EG.ISO8859-6',
+ 'ar_in': 'ar_IN.UTF-8',
'ar_iq': 'ar_IQ.ISO8859-6',
'ar_iq.iso88596': 'ar_IQ.ISO8859-6',
'ar_jo': 'ar_JO.ISO8859-6',
@@ -786,6 +838,7 @@
'arabic': 'ar_AA.ISO8859-6',
'arabic.iso88596': 'ar_AA.ISO8859-6',
'as': 'as_IN.UTF-8',
+ 'as_in': 'as_IN.UTF-8',
'az': 'az_AZ.ISO8859-9E',
'az_az': 'az_AZ.ISO8859-9E',
'az_az.iso88599e': 'az_AZ.ISO8859-9E',
@@ -803,6 +856,7 @@
'bg_bg.koi8r': 'bg_BG.KOI8-R',
'bg_bg.microsoftcp1251': 'bg_BG.CP1251',
'bn_in': 'bn_IN.UTF-8',
+ 'bo_in': 'bo_IN.UTF-8',
'bokmal': 'nb_NO.ISO8859-1',
'bokm\xe5l': 'nb_NO.ISO8859-1',
'br': 'br_FR.ISO8859-1',
@@ -820,6 +874,7 @@
'c': 'C',
'c-french': 'fr_CA.ISO8859-1',
'c-french.iso88591': 'fr_CA.ISO8859-1',
+ 'c.ascii': 'C',
'c.en': 'C',
'c.iso88591': 'en_US.ISO8859-1',
'c_c': 'C',
@@ -857,7 +912,7 @@
'croatian': 'hr_HR.ISO8859-2',
'cs': 'cs_CZ.ISO8859-2',
'cs_cs': 'cs_CZ.ISO8859-2',
- 'cs_cs.iso88592': 'cs_CS.ISO8859-2',
+ 'cs_cs.iso88592': 'cs_CZ.ISO8859-2',
'cs_cz': 'cs_CZ.ISO8859-2',
'cs_cz.iso88592': 'cs_CZ.ISO8859-2',
'cy': 'cy_GB.ISO8859-1',
@@ -1161,12 +1216,13 @@
'he_il.cp1255': 'he_IL.CP1255',
'he_il.iso88598': 'he_IL.ISO8859-8',
'he_il.microsoftcp1255': 'he_IL.CP1255',
- 'hebrew': 'iw_IL.ISO8859-8',
- 'hebrew.iso88598': 'iw_IL.ISO8859-8',
+ 'hebrew': 'he_IL.ISO8859-8',
+ 'hebrew.iso88598': 'he_IL.ISO8859-8',
'hi': 'hi_IN.ISCII-DEV',
'hi_in': 'hi_IN.ISCII-DEV',
'hi_in.isciidev': 'hi_IN.ISCII-DEV',
'hne': 'hne_IN.UTF-8',
+ 'hne_in': 'hne_IN.UTF-8',
'hr': 'hr_HR.ISO8859-2',
'hr_hr': 'hr_HR.ISO8859-2',
'hr_hr.iso88592': 'hr_HR.ISO8859-2',
@@ -1254,7 +1310,8 @@
'korean': 'ko_KR.eucKR',
'korean.euc': 'ko_KR.eucKR',
'ks': 'ks_IN.UTF-8',
- 'ks_in@devanagari': 'ks_IN@devanagari.UTF-8',
+ 'ks_in': 'ks_IN.UTF-8',
+ 'ks_in@devanagari': 'ks_IN.UTF-8@devanagari',
'kw': 'kw_GB.ISO8859-1',
'kw_gb': 'kw_GB.ISO8859-1',
'kw_gb.iso88591': 'kw_GB.ISO8859-1',
@@ -1278,6 +1335,7 @@
'lv_lv.iso885913': 'lv_LV.ISO8859-13',
'lv_lv.iso88594': 'lv_LV.ISO8859-4',
'mai': 'mai_IN.UTF-8',
+ 'mai_in': 'mai_IN.UTF-8',
'mi': 'mi_NZ.ISO8859-1',
'mi_nz': 'mi_NZ.ISO8859-1',
'mi_nz.iso88591': 'mi_NZ.ISO8859-1',
@@ -1287,6 +1345,7 @@
'mk_mk.iso88595': 'mk_MK.ISO8859-5',
'mk_mk.microsoftcp1251': 'mk_MK.CP1251',
'ml': 'ml_IN.UTF-8',
+ 'ml_in': 'ml_IN.UTF-8',
'mr': 'mr_IN.UTF-8',
'mr_in': 'mr_IN.UTF-8',
'ms': 'ms_MY.ISO8859-1',
@@ -1301,6 +1360,7 @@
'nb_no.iso88591': 'nb_NO.ISO8859-1',
'nb_no.iso885915': 'nb_NO.ISO8859-15',
'nb_no@euro': 'nb_NO.ISO8859-15',
+ 'ne_np': 'ne_NP.UTF-8',
'nl': 'nl_NL.ISO8859-1',
'nl.iso885915': 'nl_NL.ISO8859-15',
'nl_be': 'nl_BE.ISO8859-1',
@@ -1353,6 +1413,7 @@
'oc_fr.iso885915': 'oc_FR.ISO8859-15',
'oc_fr@euro': 'oc_FR.ISO8859-15',
'or': 'or_IN.UTF-8',
+ 'or_in': 'or_IN.UTF-8',
'pa': 'pa_IN.UTF-8',
'pa_in': 'pa_IN.UTF-8',
'pd': 'pd_US.ISO8859-1',
@@ -1414,7 +1475,10 @@
'rw': 'rw_RW.ISO8859-1',
'rw_rw': 'rw_RW.ISO8859-1',
'rw_rw.iso88591': 'rw_RW.ISO8859-1',
- 'sd': 'sd_IN@devanagari.UTF-8',
+ 'sd': 'sd_IN.UTF-8',
+ 'sd@devanagari': 'sd_IN.UTF-8@devanagari',
+ 'sd_in': 'sd_IN.UTF-8',
+ 'sd_in@devanagari': 'sd_IN.UTF-8@devanagari',
'se_no': 'se_NO.UTF-8',
'serbocroatian': 'sr_RS.UTF-8@latin',
'sh': 'sr_RS.UTF-8@latin',
@@ -1448,13 +1512,13 @@
'sr': 'sr_RS.UTF-8',
'sr@cyrillic': 'sr_RS.UTF-8',
'sr@latin': 'sr_RS.UTF-8@latin',
- 'sr@latn': 'sr_RS.UTF-8@latin',
- 'sr_cs': 'sr_RS.UTF-8',
+ 'sr@latn': 'sr_CS.UTF-8@latin',
+ 'sr_cs': 'sr_CS.UTF-8',
'sr_cs.iso88592': 'sr_CS.ISO8859-2',
'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2',
'sr_cs.iso88595': 'sr_CS.ISO8859-5',
- 'sr_cs.utf8@latn': 'sr_RS.UTF-8@latin',
- 'sr_cs@latn': 'sr_RS.UTF-8@latin',
+ 'sr_cs.utf8@latn': 'sr_CS.UTF-8@latin',
+ 'sr_cs@latn': 'sr_CS.UTF-8@latin',
'sr_me': 'sr_ME.UTF-8',
'sr_rs': 'sr_RS.UTF-8',
'sr_rs.utf8@latn': 'sr_RS.UTF-8@latin',
@@ -1532,6 +1596,7 @@
'universal': 'en_US.utf',
'universal.utf8@ucs4': 'en_US.UTF-8',
'ur': 'ur_PK.CP1256',
+ 'ur_in': 'ur_IN.UTF-8',
'ur_pk': 'ur_PK.CP1256',
'ur_pk.cp1256': 'ur_PK.CP1256',
'ur_pk.microsoftcp1256': 'ur_PK.CP1256',
diff -r 3a1db0d2747e Lib/logging/__init__.py
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -912,8 +912,10 @@
self.flush()
if hasattr(self.stream, "close"):
self.stream.close()
- StreamHandler.close(self)
self.stream = None
+ # Issue #19523: call unconditionally to
+ # prevent a handler leak when delay is set
+ StreamHandler.close(self)
finally:
self.release()
diff -r 3a1db0d2747e Lib/logging/config.py
--- a/Lib/logging/config.py
+++ b/Lib/logging/config.py
@@ -1,4 +1,4 @@
-# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2014 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
@@ -19,13 +19,23 @@
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
by Apache's log4j system.
-Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging' and log away!
"""
-import sys, logging, logging.handlers, socket, struct, os, traceback, re
-import types, cStringIO
+import cStringIO
+import errno
+import io
+import logging
+import logging.handlers
+import os
+import re
+import socket
+import struct
+import sys
+import traceback
+import types
try:
import thread
@@ -38,10 +48,7 @@
DEFAULT_LOGGING_CONFIG_PORT = 9030
-if sys.platform == "win32":
- RESET_ERROR = 10054 #WSAECONNRESET
-else:
- RESET_ERROR = 104 #ECONNRESET
+RESET_ERROR = errno.ECONNRESET
#
# The following code implements a socket listener for on-the-fly
@@ -275,6 +282,30 @@
return True
+class ConvertingMixin(object):
+ """For ConvertingXXX's, this mixin class provides common functions"""
+
+ def convert_with_key(self, key, value, replace=True):
+ result = self.configurator.convert(value)
+ #If the converted value is different, save for next time
+ if value is not result:
+ if replace:
+ self[key] = result
+ if type(result) in (ConvertingDict, ConvertingList,
+ ConvertingTuple):
+ result.parent = self
+ result.key = key
+ return result
+
+ def convert(self, value):
+ result = self.configurator.convert(value)
+ if value is not result:
+ if type(result) in (ConvertingDict, ConvertingList,
+ ConvertingTuple):
+ result.parent = self
+ return result
+
+
# The ConvertingXXX classes are wrappers around standard Python containers,
# and they serve to convert any suitable values in the container. The
# conversion converts base dicts, lists and tuples to their wrapped
@@ -284,77 +315,37 @@
# Each wrapper should have a configurator attribute holding the actual
# configurator to use for conversion.
-class ConvertingDict(dict):
+class ConvertingDict(dict, ConvertingMixin):
"""A converting dictionary wrapper."""
def __getitem__(self, key):
value = dict.__getitem__(self, key)
- result = self.configurator.convert(value)
- #If the converted value is different, save for next time
- if value is not result:
- self[key] = result
- if type(result) in (ConvertingDict, ConvertingList,
- ConvertingTuple):
- result.parent = self
- result.key = key
- return result
+ return self.convert_with_key(key, value)
def get(self, key, default=None):
value = dict.get(self, key, default)
- result = self.configurator.convert(value)
- #If the converted value is different, save for next time
- if value is not result:
- self[key] = result
- if type(result) in (ConvertingDict, ConvertingList,
- ConvertingTuple):
- result.parent = self
- result.key = key
- return result
+ return self.convert_with_key(key, value)
def pop(self, key, default=None):
value = dict.pop(self, key, default)
- result = self.configurator.convert(value)
- if value is not result:
- if type(result) in (ConvertingDict, ConvertingList,
- ConvertingTuple):
- result.parent = self
- result.key = key
- return result
+ return self.convert_with_key(key, value, replace=False)
-class ConvertingList(list):
+class ConvertingList(list, ConvertingMixin):
"""A converting list wrapper."""
def __getitem__(self, key):
value = list.__getitem__(self, key)
- result = self.configurator.convert(value)
- #If the converted value is different, save for next time
- if value is not result:
- self[key] = result
- if type(result) in (ConvertingDict, ConvertingList,
- ConvertingTuple):
- result.parent = self
- result.key = key
- return result
+ return self.convert_with_key(key, value)
def pop(self, idx=-1):
value = list.pop(self, idx)
- result = self.configurator.convert(value)
- if value is not result:
- if type(result) in (ConvertingDict, ConvertingList,
- ConvertingTuple):
- result.parent = self
- return result
+ return self.convert(value)
-class ConvertingTuple(tuple):
+class ConvertingTuple(tuple, ConvertingMixin):
"""A converting tuple wrapper."""
def __getitem__(self, key):
value = tuple.__getitem__(self, key)
- result = self.configurator.convert(value)
- if value is not result:
- if type(result) in (ConvertingDict, ConvertingList,
- ConvertingTuple):
- result.parent = self
- result.key = key
- return result
+ # Can't replace a tuple entry.
+ return self.convert_with_key(key, value, replace=False)
class BaseConfigurator(object):
"""
@@ -526,21 +517,21 @@
level = handler_config.get('level', None)
if level:
handler.setLevel(logging._checkLevel(level))
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure handler '
'%r: %s' % (name, e))
loggers = config.get('loggers', EMPTY_DICT)
for name in loggers:
try:
self.configure_logger(name, loggers[name], True)
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure logger '
'%r: %s' % (name, e))
root = config.get('root', None)
if root:
try:
self.configure_root(root, True)
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure root '
'logger: %s' % e)
else:
@@ -555,7 +546,7 @@
try:
formatters[name] = self.configure_formatter(
formatters[name])
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure '
'formatter %r: %s' % (name, e))
# Next, do filters - they don't refer to anything else, either
@@ -563,7 +554,7 @@
for name in filters:
try:
filters[name] = self.configure_filter(filters[name])
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure '
'filter %r: %s' % (name, e))
@@ -577,7 +568,7 @@
handler = self.configure_handler(handlers[name])
handler.name = name
handlers[name] = handler
- except StandardError, e:
+ except StandardError as e:
if 'target not configured yet' in str(e):
deferred.append(name)
else:
@@ -590,7 +581,7 @@
handler = self.configure_handler(handlers[name])
handler.name = name
handlers[name] = handler
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure handler '
'%r: %s' % (name, e))
@@ -631,7 +622,7 @@
existing.remove(name)
try:
self.configure_logger(name, loggers[name])
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure logger '
'%r: %s' % (name, e))
@@ -654,7 +645,7 @@
if root:
try:
self.configure_root(root)
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to configure root '
'logger: %s' % e)
finally:
@@ -666,7 +657,7 @@
factory = config['()'] # for use in exception handler
try:
result = self.configure_custom(config)
- except TypeError, te:
+ except TypeError as te:
if "'format'" not in str(te):
raise
#Name of parameter changed from fmt to format.
@@ -696,7 +687,7 @@
for f in filters:
try:
filterer.addFilter(self.config['filters'][f])
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to add filter %r: %s' % (f, e))
def configure_handler(self, config):
@@ -705,7 +696,7 @@
if formatter:
try:
formatter = self.config['formatters'][formatter]
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to set formatter '
'%r: %s' % (formatter, e))
level = config.pop('level', None)
@@ -727,7 +718,7 @@
config['class'] = cname # restore for deferred configuration
raise StandardError('target not configured yet')
config['target'] = th
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to set target handler '
'%r: %s' % (config['target'], e))
elif issubclass(klass, logging.handlers.SMTPHandler) and\
@@ -740,7 +731,7 @@
kwargs = dict([(k, config[k]) for k in config if valid_ident(k)])
try:
result = factory(**kwargs)
- except TypeError, te:
+ except TypeError as te:
if "'stream'" not in str(te):
raise
#The argument name changed from strm to stream
@@ -762,7 +753,7 @@
for h in handlers:
try:
logger.addHandler(self.config['handlers'][h])
- except StandardError, e:
+ except StandardError as e:
raise ValueError('Unable to add handler %r: %s' % (h, e))
def common_logger_config(self, logger, config, incremental=False):
@@ -857,13 +848,9 @@
traceback.print_exc()
if self.server.ready:
self.server.ready.set()
- except socket.error, e:
- if not isinstance(e.args, tuple):
+ except socket.error as e:
+ if e.errno != RESET_ERROR:
raise
- else:
- errcode = e.args[0]
- if errcode != RESET_ERROR:
- raise
class ConfigSocketReceiver(ThreadingTCPServer):
"""
diff -r 3a1db0d2747e Lib/mailbox.py
--- a/Lib/mailbox.py
+++ b/Lib/mailbox.py
@@ -1,5 +1,3 @@
-#! /usr/bin/env python
-
"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes."""
# Notes for authors of new mailbox subclasses:
diff -r 3a1db0d2747e Lib/mailcap.py
--- a/Lib/mailcap.py
+++ b/Lib/mailcap.py
@@ -22,8 +22,8 @@
fp = open(mailcap, 'r')
except IOError:
continue
- morecaps = readmailcapfile(fp)
- fp.close()
+ with fp:
+ morecaps = readmailcapfile(fp)
for key, value in morecaps.iteritems():
if not key in caps:
caps[key] = value
diff -r 3a1db0d2747e Lib/mimetypes.py
--- a/Lib/mimetypes.py
+++ b/Lib/mimetypes.py
@@ -373,9 +373,10 @@
f = open(file)
except IOError:
return None
- db = MimeTypes()
- db.readfp(f, True)
- return db.types_map[True]
+ with f:
+ db = MimeTypes()
+ db.readfp(f, True)
+ return db.types_map[True]
def _default_mime_types():
diff -r 3a1db0d2747e Lib/multiprocessing/pool.py
--- a/Lib/multiprocessing/pool.py
+++ b/Lib/multiprocessing/pool.py
@@ -169,7 +169,8 @@
self._task_handler = threading.Thread(
target=Pool._handle_tasks,
- args=(self._taskqueue, self._quick_put, self._outqueue, self._pool)
+ args=(self._taskqueue, self._quick_put, self._outqueue,
+ self._pool, self._cache)
)
self._task_handler.daemon = True
self._task_handler._state = RUN
@@ -329,7 +330,7 @@
debug('worker handler exiting')
@staticmethod
- def _handle_tasks(taskqueue, put, outqueue, pool):
+ def _handle_tasks(taskqueue, put, outqueue, pool, cache):
thread = threading.current_thread()
for taskseq, set_length in iter(taskqueue.get, None):
@@ -340,9 +341,12 @@
break
try:
put(task)
- except IOError:
- debug('could not put task on queue')
- break
+ except Exception as e:
+ job, ind = task[:2]
+ try:
+ cache[job]._set(ind, (False, e))
+ except KeyError:
+ pass
else:
if set_length:
debug('doing set_length()')
diff -r 3a1db0d2747e Lib/multiprocessing/process.py
--- a/Lib/multiprocessing/process.py
+++ b/Lib/multiprocessing/process.py
@@ -267,7 +267,7 @@
else:
sys.stderr.write(str(e.args[0]) + '\n')
sys.stderr.flush()
- exitcode = 0 if isinstance(e.args[0], str) else 1
+ exitcode = 1
except:
exitcode = 1
import traceback
diff -r 3a1db0d2747e Lib/multiprocessing/util.py
--- a/Lib/multiprocessing/util.py
+++ b/Lib/multiprocessing/util.py
@@ -32,6 +32,7 @@
# SUCH DAMAGE.
#
+import os
import itertools
import weakref
import atexit
@@ -184,6 +185,7 @@
self._args = args
self._kwargs = kwargs or {}
self._key = (exitpriority, _finalizer_counter.next())
+ self._pid = os.getpid()
_finalizer_registry[self._key] = self
@@ -196,9 +198,13 @@
except KeyError:
sub_debug('finalizer no longer registered')
else:
- sub_debug('finalizer calling %s with args %s and kwargs %s',
- self._callback, self._args, self._kwargs)
- res = self._callback(*self._args, **self._kwargs)
+ if self._pid != os.getpid():
+ sub_debug('finalizer ignored because different process')
+ res = None
+ else:
+ sub_debug('finalizer calling %s with args %s and kwargs %s',
+ self._callback, self._args, self._kwargs)
+ res = self._callback(*self._args, **self._kwargs)
self._weakref = self._callback = self._args = \
self._kwargs = self._key = None
return res
diff -r 3a1db0d2747e Lib/ntpath.py
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -59,61 +59,30 @@
# Join two (or more) paths.
-
-def join(a, *p):
- """Join two or more pathname components, inserting "\\" as needed.
- If any component is an absolute path, all previous path components
- will be discarded."""
- path = a
- for b in p:
- b_wins = 0 # set to 1 iff b makes path irrelevant
- if path == "":
- b_wins = 1
-
- elif isabs(b):
- # This probably wipes out path so far. However, it's more
- # complicated if path begins with a drive letter:
- # 1. join('c:', '/a') == 'c:/a'
- # 2. join('c:/', '/a') == 'c:/a'
- # But
- # 3. join('c:/a', '/b') == '/b'
- # 4. join('c:', 'd:/') = 'd:/'
- # 5. join('c:/', 'd:/') = 'd:/'
- if path[1:2] != ":" or b[1:2] == ":":
- # Path doesn't start with a drive letter, or cases 4 and 5.
- b_wins = 1
-
- # Else path has a drive letter, and b doesn't but is absolute.
- elif len(path) > 3 or (len(path) == 3 and
- path[-1] not in "/\\"):
- # case 3
- b_wins = 1
-
- if b_wins:
- path = b
- else:
- # Join, and ensure there's a separator.
- assert len(path) > 0
- if path[-1] in "/\\":
- if b and b[0] in "/\\":
- path += b[1:]
- else:
- path += b
- elif path[-1] == ":":
- path += b
- elif b:
- if b[0] in "/\\":
- path += b
- else:
- path += "\\" + b
- else:
- # path is not empty and does not end with a backslash,
- # but b is empty; since, e.g., split('a/') produces
- # ('a', ''), it's best if join() adds a backslash in
- # this case.
- path += '\\'
-
- return path
+def join(path, *paths):
+ """Join two or more pathname components, inserting "\\" as needed."""
+ result_drive, result_path = splitdrive(path)
+ for p in paths:
+ p_drive, p_path = splitdrive(p)
+ if p_path and p_path[0] in '\\/':
+ # Second path is absolute
+ if p_drive or not result_drive:
+ result_drive = p_drive
+ result_path = p_path
+ continue
+ elif p_drive and p_drive != result_drive:
+ if p_drive.lower() != result_drive.lower():
+ # Different drives => ignore the first path entirely
+ result_drive = p_drive
+ result_path = p_path
+ continue
+ # Same drive in different case
+ result_drive = p_drive
+ # Second path is relative to the first
+ if result_path and result_path[-1] not in '\\/':
+ result_path = result_path + '\\'
+ result_path = result_path + p_path
+ return result_drive + result_path
# Split a path in a drive specification (a drive letter followed by a
@@ -144,15 +113,18 @@
# vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
# \\machine\mountpoint\directories...
# directory ^^^^^^^^^^^^^^^
- normp = normcase(p)
- index = normp.find('\\', 2)
- if index == -1:
- ##raise RuntimeError, 'illegal UNC path: "' + p + '"'
- return ("", p)
- index = normp.find('\\', index + 1)
- if index == -1:
- index = len(p)
- return p[:index], p[index:]
+ normp = p.replace('\\', '/')
+ index = normp.find('/', 2)
+ if index <= 2:
+ return '', p
+ index2 = normp.find('/', index + 1)
+ # a UNC path can't have two slashes in a row
+ # (after the initial two)
+ if index2 == index + 1:
+ return '', p
+ if index2 == -1:
+ index2 = len(p)
+ return p[:index2], p[index2:]
return '', p
@@ -322,6 +294,13 @@
return path
import string
varchars = string.ascii_letters + string.digits + '_-'
+ if isinstance(path, unicode):
+ encoding = sys.getfilesystemencoding()
+ def getenv(var):
+ return os.environ[var.encode(encoding)].decode(encoding)
+ else:
+ def getenv(var):
+ return os.environ[var]
res = ''
index = 0
pathlen = len(path)
@@ -350,9 +329,9 @@
index = pathlen - 1
else:
var = path[:index]
- if var in os.environ:
- res = res + os.environ[var]
- else:
+ try:
+ res = res + getenv(var)
+ except KeyError:
res = res + '%' + var + '%'
elif c == '$': # variable or '$$'
if path[index + 1:index + 2] == '$':
@@ -364,9 +343,9 @@
try:
index = path.index('}')
var = path[:index]
- if var in os.environ:
- res = res + os.environ[var]
- else:
+ try:
+ res = res + getenv(var)
+ except KeyError:
res = res + '${' + var + '}'
except ValueError:
res = res + '${' + path
@@ -379,9 +358,9 @@
var = var + c
index = index + 1
c = path[index:index + 1]
- if var in os.environ:
- res = res + os.environ[var]
- else:
+ try:
+ res = res + getenv(var)
+ except KeyError:
res = res + '$' + var
if c != '':
index = index - 1
diff -r 3a1db0d2747e Lib/optparse.py
--- a/Lib/optparse.py
+++ b/Lib/optparse.py
@@ -204,7 +204,6 @@
short_first):
self.parser = None
self.indent_increment = indent_increment
- self.help_position = self.max_help_position = max_help_position
if width is None:
try:
width = int(os.environ['COLUMNS'])
@@ -212,6 +211,8 @@
width = 80
width -= 2
self.width = width
+ self.help_position = self.max_help_position = \
+ min(max_help_position, max(width - 20, indent_increment * 2))
self.current_indent = 0
self.level = 0
self.help_width = None # computed later
@@ -256,7 +257,7 @@
Format a paragraph of free-form text for inclusion in the
help output at the current indentation level.
"""
- text_width = self.width - self.current_indent
+ text_width = max(self.width - self.current_indent, 11)
indent = " "*self.current_indent
return textwrap.fill(text,
text_width,
@@ -337,7 +338,7 @@
self.dedent()
self.dedent()
self.help_position = min(max_len + 2, self.max_help_position)
- self.help_width = self.width - self.help_position
+ self.help_width = max(self.width - self.help_position, 11)
def format_option_strings(self, option):
"""Return a comma-separated list of option strings & metavariables."""
diff -r 3a1db0d2747e Lib/pickle.py
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -269,7 +269,7 @@
def save(self, obj):
# Check for persistent id (defined by a subclass)
pid = self.persistent_id(obj)
- if pid:
+ if pid is not None:
self.save_pers(pid)
return
diff -r 3a1db0d2747e Lib/posixpath.py
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -285,28 +285,43 @@
# Non-existent variables are left unchanged.
_varprog = None
+_uvarprog = None
def expandvars(path):
"""Expand shell variables of form $var and ${var}. Unknown variables
are left unchanged."""
- global _varprog
+ global _varprog, _uvarprog
if '$' not in path:
return path
- if not _varprog:
- import re
- _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
+ if isinstance(path, _unicode):
+ if not _varprog:
+ import re
+ _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
+ varprog = _varprog
+ encoding = sys.getfilesystemencoding()
+ else:
+ if not _uvarprog:
+ import re
+ _uvarprog = re.compile(_unicode(r'\$(\w+|\{[^}]*\})'), re.UNICODE)
+ varprog = _uvarprog
+ encoding = None
i = 0
while True:
- m = _varprog.search(path, i)
+ m = varprog.search(path, i)
if not m:
break
i, j = m.span(0)
name = m.group(1)
if name.startswith('{') and name.endswith('}'):
name = name[1:-1]
+ if encoding:
+ name = name.encode(encoding)
if name in os.environ:
tail = path[j:]
- path = path[:i] + os.environ[name]
+ value = os.environ[name]
+ if encoding:
+ value = value.decode(encoding)
+ path = path[:i] + value
i = len(path)
path += tail
else:
diff -r 3a1db0d2747e Lib/pydoc.py
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -81,6 +81,7 @@
def getdoc(object):
"""Get the doc string or comments for an object."""
result = inspect.getdoc(object) or inspect.getcomments(object)
+ result = _encode(result)
return result and re.sub('^ *\n', '', rstrip(result)) or ''
def splitdoc(doc):
@@ -182,6 +183,36 @@
return name, kind, cls, value
return map(fixup, inspect.classify_class_attrs(object))
+# ----------------------------------------------------- Unicode support helpers
+
+try:
+ _unicode = unicode
+except NameError:
+ # If Python is built without Unicode support, the unicode type
+ # will not exist. Fake one that nothing will match, and make
+ # the _encode function that do nothing.
+ class _unicode(object):
+ pass
+ _encoding = 'ascii'
+ def _encode(text, encoding='ascii'):
+ return text
+else:
+ import locale
+ _encoding = locale.getpreferredencoding()
+
+ def _encode(text, encoding=None):
+ if isinstance(text, unicode):
+ return text.encode(encoding or _encoding, 'xmlcharrefreplace')
+ else:
+ return text
+
+def _binstr(obj):
+ # Ensure that we have an encoded (binary) string representation of obj,
+ # even if it is a unicode string.
+ if isinstance(obj, _unicode):
+ return obj.encode(_encoding, 'xmlcharrefreplace')
+ return str(obj)
+
# ----------------------------------------------------- module manipulation
def ispackage(path):
@@ -424,12 +455,13 @@
def page(self, title, contents):
"""Format an HTML page."""
- return '''
+ return _encode('''
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: %s</title>
+<meta charset="utf-8">
</head><body bgcolor="#f0f0f8">
%s
-</body></html>''' % (title, contents)
+</body></html>''' % (title, contents), 'ascii')
def heading(self, title, fgcol, bgcol, extras=''):
"""Format a page heading."""
@@ -606,12 +638,12 @@
filelink = '(built-in)'
info = []
if hasattr(object, '__version__'):
- version = str(object.__version__)
+ version = _binstr(object.__version__)
if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
version = strip(version[11:-1])
info.append('version %s' % self.escape(version))
if hasattr(object, '__date__'):
- info.append(self.escape(str(object.__date__)))
+ info.append(self.escape(_binstr(object.__date__)))
if info:
head = head + ' (%s)' % join(info, ', ')
docloc = self.getdocloc(object)
@@ -694,11 +726,11 @@
result = result + self.bigsection(
'Data', '#ffffff', '#55aa55', join(contents, '<br>\n'))
if hasattr(object, '__author__'):
- contents = self.markup(str(object.__author__), self.preformat)
+ contents = self.markup(_binstr(object.__author__), self.preformat)
result = result + self.bigsection(
'Author', '#ffffff', '#7799ee', contents)
if hasattr(object, '__credits__'):
- contents = self.markup(str(object.__credits__), self.preformat)
+ contents = self.markup(_binstr(object.__credits__), self.preformat)
result = result + self.bigsection(
'Credits', '#ffffff', '#7799ee', contents)
@@ -1116,16 +1148,16 @@
result = result + self.section('DATA', join(contents, '\n'))
if hasattr(object, '__version__'):
- version = str(object.__version__)
+ version = _binstr(object.__version__)
if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
version = strip(version[11:-1])
result = result + self.section('VERSION', version)
if hasattr(object, '__date__'):
- result = result + self.section('DATE', str(object.__date__))
+ result = result + self.section('DATE', _binstr(object.__date__))
if hasattr(object, '__author__'):
- result = result + self.section('AUTHOR', str(object.__author__))
+ result = result + self.section('AUTHOR', _binstr(object.__author__))
if hasattr(object, '__credits__'):
- result = result + self.section('CREDITS', str(object.__credits__))
+ result = result + self.section('CREDITS', _binstr(object.__credits__))
return result
def docclass(self, object, name=None, mod=None, *ignored):
@@ -1375,7 +1407,7 @@
"""Page through text by feeding it to another program."""
pipe = os.popen(cmd, 'w')
try:
- pipe.write(text)
+ pipe.write(_encode(text))
pipe.close()
except IOError:
pass # Ignore broken pipes caused by quitting the pager program.
@@ -1385,7 +1417,7 @@
import tempfile
filename = tempfile.mktemp()
file = open(filename, 'w')
- file.write(text)
+ file.write(_encode(text))
file.close()
try:
os.system(cmd + ' "' + filename + '"')
@@ -1394,7 +1426,7 @@
def ttypager(text):
"""Page through text on a text terminal."""
- lines = split(plain(text), '\n')
+ lines = plain(_encode(plain(text), getattr(sys.stdout, 'encoding', _encoding))).split('\n')
try:
import tty
fd = sys.stdin.fileno()
@@ -1432,7 +1464,7 @@
def plainpager(text):
"""Simply print unformatted text. This is the ultimate fallback."""
- sys.stdout.write(plain(text))
+ sys.stdout.write(_encode(plain(text), getattr(sys.stdout, 'encoding', _encoding)))
def describe(thing):
"""Produce a short description of the given thing."""
diff -r 3a1db0d2747e Lib/pydoc_data/topics.py
--- a/Lib/pydoc_data/topics.py
+++ b/Lib/pydoc_data/topics.py
@@ -1,4 +1,4 @@
-# Autogenerated by Sphinx on Sat Oct 26 13:44:16 2013
+# Autogenerated by Sphinx on Fri Feb 14 06:59:30 2014
topics = {'assert': '\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n',
'assignment': '\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n',
'atom-identifiers': '\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier\n``__spam`` occurring in a class named ``Ham`` will be transformed to\n``_Ham__spam``. This transformation is independent of the syntactical\ncontext in which the identifier is used. If the transformed name is\nextremely long (longer than 255 characters), implementation defined\ntruncation may happen. If the class name consists only of underscores,\nno transformation is done.\n',
@@ -29,11 +29,12 @@
'dynamic-features': '\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n',
'else': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n',
'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n',
+ 'exec': '\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a Unicode string, a *Latin-1*\nencoded string, an open file object, a code object, or a tuple. If it\nis a string, the string is parsed as a suite of Python statements\nwhich is then executed (unless a syntax error occurs). [1] If it is an\nopen file, the file is parsed until EOF and executed. If it is a code\nobject, it is simply executed. For the interpretation of a tuple, see\nbelow. In all cases, the code that\'s executed is expected to be valid\nas file input (see section *File input*). Be aware that the\n``return`` and ``yield`` statements may not be used outside of\nfunction definitions even within the context of code passed to the\n``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object. Remember that at module\nlevel, globals and locals are the same dictionary. If two separate\nobjects are given as *globals* and *locals*, the code will be executed\nas if it were embedded in a class definition.\n\nThe first expression may also be a tuple of length 2 or 3. In this\ncase, the optional parts must be omitted. The form ``exec(expr,\nglobals)`` is equivalent to ``exec expr in globals``, while the form\n``exec(expr, globals, locals)`` is equivalent to ``exec expr in\nglobals, locals``. The tuple form of ``exec`` provides compatibility\nwith Python 3, where ``exec`` is a function rather than a statement.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use *universal newlines* mode to convert Windows or Mac-style\n newlines.\n',
'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n',
'exprlists': '\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n',
'floating': '\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n',
'for': '\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n',
- 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= <any source character except "]"> +\n conversion ::= "r" | "s"\n format_spec ::= <described in the next section>\n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings ``\'10\'`` or\n``\':-]\'``) within a format string. The *arg_name* can be followed by\nany number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= <any character>\n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceeded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use ``{`` and ``}`` as *fill*\nchar while using the ``str.format()`` method; this limitation however\ndoesn\'t affect the ``format()`` function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero (``\'0\'``) character enables\nsign-aware zero-padding for numeric types. This is equivalent to a\n*fill* character of ``\'0\'`` with an *alignment* type of ``\'=\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n',
+ 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= <any source character except "]"> +\n conversion ::= "r" | "s"\n format_spec ::= <described in the next section>\n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings ``\'10\'`` or\n``\':-]\'``) within a format string. The *arg_name* can be followed by\nany number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= <any character>\n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use ``{`` and ``}`` as *fill*\nchar while using the ``str.format()`` method; this limitation however\ndoesn\'t affect the ``format()`` function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero (``\'0\'``) character enables\nsign-aware zero-padding for numeric types. This is equivalent to a\n*fill* character of ``\'0\'`` with an *alignment* type of ``\'=\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n',
'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier ["," "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level *parameters* have the form *parameter*\n``=`` *expression*, the function is said to have "default parameter\nvalues." For a parameter with a default value, the corresponding\n*argument* may be omitted from a call, in which case the parameter\'s\ndefault value is substituted. If a parameter has a default value, all\nfollowing parameters must also have a default value --- this is a\nsyntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that the same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a "``def``" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The "``def``" form is actually more powerful since it\nallows the execution of multiple statements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n',
'global': '\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n',
'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n',
@@ -52,6 +53,7 @@
'operator-summary': '\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` ``x`` | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not in``, ``is``, ``is not``, ``<``, | Comparisons, including membership |\n| ``<=``, ``>``, ``>=``, ``<>``, ``!=``, ``==`` | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n| | [8] |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [9] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key: value...}``, ```expressions...``` | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. The function\n ``math.fmod()`` returns a result whose sign matches the sign of\n the first argument instead, and so returns ``-1e-100`` in this\n case. Which approach is more appropriate depends on the\n application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[8] The ``%`` operator is also used for string formatting; the same\n precedence applies.\n\n[9] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n',
'pass': '\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n',
'power': '\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n',
+ 'print': '\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is a whitespace character except ``\' \'``, or (3) when the last\nwrite operation on standard output was not a ``print`` statement. (In\nsome cases it may be functional to write an empty string to standard\noutput for this reason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n',
'raise': '\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["," expression ["," expression]]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a ``TypeError`` exception is raised indicating that\nthis is an error (if running under IDLE, a ``Queue.Empty`` exception\nis raised instead).\n\nOtherwise, ``raise`` evaluates the expressions to get three objects,\nusing ``None`` as the value of omitted expressions. The first two\nobjects are used to determine the *type* and *value* of the exception.\n\nIf the first object is an instance, the type of the exception is the\nclass of the instance, the instance itself is the value, and the\nsecond object must be ``None``.\n\nIf the first object is a class, it becomes the type of the exception.\nThe second object is used to determine the exception value: If it is\nan instance of the class, the instance becomes the exception value. If\nthe second object is a tuple, it is used as the argument list for the\nclass constructor; if it is ``None``, an empty argument list is used,\nand any other object is treated as a single argument to the\nconstructor. The instance so created by calling the constructor is\nused as the exception value.\n\nIf a third object is present and not ``None``, it must be a traceback\nobject (see section *The standard type hierarchy*), and it is\nsubstituted instead of the current location as the place where the\nexception occurred. If the third object is present and not a\ntraceback object or ``None``, a ``TypeError`` exception is raised.\nThe three-expression form of ``raise`` is useful to re-raise an\nexception transparently in an except clause, but ``raise`` with no\nexpressions should be preferred if the exception to be re-raised was\nthe most recently active exception in the current scope.\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n',
'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an ``expression_list``. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n',
'sequence-types': "\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn't define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\n New in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don't define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n",
@@ -64,13 +66,13 @@
'subscriptions': '\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object of a sequence or mapping type.\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``x[-1]`` selects the last item of\n``x``.) The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n',
'truth': "\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0L``, ``0.0``,\n ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n",
'try': '\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is discarded:\n\n def f():\n try:\n 1/0\n finally:\n return 42\n\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n',
- 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For Python 3 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself, and its ``im_func`` attribute is\n the function object underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *alist*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_self`` attribute is ``C``. When it would\n yield a static method object, it is transformed into the object\n wrapped by the static method object. See section *Implementing\n Descriptors* for another way in which attributes retrieved from a\n class may differ from those actually contained in its ``__dict__``\n (note that only new-style classes support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n',
+ 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values ``False`` and ``True`` are\n the only Boolean objects. The Boolean type is a subtype of\n plain integers, and Boolean values behave like the values 0\n and 1, respectively, in almost all contexts, the exception\n being that when converted to a string, the strings\n ``"False"`` or ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | ``func_doc`` | string, or ``None`` if | |\n | | unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name. | Writable |\n | ``func_name`` | | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | ``func_defaults`` | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value. | |\n +-------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | ``func_code`` | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | ``func_globals`` | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | ``func_dict`` | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | ``func_closure`` | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Changed in version 2.6: The double-underscore attributes\n ``__closure__``, ``__code__``, ``__defaults__``, and\n ``__globals__`` were introduced as aliases for the corresponding\n ``func_*`` attributes for forwards compatibility with Python 3.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For Python 3 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself, and its ``im_func`` attribute is\n the function object underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *alist*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_self`` attribute is ``C``. When it would\n yield a static method object, it is transformed into the object\n wrapped by the static method object. See section *Implementing\n Descriptors* for another way in which attributes retrieved from a\n class may differ from those actually contained in its ``__dict__``\n (note that only new-style classes support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n',
'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n',
'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterator*\n object. Each item in the iterable must itself be an iterator with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to ``{"one": 1, "two": 2, "three": 3}``:\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n New in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the ``iterkeys()``\n and ``itervalues()`` methods: ``pairs = zip(d.itervalues(),\n d.iterkeys())`` provides the same value for ``pairs``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n New in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n\n viewitems()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n New in version 2.7.\n\n viewkeys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n viewvalues()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.viewkeys()``, ``dict.viewvalues()`` and\n``dict.viewitems()`` are *view objects*. They provide a dynamic view\non the dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.viewkeys()\n >>> values = dishes.viewvalues()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n',
'typesmethods': '\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method\'s class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set an attribute on a method results in an\n``AttributeError`` being raised. In order to set a method attribute,\nyou need to explicitly set it on the underlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n AttributeError: \'instancemethod\' object has no attribute \'whoami\'\n >>> c.method.im_func.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n',
'typesmodules': "\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special attribute of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ``<module\n'sys' (built-in)>``. If loaded from a file, they are written as\n``<module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>``.\n",
- 'typesseq': '\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``bytearray``, ``buffer``, ``xrange``\n***************************************************************************************************\n\nThere are seven sequence types: strings, Unicode strings, lists,\ntuples, bytearrays, buffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBytearray objects are created with the built-in function\n``bytearray()``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.index(i)`` | index of the first occurrence of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.count(i)`` | total number of occurrences of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n``bytearray`` objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange* section. To output formatted strings use\ntemplate strings or the ``%`` operator described in the *String\nFormatting Operations* section. Also, see the ``re`` module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab (``\\t``), one or more space characters are inserted in the\n result until the current column is equal to the next tab position.\n (The tab character itself is not copied.) If the character is a\n newline (``\\n``) or return (``\\r``), it is copied and the current\n column is reset to zero. Any other character is copied unchanged\n and the current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified or ``-1``, then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example, ``\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()`` returns\n ``[\'ab c\', \'\', \'de fg\', \'kl\']``, while the same call with\n ``splitlines(True)`` returns ``[\'ab c\\n\', \'\\n\', \'de fg\\r\',\n \'kl\\r\\n\']``.\n\n Unlike ``split()`` when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that ``str.upper().isupper()`` might\n be ``False`` if ``s`` contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than or equal to ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that can be used to form decimal-radix numbers,\n e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf()`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [5] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(number)03d quote types.\' % \\\n... {"language": "Python", "number": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using *repr()*). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n',
- 'typesseq-mutable': "\nMutable Sequence Types\n**********************\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n",
+ 'typesseq': '\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``bytearray``, ``buffer``, ``xrange``\n***************************************************************************************************\n\nThere are seven sequence types: strings, Unicode strings, lists,\ntuples, bytearrays, buffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBytearray objects are created with the built-in function\n``bytearray()``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.index(i)`` | index of the first occurrence of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.count(i)`` | total number of occurrences of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n``bytearray`` objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange* section. To output formatted strings use\ntemplate strings or the ``%`` operator described in the *String\nFormatting Operations* section. Also, see the ``re`` module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab (``\\t``), one or more space characters are inserted in the\n result until the current column is equal to the next tab position.\n (The tab character itself is not copied.) If the character is a\n newline (``\\n``) or return (``\\r``), it is copied and the current\n column is reset to zero. Any other character is copied unchanged\n and the current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified or ``-1``, then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example, ``\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()`` returns\n ``[\'ab c\', \'\', \'de fg\', \'kl\']``, while the same call with\n ``splitlines(True)`` returns ``[\'ab c\\n\', \'\\n\', \'de fg\\r\',\n \'kl\\r\\n\']``.\n\n Unlike ``split()`` when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that ``str.upper().isupper()`` might\n be ``False`` if ``s`` contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than or equal to ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that can be used to form decimal-radix numbers,\n e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf()`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [5] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(number)03d quote types.\' % \\\n... {"language": "Python", "number": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using *repr()*). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method\'s optional argument *i* defaults to ``-1``, so\n that by default the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n',
+ 'typesseq-mutable': "\nMutable Sequence Types\n**********************\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method's optional argument *i* defaults to ``-1``, so\n that by default the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n",
'unary': '\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n',
'while': '\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n',
'with': '\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n',
diff -r 3a1db0d2747e Lib/random.py
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -108,7 +108,7 @@
if a is None:
try:
- a = long(_hexlify(_urandom(16)), 16)
+ a = long(_hexlify(_urandom(32)), 16)
except NotImplementedError:
import time
a = long(time.time() * 256) # use fractional seconds
diff -r 3a1db0d2747e Lib/re.py
--- a/Lib/re.py
+++ b/Lib/re.py
@@ -225,11 +225,13 @@
def _compile(*key):
# internal: compile pattern
- cachekey = (type(key[0]),) + key
- p = _cache.get(cachekey)
- if p is not None:
- return p
pattern, flags = key
+ bypass_cache = flags & DEBUG
+ if not bypass_cache:
+ cachekey = (type(key[0]),) + key
+ p = _cache.get(cachekey)
+ if p is not None:
+ return p
if isinstance(pattern, _pattern_type):
if flags:
raise ValueError('Cannot process flags argument with a compiled pattern')
@@ -240,9 +242,10 @@
p = sre_compile.compile(pattern, flags)
except error, v:
raise error, v # invalid expression
- if len(_cache) >= _MAXCACHE:
- _cache.clear()
- _cache[cachekey] = p
+ if not bypass_cache:
+ if len(_cache) >= _MAXCACHE:
+ _cache.clear()
+ _cache[cachekey] = p
return p
def _compile_repl(*key):
diff -r 3a1db0d2747e Lib/shutil.py
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -259,7 +259,8 @@
def _basename(path):
# A basename() variant which first strips the trailing slash, if present.
# Thus we always get the last component of the path, even for directories.
- return os.path.basename(path.rstrip(os.path.sep))
+ sep = os.path.sep + (os.path.altsep or '')
+ return os.path.basename(path.rstrip(sep))
def move(src, dst):
"""Recursively move a file or directory to another location. This is
@@ -446,17 +447,15 @@
zip_filename, base_dir)
if not dry_run:
- zip = zipfile.ZipFile(zip_filename, "w",
- compression=zipfile.ZIP_DEFLATED)
-
- for dirpath, dirnames, filenames in os.walk(base_dir):
- for name in filenames:
- path = os.path.normpath(os.path.join(dirpath, name))
- if os.path.isfile(path):
- zip.write(path, path)
- if logger is not None:
- logger.info("adding '%s'", path)
- zip.close()
+ with zipfile.ZipFile(zip_filename, "w",
+ compression=zipfile.ZIP_DEFLATED) as zf:
+ for dirpath, dirnames, filenames in os.walk(base_dir):
+ for name in filenames:
+ path = os.path.normpath(os.path.join(dirpath, name))
+ if os.path.isfile(path):
+ zf.write(path, path)
+ if logger is not None:
+ logger.info("adding '%s'", path)
return zip_filename
diff -r 3a1db0d2747e Lib/sqlite3/test/factory.py
--- a/Lib/sqlite3/test/factory.py
+++ b/Lib/sqlite3/test/factory.py
@@ -47,9 +47,7 @@
self.con.close()
def CheckIsInstance(self):
- self.assertTrue(isinstance(self.con,
- MyConnection),
- "connection is not instance of MyConnection")
+ self.assertIsInstance(self.con, MyConnection)
class CursorFactoryTests(unittest.TestCase):
def setUp(self):
@@ -60,9 +58,7 @@
def CheckIsInstance(self):
cur = self.con.cursor(factory=MyCursor)
- self.assertTrue(isinstance(cur,
- MyCursor),
- "cursor is not instance of MyCursor")
+ self.assertIsInstance(cur, MyCursor)
class RowFactoryTestsBackwardsCompat(unittest.TestCase):
def setUp(self):
@@ -72,9 +68,7 @@
cur = self.con.cursor(factory=MyCursor)
cur.execute("select 4+5 as foo")
row = cur.fetchone()
- self.assertTrue(isinstance(row,
- dict),
- "row is not instance of dict")
+ self.assertIsInstance(row, dict)
cur.close()
def tearDown(self):
@@ -87,28 +81,24 @@
def CheckCustomFactory(self):
self.con.row_factory = lambda cur, row: list(row)
row = self.con.execute("select 1, 2").fetchone()
- self.assertTrue(isinstance(row,
- list),
- "row is not instance of list")
+ self.assertIsInstance(row, list)
def CheckSqliteRowIndex(self):
self.con.row_factory = sqlite.Row
row = self.con.execute("select 1 as a, 2 as b").fetchone()
- self.assertTrue(isinstance(row,
- sqlite.Row),
- "row is not instance of sqlite.Row")
+ self.assertIsInstance(row, sqlite.Row)
col1, col2 = row["a"], row["b"]
- self.assertTrue(col1 == 1, "by name: wrong result for column 'a'")
- self.assertTrue(col2 == 2, "by name: wrong result for column 'a'")
+ self.assertEqual(col1, 1, "by name: wrong result for column 'a'")
+ self.assertEqual(col2, 2, "by name: wrong result for column 'a'")
col1, col2 = row["A"], row["B"]
- self.assertTrue(col1 == 1, "by name: wrong result for column 'A'")
- self.assertTrue(col2 == 2, "by name: wrong result for column 'B'")
+ self.assertEqual(col1, 1, "by name: wrong result for column 'A'")
+ self.assertEqual(col2, 2, "by name: wrong result for column 'B'")
col1, col2 = row[0], row[1]
- self.assertTrue(col1 == 1, "by index: wrong result for column 0")
- self.assertTrue(col2 == 2, "by index: wrong result for column 1")
+ self.assertEqual(col1, 1, "by index: wrong result for column 0")
+ self.assertEqual(col2, 2, "by index: wrong result for column 1")
def CheckSqliteRowIter(self):
"""Checks if the row object is iterable"""
@@ -122,6 +112,7 @@
self.con.row_factory = sqlite.Row
row = self.con.execute("select 1 as a, 2 as b").fetchone()
t = tuple(row)
+ self.assertEqual(t, (row['a'], row['b']))
def CheckSqliteRowAsDict(self):
"""Checks if the row object can be correctly converted to a dictionary"""
@@ -138,8 +129,8 @@
row_2 = self.con.execute("select 1 as a, 2 as b").fetchone()
row_3 = self.con.execute("select 1 as a, 3 as b").fetchone()
- self.assertTrue(row_1 == row_1)
- self.assertTrue(row_1 == row_2)
+ self.assertEqual(row_1, row_1)
+ self.assertEqual(row_1, row_2)
self.assertTrue(row_2 != row_3)
self.assertFalse(row_1 != row_1)
@@ -161,20 +152,20 @@
def CheckUnicode(self):
austria = unicode("sterreich", "latin1")
row = self.con.execute("select ?", (austria,)).fetchone()
- self.assertTrue(type(row[0]) == unicode, "type of row[0] must be unicode")
+ self.assertEqual(type(row[0]), unicode, "type of row[0] must be unicode")
def CheckString(self):
self.con.text_factory = str
austria = unicode("sterreich", "latin1")
row = self.con.execute("select ?", (austria,)).fetchone()
- self.assertTrue(type(row[0]) == str, "type of row[0] must be str")
- self.assertTrue(row[0] == austria.encode("utf-8"), "column must equal original data in UTF-8")
+ self.assertEqual(type(row[0]), str, "type of row[0] must be str")
+ self.assertEqual(row[0], austria.encode("utf-8"), "column must equal original data in UTF-8")
def CheckCustom(self):
self.con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
austria = unicode("sterreich", "latin1")
row = self.con.execute("select ?", (austria.encode("latin1"),)).fetchone()
- self.assertTrue(type(row[0]) == unicode, "type of row[0] must be unicode")
+ self.assertEqual(type(row[0]), unicode, "type of row[0] must be unicode")
self.assertTrue(row[0].endswith(u"reich"), "column must contain original data")
def CheckOptimizedUnicode(self):
@@ -183,8 +174,8 @@
germany = unicode("Deutchland")
a_row = self.con.execute("select ?", (austria,)).fetchone()
d_row = self.con.execute("select ?", (germany,)).fetchone()
- self.assertTrue(type(a_row[0]) == unicode, "type of non-ASCII row must be unicode")
- self.assertTrue(type(d_row[0]) == str, "type of ASCII-only row must be str")
+ self.assertEqual(type(a_row[0]), unicode, "type of non-ASCII row must be unicode")
+ self.assertEqual(type(d_row[0]), str, "type of ASCII-only row must be str")
def tearDown(self):
self.con.close()
diff -r 3a1db0d2747e Lib/sqlite3/test/hooks.py
--- a/Lib/sqlite3/test/hooks.py
+++ b/Lib/sqlite3/test/hooks.py
@@ -162,7 +162,7 @@
create table bar (a, b)
""")
second_count = len(progress_calls)
- self.assertTrue(first_count > second_count)
+ self.assertGreaterEqual(first_count, second_count)
def CheckCancelOperation(self):
"""
diff -r 3a1db0d2747e Lib/sqlite3/test/regression.py
--- a/Lib/sqlite3/test/regression.py
+++ b/Lib/sqlite3/test/regression.py
@@ -313,6 +313,11 @@
datetime.datetime(2012, 4, 4, 15, 6, 0, 123456),
])
+ def CheckInvalidIsolationLevelType(self):
+ # isolation level is a string, not an integer
+ self.assertRaises(TypeError,
+ sqlite.connect, ":memory:", isolation_level=123)
+
def suite():
regression_suite = unittest.makeSuite(RegressionTests, "Check")
diff -r 3a1db0d2747e Lib/sre_compile.py
--- a/Lib/sre_compile.py
+++ b/Lib/sre_compile.py
@@ -276,10 +276,10 @@
# set is constructed. Then, this bitmap is sliced into chunks of 256
# characters, duplicate chunks are eliminated, and each chunk is
# given a number. In the compiled expression, the charset is
-# represented by a 16-bit word sequence, consisting of one word for
-# the number of different chunks, a sequence of 256 bytes (128 words)
+# represented by a 32-bit word sequence, consisting of one word for
+# the number of different chunks, a sequence of 256 bytes (64 words)
# of chunk numbers indexed by their original chunk position, and a
-# sequence of chunks (16 words each).
+# sequence of 256-bit chunks (8 words each).
# Compression is normally good: in a typical charset, large ranges of
# Unicode will be either completely excluded (e.g. if only cyrillic
@@ -294,7 +294,7 @@
# In UCS-4 mode, the BIGCHARSET opcode still supports only subsets
# of the basic multilingual plane; an efficient representation
-# for all of UTF-16 has not yet been developed. This means,
+# for all of Unicode has not yet been developed. This means,
# in particular, that negated charsets cannot be represented as
# bigcharsets.
diff -r 3a1db0d2747e Lib/ssl.py
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -89,6 +89,7 @@
from socket import socket, _fileobject, _delegate_methods, error as socket_error
from socket import getnameinfo as _getnameinfo
+from socket import SOL_SOCKET, SO_TYPE, SOCK_STREAM
import base64 # for DER-to-PEM translation
import errno
@@ -108,6 +109,10 @@
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
do_handshake_on_connect=True,
suppress_ragged_eofs=True, ciphers=None):
+ # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
+ # mixed in.
+ if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
+ raise NotImplementedError("only stream sockets are supported")
socket.__init__(self, _sock=sock._sock)
# The initializer for socket overrides the methods send(), recv(), etc.
# in the instancce, which we don't need -- but we want to provide the
diff -r 3a1db0d2747e Lib/subprocess.py
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -11,7 +11,7 @@
This module allows you to spawn processes, connect to their
input/output/error pipes, and obtain their return codes. This module
-intends to replace several other, older modules and functions, like:
+intends to replace several older modules and functions:
os.system
os.spawn*
@@ -645,6 +645,8 @@
class Popen(object):
+ _child_created = False # Set here since __del__ checks it
+
def __init__(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
@@ -653,7 +655,6 @@
"""Create new Popen instance."""
_cleanup()
- self._child_created = False
if not isinstance(bufsize, (int, long)):
raise TypeError("bufsize must be an integer")
@@ -750,11 +751,11 @@
return data
- def __del__(self, _maxint=sys.maxint, _active=_active):
+ def __del__(self, _maxint=sys.maxint):
# If __init__ hasn't had a chance to execute (e.g. if it
# was passed an undeclared keyword argument), we don't
# have a _child_created attribute at all.
- if not getattr(self, '_child_created', False):
+ if not self._child_created:
# We didn't get to successfully create a child process.
return
# In case the child hasn't been waited on, check if it's done.
@@ -1330,7 +1331,7 @@
_WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED,
_WEXITSTATUS=os.WEXITSTATUS):
# This method is called (indirectly) by __del__, so it cannot
- # refer to anything outside of its local scope."""
+ # refer to anything outside of its local scope.
if _WIFSIGNALED(sts):
self.returncode = -_WTERMSIG(sts)
elif _WIFEXITED(sts):
diff -r 3a1db0d2747e Lib/sunau.py
--- a/Lib/sunau.py
+++ b/Lib/sunau.py
@@ -224,7 +224,7 @@
if self._data_size == AUDIO_UNKNOWN_SIZE:
return AUDIO_UNKNOWN_SIZE
if self._encoding in _simple_encodings:
- return self._data_size / self._framesize
+ return self._data_size // self._framesize
return 0 # XXX--must do some arithmetic here
def getcomptype(self):
diff -r 3a1db0d2747e Lib/tarfile.py
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
#-------------------------------------------------------------------
# tarfile.py
@@ -1509,10 +1508,11 @@
can be determined, `mode' is overridden by `fileobj's mode.
`fileobj' is not closed, when TarFile is closed.
"""
- if len(mode) > 1 or mode not in "raw":
+ modes = {"r": "rb", "a": "r+b", "w": "wb"}
+ if mode not in modes:
raise ValueError("mode must be 'r', 'a' or 'w'")
self.mode = mode
- self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
+ self._mode = modes[mode]
if not fileobj:
if self.mode == "a" and not os.path.exists(name):
@@ -1682,7 +1682,7 @@
filemode = filemode or "r"
comptype = comptype or "tar"
- if filemode not in "rw":
+ if filemode not in ("r", "w"):
raise ValueError("mode must be 'r' or 'w'")
t = cls(name, filemode,
@@ -1691,7 +1691,7 @@
t._extfileobj = False
return t
- elif mode in "aw":
+ elif mode in ("a", "w"):
return cls.taropen(name, mode, fileobj, **kwargs)
raise ValueError("undiscernible mode")
@@ -1700,7 +1700,7 @@
def taropen(cls, name, mode="r", fileobj=None, **kwargs):
"""Open uncompressed tar archive name for reading or writing.
"""
- if len(mode) > 1 or mode not in "raw":
+ if mode not in ("r", "a", "w"):
raise ValueError("mode must be 'r', 'a' or 'w'")
return cls(name, mode, fileobj, **kwargs)
@@ -1709,7 +1709,7 @@
"""Open gzip compressed tar archive name for reading or writing.
Appending is not allowed.
"""
- if len(mode) > 1 or mode not in "rw":
+ if mode not in ("r", "w"):
raise ValueError("mode must be 'r' or 'w'")
try:
@@ -1726,7 +1726,9 @@
gzip.GzipFile(name, mode, compresslevel, fileobj),
**kwargs)
except IOError:
- raise ReadError("not a gzip file")
+ if mode == 'r':
+ raise ReadError("not a gzip file")
+ raise
t._extfileobj = False
return t
@@ -1735,7 +1737,7 @@
"""Open bzip2 compressed tar archive name for reading or writing.
Appending is not allowed.
"""
- if len(mode) > 1 or mode not in "rw":
+ if mode not in ("r", "w"):
raise ValueError("mode must be 'r' or 'w'.")
try:
@@ -1751,7 +1753,9 @@
try:
t = cls.taropen(name, mode, fileobj, **kwargs)
except (IOError, EOFError):
- raise ReadError("not a bzip2 file")
+ if mode == 'r':
+ raise ReadError("not a bzip2 file")
+ raise
t._extfileobj = False
return t
diff -r 3a1db0d2747e Lib/telnetlib.py
--- a/Lib/telnetlib.py
+++ b/Lib/telnetlib.py
@@ -312,7 +312,9 @@
poller.register(self, poll_in_or_priority_flags)
while i < 0 and not self.eof:
try:
- ready = poller.poll(call_timeout)
+ # Poll takes its timeout in milliseconds.
+ ready = poller.poll(None if timeout is None
+ else 1000 * call_timeout)
except select.error as e:
if e.errno == errno.EINTR:
if timeout is not None:
@@ -682,7 +684,8 @@
poller.register(self, poll_in_or_priority_flags)
while not m and not self.eof:
try:
- ready = poller.poll(call_timeout)
+ ready = poller.poll(None if timeout is None
+ else 1000 * call_timeout)
except select.error as e:
if e.errno == errno.EINTR:
if timeout is not None:
diff -r 3a1db0d2747e Lib/test/audiotests.py
--- a/Lib/test/audiotests.py
+++ b/Lib/test/audiotests.py
@@ -6,11 +6,19 @@
import sys
import base64
+class UnseekableIO(file):
+ def tell(self):
+ raise io.UnsupportedOperation
+
+ def seek(self, *args, **kwargs):
+ raise io.UnsupportedOperation
+
def fromhex(s):
return base64.b16decode(s.replace(' ', ''))
def byteswap2(data):
- a = array.array('h', data)
+ a = array.array('h')
+ a.fromstring(data)
a.byteswap()
return a.tostring()
@@ -21,7 +29,8 @@
return bytes(ba)
def byteswap4(data):
- a = array.array('i', data)
+ a = array.array('i')
+ a.fromstring(data)
a.byteswap()
return a.tostring()
@@ -131,6 +140,62 @@
self.assertEqual(testfile.read(13), b'ababagalamaga')
self.check_file(testfile, self.nframes, self.frames)
+ def test_unseekable_read(self):
+ f = self.create_file(TESTFN)
+ f.setnframes(self.nframes)
+ f.writeframes(self.frames)
+ f.close()
+
+ with UnseekableIO(TESTFN, 'rb') as testfile:
+ self.check_file(testfile, self.nframes, self.frames)
+
+ def test_unseekable_write(self):
+ with UnseekableIO(TESTFN, 'wb') as testfile:
+ f = self.create_file(testfile)
+ f.setnframes(self.nframes)
+ f.writeframes(self.frames)
+ f.close()
+ self.fout = None
+
+ self.check_file(TESTFN, self.nframes, self.frames)
+
+ def test_unseekable_incompleted_write(self):
+ with UnseekableIO(TESTFN, 'wb') as testfile:
+ testfile.write(b'ababagalamaga')
+ f = self.create_file(testfile)
+ f.setnframes(self.nframes + 1)
+ try:
+ f.writeframes(self.frames)
+ except IOError:
+ pass
+ try:
+ f.close()
+ except IOError:
+ pass
+
+ with open(TESTFN, 'rb') as testfile:
+ self.assertEqual(testfile.read(13), b'ababagalamaga')
+ self.check_file(testfile, self.nframes + 1, self.frames)
+
+ def test_unseekable_overflowed_write(self):
+ with UnseekableIO(TESTFN, 'wb') as testfile:
+ testfile.write(b'ababagalamaga')
+ f = self.create_file(testfile)
+ f.setnframes(self.nframes - 1)
+ try:
+ f.writeframes(self.frames)
+ except IOError:
+ pass
+ try:
+ f.close()
+ except IOError:
+ pass
+
+ with open(TESTFN, 'rb') as testfile:
+ self.assertEqual(testfile.read(13), b'ababagalamaga')
+ framesize = self.nchannels * self.sampwidth
+ self.check_file(testfile, self.nframes - 1, self.frames[:-framesize])
+
class AudioTestsWithSourceFile(AudioTests):
diff -r 3a1db0d2747e Lib/test/bad_coding3.py
--- /dev/null
+++ b/Lib/test/bad_coding3.py
@@ -0,0 +1,2 @@
+# coding: string-escape
+\x70\x72\x69\x6e\x74\x20\x32\x2b\x32\x0a
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.bmp
Binary file Lib/test/imghdrdata/python.bmp has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.gif
Binary file Lib/test/imghdrdata/python.gif has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.jpg
Binary file Lib/test/imghdrdata/python.jpg has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.pbm
--- /dev/null
+++ b/Lib/test/imghdrdata/python.pbm
@@ -0,0 +1,3 @@
+P4
+16 16
+[a_X?
\ No newline at end of file
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.pgm
Binary file Lib/test/imghdrdata/python.pgm has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.png
Binary file Lib/test/imghdrdata/python.png has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.ppm
Binary file Lib/test/imghdrdata/python.ppm has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.ras
Binary file Lib/test/imghdrdata/python.ras has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.sgi
Binary file Lib/test/imghdrdata/python.sgi has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.tiff
Binary file Lib/test/imghdrdata/python.tiff has changed
diff -r 3a1db0d2747e Lib/test/imghdrdata/python.xbm
--- /dev/null
+++ b/Lib/test/imghdrdata/python.xbm
@@ -0,0 +1,6 @@
+#define python_width 16
+#define python_height 16
+static char python_bits[] = {
+ 0xDF, 0xFE, 0x8F, 0xFD, 0x5F, 0xFB, 0xAB, 0xFE, 0xB5, 0x8D, 0xDA, 0x8F,
+ 0xA5, 0x86, 0xFA, 0x83, 0x1A, 0x80, 0x0D, 0x80, 0x0D, 0x80, 0x0F, 0xE0,
+ 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, };
diff -r 3a1db0d2747e Lib/test/pickletester.py
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -1152,30 +1152,34 @@
if isinstance(object, int) and object % 2 == 0:
self.id_count += 1
return str(object)
+ elif object == "test_false_value":
+ self.false_count += 1
+ return ""
else:
return None
def persistent_load(self, oid):
- self.load_count += 1
- object = int(oid)
- assert object % 2 == 0
- return object
+ if not oid:
+ self.load_false_count += 1
+ return "test_false_value"
+ else:
+ self.load_count += 1
+ object = int(oid)
+ assert object % 2 == 0
+ return object
def test_persistence(self):
- self.id_count = 0
- self.load_count = 0
- L = range(10)
- self.assertEqual(self.loads(self.dumps(L)), L)
- self.assertEqual(self.id_count, 5)
- self.assertEqual(self.load_count, 5)
-
- def test_bin_persistence(self):
- self.id_count = 0
- self.load_count = 0
- L = range(10)
- self.assertEqual(self.loads(self.dumps(L, 1)), L)
- self.assertEqual(self.id_count, 5)
- self.assertEqual(self.load_count, 5)
+ L = range(10) + ["test_false_value"]
+ for proto in protocols:
+ self.id_count = 0
+ self.false_count = 0
+ self.load_false_count = 0
+ self.load_count = 0
+ self.assertEqual(self.loads(self.dumps(L, proto)), L)
+ self.assertEqual(self.id_count, 5)
+ self.assertEqual(self.false_count, 1)
+ self.assertEqual(self.load_count, 5)
+ self.assertEqual(self.load_false_count, 1)
class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/string_tests.py
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -5,7 +5,6 @@
import unittest, string, sys, struct
from test import test_support
from UserList import UserList
-import _testcapi
class Sequence:
def __init__(self, seq='wxyz'): self.seq = seq
@@ -750,10 +749,10 @@
self.checkraises(TypeError, 'hello', 'replace', 42, 'h')
self.checkraises(TypeError, 'hello', 'replace', 'h', 42)
+ @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4,
+ 'only applies to 32-bit platforms')
def test_replace_overflow(self):
# Check for overflow checking on 32 bit machines
- if sys.maxint != 2147483647 or struct.calcsize("P") > 4:
- return
A2_16 = "A" * (2**16)
self.checkraises(OverflowError, A2_16, "replace", "", A2_16)
self.checkraises(OverflowError, A2_16, "replace", "A", A2_16)
@@ -1114,20 +1113,6 @@
self.checkraises(TypeError, '%10.*f', '__mod__', ('foo', 42.))
self.checkraises(ValueError, '%10', '__mod__', (42,))
- width = int(_testcapi.PY_SSIZE_T_MAX + 1)
- if width <= sys.maxint:
- self.checkraises(OverflowError, '%*s', '__mod__', (width, ''))
- prec = int(_testcapi.INT_MAX + 1)
- if prec <= sys.maxint:
- self.checkraises(OverflowError, '%.*f', '__mod__', (prec, 1. / 7))
- # Issue 15989
- width = int(1 << (_testcapi.PY_SSIZE_T_MAX.bit_length() + 1))
- if width <= sys.maxint:
- self.checkraises(OverflowError, '%*s', '__mod__', (width, ''))
- prec = int(_testcapi.UINT_MAX + 1)
- if prec <= sys.maxint:
- self.checkraises(OverflowError, '%.*f', '__mod__', (prec, 1. / 7))
-
class X(object): pass
self.checkraises(TypeError, 'abc', '__mod__', X())
class X(Exception):
@@ -1135,6 +1120,24 @@
return k
self.checkequal('melon apple', '%(melon)s %(apple)s', '__mod__', X())
+ @test_support.cpython_only
+ def test_formatting_c_limits(self):
+ from _testcapi import PY_SSIZE_T_MAX, INT_MAX, UINT_MAX
+ SIZE_MAX = (1 << (PY_SSIZE_T_MAX.bit_length() + 1)) - 1
+ width = int(PY_SSIZE_T_MAX + 1)
+ if width <= sys.maxint:
+ self.checkraises(OverflowError, '%*s', '__mod__', (width, ''))
+ prec = int(INT_MAX + 1)
+ if prec <= sys.maxint:
+ self.checkraises(OverflowError, '%.*f', '__mod__', (prec, 1. / 7))
+ # Issue 15989
+ width = int(SIZE_MAX + 1)
+ if width <= sys.maxint:
+ self.checkraises(OverflowError, '%*s', '__mod__', (width, ''))
+ prec = int(UINT_MAX + 1)
+ if prec <= sys.maxint:
+ self.checkraises(OverflowError, '%.*f', '__mod__', (prec, 1. / 7))
+
def test_floatformatting(self):
# float formatting
for prec in xrange(100):
@@ -1286,27 +1289,27 @@
# Additional tests that only work with
# 8bit compatible object, i.e. str and UserString
- if test_support.have_unicode:
- def test_encoding_decoding(self):
- codecs = [('rot13', 'uryyb jbeyq'),
- ('base64', 'aGVsbG8gd29ybGQ=\n'),
- ('hex', '68656c6c6f20776f726c64'),
- ('uu', 'begin 666 <data>\n+:&5L;&\\@=V]R;&0 \n \nend\n')]
- for encoding, data in codecs:
- self.checkequal(data, 'hello world', 'encode', encoding)
- self.checkequal('hello world', data, 'decode', encoding)
- # zlib is optional, so we make the test optional too...
- try:
- import zlib
- except ImportError:
- pass
- else:
- data = 'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\x01\x00\x1a\x0b\x04]'
- self.checkequal(data, 'hello world', 'encode', 'zlib')
- self.checkequal('hello world', data, 'decode', 'zlib')
+ @unittest.skipUnless(test_support.have_unicode, 'no unicode support')
+ def test_encoding_decoding(self):
+ codecs = [('rot13', 'uryyb jbeyq'),
+ ('base64', 'aGVsbG8gd29ybGQ=\n'),
+ ('hex', '68656c6c6f20776f726c64'),
+ ('uu', 'begin 666 <data>\n+:&5L;&\\@=V]R;&0 \n \nend\n')]
+ for encoding, data in codecs:
+ self.checkequal(data, 'hello world', 'encode', encoding)
+ self.checkequal('hello world', data, 'decode', encoding)
+ # zlib is optional, so we make the test optional too...
+ try:
+ import zlib
+ except ImportError:
+ pass
+ else:
+ data = 'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\x01\x00\x1a\x0b\x04]'
+ self.checkequal(data, 'hello world', 'encode', 'zlib')
+ self.checkequal('hello world', data, 'decode', 'zlib')
- self.checkraises(TypeError, 'xyz', 'decode', 42)
- self.checkraises(TypeError, 'xyz', 'encode', 42)
+ self.checkraises(TypeError, 'xyz', 'decode', 42)
+ self.checkraises(TypeError, 'xyz', 'encode', 42)
class MixinStrUnicodeTest:
diff -r 3a1db0d2747e Lib/test/test___future__.py
--- a/Lib/test/test___future__.py
+++ b/Lib/test/test___future__.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
import unittest
from test import test_support
import __future__
diff -r 3a1db0d2747e Lib/test/test_aepack.py
--- a/Lib/test/test_aepack.py
+++ b/Lib/test/test_aepack.py
@@ -59,10 +59,10 @@
try:
import Carbon.File
except:
- return
+ self.skipTest('Carbon.File not available')
if not hasattr(Carbon.File, "FSSpec"):
- return
+ self.skipTest('Carbon.File.FSSpec not available')
o = Carbon.File.FSSpec(os.curdir)
packed = aepack.pack(o)
unpacked = aepack.unpack(packed)
@@ -72,9 +72,9 @@
try:
import Carbon.File
except:
- return
+ self.skipTest('Carbon.File not available')
if not hasattr(Carbon.File, "FSSpec"):
- return
+ self.skipTest('Carbon.File.FSSpec not available')
o = Carbon.File.FSSpec(os.curdir).NewAliasMinimal()
packed = aepack.pack(o)
unpacked = aepack.unpack(packed)
diff -r 3a1db0d2747e Lib/test/test_aifc.py
--- a/Lib/test/test_aifc.py
+++ b/Lib/test/test_aifc.py
@@ -9,10 +9,14 @@
import aifc
-class AifcPCM8Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
+class AifcTest(audiotests.AudioWriteTests,
+ audiotests.AudioTestsWithSourceFile):
module = aifc
+ close_fd = True
+ test_unseekable_read = None
+
+
+class AifcPCM8Test(AifcTest, unittest.TestCase):
sndfilename = 'pluck-pcm8.aiff'
sndfilenframes = 3307
nchannels = 2
@@ -27,13 +31,9 @@
11FA 3EFB BCFC 66FF CF04 4309 C10E 5112 EE17 8216 7F14 8012 \
490E 520D EF0F CE0F E40C 630A 080A 2B0B 510E 8B11 B60E 440A \
""")
- close_fd = True
-class AifcPCM16Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = aifc
+class AifcPCM16Test(AifcTest, unittest.TestCase):
sndfilename = 'pluck-pcm16.aiff'
sndfilenframes = 3307
nchannels = 2
@@ -50,13 +50,9 @@
EEE21753 82071665 7FFF1443 8004128F 49A20EAF 52BB0DBA EFB40F60 CE3C0FBF \
E4B30CEC 63430A5C 08C80A20 2BBB0B08 514A0E43 8BCF1139 B6F60EEB 44120A5E \
""")
- close_fd = True
-class AifcPCM24Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = aifc
+class AifcPCM24Test(AifcTest, unittest.TestCase):
sndfilename = 'pluck-pcm24.aiff'
sndfilenframes = 3307
nchannels = 2
@@ -79,13 +75,9 @@
E4B49C0CEA2D 6344A80A5A7C 08C8FE0A1FFE 2BB9860B0A0E \
51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \
""")
- close_fd = True
-class AifcPCM32Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = aifc
+class AifcPCM32Test(AifcTest, unittest.TestCase):
sndfilename = 'pluck-pcm32.aiff'
sndfilenframes = 3307
nchannels = 2
@@ -108,13 +100,9 @@
E4B49CC00CEA2D90 6344A8800A5A7CA0 08C8FE800A1FFEE0 2BB986C00B0A0E00 \
51486F800E44E190 8BCC6480113B0580 B6F4EC000EEB3630 441317800A5B48A0 \
""")
- close_fd = True
-class AifcULAWTest(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = aifc
+class AifcULAWTest(AifcTest, unittest.TestCase):
sndfilename = 'pluck-ulaw.aifc'
sndfilenframes = 3307
nchannels = 2
@@ -133,7 +121,6 @@
""")
if sys.byteorder != 'big':
frames = audiotests.byteswap2(frames)
- close_fd = True
class AifcMiscTest(audiotests.AudioTests, unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/test_al.py
--- a/Lib/test/test_al.py
+++ b/Lib/test/test_al.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Whimpy test script for the al module
Roger E. Masse
"""
diff -r 3a1db0d2747e Lib/test/test_anydbm.py
--- a/Lib/test/test_anydbm.py
+++ b/Lib/test/test_anydbm.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for the anydbm module
based on testdumbdbm.py
"""
diff -r 3a1db0d2747e Lib/test/test_argparse.py
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -2936,6 +2936,60 @@
0.1
'''
+class TestShortColumns(HelpTestCase):
+ '''Test extremely small number of columns.
+
+ TestCase prevents "COLUMNS" from being too small in the tests themselves,
+ but we don't want any exceptions thrown in such case. Only ugly representation.
+ '''
+ def setUp(self):
+ env = test_support.EnvironmentVarGuard()
+ env.set("COLUMNS", '15')
+ self.addCleanup(env.__exit__)
+
+ parser_signature = TestHelpBiggerOptionals.parser_signature
+ argument_signatures = TestHelpBiggerOptionals.argument_signatures
+ argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures
+ usage = '''\
+ usage: PROG
+ [-h]
+ [-v]
+ [-x]
+ [--y Y]
+ foo
+ bar
+ '''
+ help = usage + '''\
+
+ DESCRIPTION
+
+ positional arguments:
+ foo
+ FOO HELP
+ bar
+ BAR HELP
+
+ optional arguments:
+ -h, --help
+ show this
+ help
+ message and
+ exit
+ -v, --version
+ show
+ program's
+ version
+ number and
+ exit
+ -x
+ X HELP
+ --y Y
+ Y HELP
+
+ EPILOG
+ '''
+ version = TestHelpBiggerOptionals.version
+
class TestHelpBiggerOptionalGroups(HelpTestCase):
"""Make sure that argument help aligns when options are longer"""
diff -r 3a1db0d2747e Lib/test/test_array.py
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test the arraymodule.
Roger E. Masse
"""
@@ -9,6 +8,7 @@
from weakref import proxy
import array, cStringIO
from cPickle import loads, dumps, HIGHEST_PROTOCOL
+import sys
class ArraySubclass(array.array):
pass
@@ -49,7 +49,7 @@
def test_constructor(self):
a = array.array(self.typecode)
self.assertEqual(a.typecode, self.typecode)
- self.assertTrue(a.itemsize>=self.minitemsize)
+ self.assertGreaterEqual(a.itemsize, self.minitemsize)
self.assertRaises(TypeError, array.array, self.typecode, None)
def test_len(self):
@@ -253,39 +253,39 @@
def test_cmp(self):
a = array.array(self.typecode, self.example)
- self.assertTrue((a == 42) is False)
- self.assertTrue((a != 42) is True)
+ self.assertIs(a == 42, False)
+ self.assertIs(a != 42, True)
- self.assertTrue((a == a) is True)
- self.assertTrue((a != a) is False)
- self.assertTrue((a < a) is False)
- self.assertTrue((a <= a) is True)
- self.assertTrue((a > a) is False)
- self.assertTrue((a >= a) is True)
+ self.assertIs(a == a, True)
+ self.assertIs(a != a, False)
+ self.assertIs(a < a, False)
+ self.assertIs(a <= a, True)
+ self.assertIs(a > a, False)
+ self.assertIs(a >= a, True)
al = array.array(self.typecode, self.smallerexample)
ab = array.array(self.typecode, self.biggerexample)
- self.assertTrue((a == 2*a) is False)
- self.assertTrue((a != 2*a) is True)
- self.assertTrue((a < 2*a) is True)
- self.assertTrue((a <= 2*a) is True)
- self.assertTrue((a > 2*a) is False)
- self.assertTrue((a >= 2*a) is False)
+ self.assertIs(a == 2*a, False)
+ self.assertIs(a != 2*a, True)
+ self.assertIs(a < 2*a, True)
+ self.assertIs(a <= 2*a, True)
+ self.assertIs(a > 2*a, False)
+ self.assertIs(a >= 2*a, False)
- self.assertTrue((a == al) is False)
- self.assertTrue((a != al) is True)
- self.assertTrue((a < al) is False)
- self.assertTrue((a <= al) is False)
- self.assertTrue((a > al) is True)
- self.assertTrue((a >= al) is True)
+ self.assertIs(a == al, False)
+ self.assertIs(a != al, True)
+ self.assertIs(a < al, False)
+ self.assertIs(a <= al, False)
+ self.assertIs(a > al, True)
+ self.assertIs(a >= al, True)
- self.assertTrue((a == ab) is False)
- self.assertTrue((a != ab) is True)
- self.assertTrue((a < ab) is True)
- self.assertTrue((a <= ab) is True)
- self.assertTrue((a > ab) is False)
- self.assertTrue((a >= ab) is False)
+ self.assertIs(a == ab, False)
+ self.assertIs(a != ab, True)
+ self.assertIs(a < ab, True)
+ self.assertIs(a <= ab, True)
+ self.assertIs(a > ab, False)
+ self.assertIs(a >= ab, False)
def test_add(self):
a = array.array(self.typecode, self.example) \
@@ -304,7 +304,7 @@
a = array.array(self.typecode, self.example[::-1])
b = a
a += array.array(self.typecode, 2*self.example)
- self.assertTrue(a is b)
+ self.assertIs(a, b)
self.assertEqual(
a,
array.array(self.typecode, self.example[::-1]+2*self.example)
@@ -353,22 +353,22 @@
b = a
a *= 5
- self.assertTrue(a is b)
+ self.assertIs(a, b)
self.assertEqual(
a,
array.array(self.typecode, 5*self.example)
)
a *= 0
- self.assertTrue(a is b)
+ self.assertIs(a, b)
self.assertEqual(a, array.array(self.typecode))
a *= 1000
- self.assertTrue(a is b)
+ self.assertIs(a, b)
self.assertEqual(a, array.array(self.typecode))
a *= -1
- self.assertTrue(a is b)
+ self.assertIs(a, b)
self.assertEqual(a, array.array(self.typecode))
a = array.array(self.typecode, self.example)
@@ -753,7 +753,7 @@
try:
import gc
except ImportError:
- return
+ self.skipTest('gc module not available')
a = array.array(self.typecode)
l = [iter(a)]
l.append(l)
@@ -772,15 +772,15 @@
s = None
self.assertRaises(ReferenceError, len, p)
+ @unittest.skipUnless(hasattr(sys, 'getrefcount'),
+ 'test needs sys.getrefcount()')
def test_bug_782369(self):
- import sys
- if hasattr(sys, "getrefcount"):
- for i in range(10):
- b = array.array('B', range(64))
- rc = sys.getrefcount(10)
- for i in range(10):
- b = array.array('B', range(64))
- self.assertEqual(rc, sys.getrefcount(10))
+ for i in range(10):
+ b = array.array('B', range(64))
+ rc = sys.getrefcount(10)
+ for i in range(10):
+ b = array.array('B', range(64))
+ self.assertEqual(rc, sys.getrefcount(10))
def test_subclass_with_kwargs(self):
# SF bug #1486663 -- this used to erroneously raise a TypeError
diff -r 3a1db0d2747e Lib/test/test_binhex.py
--- a/Lib/test/test_binhex.py
+++ b/Lib/test/test_binhex.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for the binhex C module
Uses the mechanism of the python binhex module
diff -r 3a1db0d2747e Lib/test/test_bsddb.py
--- a/Lib/test/test_bsddb.py
+++ b/Lib/test/test_bsddb.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for the bsddb C module by Roger E. Masse
Adapted to unittest format and expanded scope by Raymond Hettinger
"""
@@ -47,10 +46,7 @@
self.assertIn('discovered', self.f.values())
def test_close_and_reopen(self):
- if self.fname is None:
- # if we're using an in-memory only db, we can't reopen it
- # so finish here.
- return
+ self.assertIsNotNone(self.fname)
self.f.close()
self.f = self.openmethod[0](self.fname, 'w')
for k, v in self.d.iteritems():
@@ -309,8 +305,7 @@
self.assertEqual(self.f[k], v)
def test_keyordering(self):
- if self.openmethod[0] is not bsddb.btopen:
- return
+ self.assertIs(self.openmethod[0], bsddb.btopen)
keys = self.d.keys()
keys.sort()
self.assertEqual(self.f.first()[0], keys[0])
@@ -327,19 +322,34 @@
fname = None
openmethod = [bsddb.btopen]
+ # if we're using an in-memory only db, we can't reopen it
+ test_close_and_reopen = None
+
class TestBTree_InMemory_Truncate(TestBSDDB):
fname = None
openflag = 'n'
openmethod = [bsddb.btopen]
+ # if we're using an in-memory only db, we can't reopen it
+ test_close_and_reopen = None
+
class TestHashTable(TestBSDDB):
fname = test_support.TESTFN
openmethod = [bsddb.hashopen]
+ # keyordering is specific to btopen method
+ test_keyordering = None
+
class TestHashTable_InMemory(TestBSDDB):
fname = None
openmethod = [bsddb.hashopen]
+ # if we're using an in-memory only db, we can't reopen it
+ test_close_and_reopen = None
+
+ # keyordering is specific to btopen method
+ test_keyordering = None
+
## # (bsddb.rnopen,'Record Numbers'), 'put' for RECNO for bsddb 1.85
## # appears broken... at least on
## # Solaris Intel - rmasse 1/97
diff -r 3a1db0d2747e Lib/test/test_builtin.py
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -447,59 +447,6 @@
return 'a'
self.assertRaises(TypeError, eval, 'dir()', globals(), C())
- # Done outside of the method test_z to get the correct scope
- z = 0
- f = open(TESTFN, 'w')
- f.write('z = z+1\n')
- f.write('z = z*2\n')
- f.close()
- with check_py3k_warnings(("execfile.. not supported in 3.x",
- DeprecationWarning)):
- execfile(TESTFN)
-
- def test_execfile(self):
- global numruns
- if numruns:
- return
- numruns += 1
-
- globals = {'a': 1, 'b': 2}
- locals = {'b': 200, 'c': 300}
-
- self.assertEqual(self.__class__.z, 2)
- globals['z'] = 0
- execfile(TESTFN, globals)
- self.assertEqual(globals['z'], 2)
- locals['z'] = 0
- execfile(TESTFN, globals, locals)
- self.assertEqual(locals['z'], 2)
-
- class M:
- "Test mapping interface versus possible calls from execfile()."
- def __init__(self):
- self.z = 10
- def __getitem__(self, key):
- if key == 'z':
- return self.z
- raise KeyError
- def __setitem__(self, key, value):
- if key == 'z':
- self.z = value
- return
- raise KeyError
-
- locals = M()
- locals['z'] = 0
- execfile(TESTFN, globals, locals)
- self.assertEqual(locals['z'], 2)
-
- unlink(TESTFN)
- self.assertRaises(TypeError, execfile)
- self.assertRaises(TypeError, execfile, TESTFN, {}, ())
- import os
- self.assertRaises(IOError, execfile, os.curdir)
- self.assertRaises(IOError, execfile, "I_dont_exist")
-
def test_filter(self):
self.assertEqual(filter(lambda c: 'a' <= c <= 'z', 'Hello World'), 'elloorld')
self.assertEqual(filter(None, [1, 'hello', [], [3], '', None, 9, 0]), [1, 'hello', [3], 9])
@@ -1646,6 +1593,56 @@
self.assertRaises(ValueError, x.translate, "1", 1)
self.assertRaises(TypeError, x.translate, "1"*256, 1)
+class TestExecFile(unittest.TestCase):
+ # Done outside of the method test_z to get the correct scope
+ z = 0
+ f = open(TESTFN, 'w')
+ f.write('z = z+1\n')
+ f.write('z = z*2\n')
+ f.close()
+ with check_py3k_warnings(("execfile.. not supported in 3.x",
+ DeprecationWarning)):
+ execfile(TESTFN)
+
+ def test_execfile(self):
+ globals = {'a': 1, 'b': 2}
+ locals = {'b': 200, 'c': 300}
+
+ self.assertEqual(self.__class__.z, 2)
+ globals['z'] = 0
+ execfile(TESTFN, globals)
+ self.assertEqual(globals['z'], 2)
+ locals['z'] = 0
+ execfile(TESTFN, globals, locals)
+ self.assertEqual(locals['z'], 2)
+
+ class M:
+ "Test mapping interface versus possible calls from execfile()."
+ def __init__(self):
+ self.z = 10
+ def __getitem__(self, key):
+ if key == 'z':
+ return self.z
+ raise KeyError
+ def __setitem__(self, key, value):
+ if key == 'z':
+ self.z = value
+ return
+ raise KeyError
+
+ locals = M()
+ locals['z'] = 0
+ execfile(TESTFN, globals, locals)
+ self.assertEqual(locals['z'], 2)
+
+ unlink(TESTFN)
+ self.assertRaises(TypeError, execfile)
+ self.assertRaises(TypeError, execfile, TESTFN, {}, ())
+ import os
+ self.assertRaises(IOError, execfile, os.curdir)
+ self.assertRaises(IOError, execfile, "I_dont_exist")
+
+
class TestSorted(unittest.TestCase):
def test_basic(self):
@@ -1693,6 +1690,12 @@
run_unittest(*args)
def test_main(verbose=None):
+ global numruns
+ if not numruns:
+ with check_py3k_warnings(
+ (".+ not supported in 3.x", DeprecationWarning)):
+ run_unittest(TestExecFile)
+ numruns += 1
test_classes = (BuiltinTest, TestSorted)
_run_unittest(*test_classes)
diff -r 3a1db0d2747e Lib/test/test_bz2.py
--- a/Lib/test/test_bz2.py
+++ b/Lib/test/test_bz2.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
from test import test_support
from test.test_support import TESTFN, _4G, bigmemtest, import_module, findfile
@@ -325,6 +324,21 @@
self.assertRaises(ValueError, f.readline)
self.assertRaises(ValueError, f.readlines)
+ @unittest.skipIf(sys.platform == 'win32',
+ 'test depends on being able to delete a still-open file,'
+ ' which is not possible on Windows')
+ def testInitNonExistentFile(self):
+ # Issue #19878: Should not segfault when __init__ with non-existent
+ # file for the second time.
+ self.createTempFile()
+ # Test close():
+ with BZ2File(self.filename, "wb") as f:
+ self.assertRaises(IOError, f.__init__, "non-existent-file")
+ # Test object deallocation without call to close():
+ f = bz2.BZ2File(self.filename)
+ self.assertRaises(IOError, f.__init__, "non-existent-file")
+ del f
+
class BZ2CompressorTest(BaseTest):
def testCompress(self):
# "Test BZ2Compressor.compress()/flush()"
diff -r 3a1db0d2747e Lib/test/test_capi.py
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -13,7 +13,9 @@
except ImportError:
thread = None
threading = None
-import _testcapi
+# Skip this test if the _testcapi module isn't available.
+_testcapi = test_support.import_module('_testcapi')
+
@unittest.skipUnless(threading, 'Threading required for this test.')
class TestPendingCalls(unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/test_cd.py
--- a/Lib/test/test_cd.py
+++ b/Lib/test/test_cd.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Whimpy test script for the cd module
Roger E. Masse
"""
diff -r 3a1db0d2747e Lib/test/test_cfgparser.py
--- a/Lib/test/test_cfgparser.py
+++ b/Lib/test/test_cfgparser.py
@@ -284,13 +284,17 @@
cf.set("sect", "option1", mystr("splat"))
cf.set("sect", "option2", "splat")
cf.set("sect", "option2", mystr("splat"))
+
+ def test_set_unicode(self):
try:
unicode
except NameError:
- pass
- else:
- cf.set("sect", "option1", unicode("splat"))
- cf.set("sect", "option2", unicode("splat"))
+ self.skipTest('no unicode support')
+
+ cf = self.fromstring("[sect]\n"
+ "option1=foo\n")
+ cf.set("sect", "option1", unicode("splat"))
+ cf.set("sect", "option2", unicode("splat"))
def test_read_returns_file_list(self):
file1 = test_support.findfile("cfgparser.1")
diff -r 3a1db0d2747e Lib/test/test_cgi.py
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -5,6 +5,8 @@
import tempfile
import unittest
+from collections import namedtuple
+
class HackedSysModule:
# The regression test will have real values in sys.argv, which
# will completely confuse the test of the cgi module
@@ -230,7 +232,15 @@
# if we're not chunking properly, readline is only called twice
# (by read_binary); if we are chunking properly, it will be called 5 times
# as long as the chunksize is 1 << 16.
- self.assertTrue(f.numcalls > 2)
+ self.assertGreater(f.numcalls, 2)
+
+ def test_fieldstorage_invalid(self):
+ fs = cgi.FieldStorage()
+ self.assertFalse(fs)
+ self.assertRaises(TypeError, bool(fs))
+ self.assertEqual(list(fs), list(fs.keys()))
+ fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue'))
+ self.assertTrue(fs)
def test_fieldstorage_multipart(self):
#Test basic FieldStorage multipart parsing
diff -r 3a1db0d2747e Lib/test/test_cl.py
--- a/Lib/test/test_cl.py
+++ b/Lib/test/test_cl.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Whimpy test script for the cl module
Roger E. Masse
"""
diff -r 3a1db0d2747e Lib/test/test_cmath.py
--- a/Lib/test/test_cmath.py
+++ b/Lib/test/test_cmath.py
@@ -282,7 +282,7 @@
def test_specific_values(self):
if not float.__getformat__("double").startswith("IEEE"):
- return
+ self.skipTest('needs IEEE double')
def rect_complex(z):
"""Wrapped version of rect that accepts a complex number instead of
diff -r 3a1db0d2747e Lib/test/test_cmd.py
--- a/Lib/test/test_cmd.py
+++ b/Lib/test/test_cmd.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
"""
Test script for the 'cmd' module
Original by Michael Schneider
diff -r 3a1db0d2747e Lib/test/test_code.py
--- a/Lib/test/test_code.py
+++ b/Lib/test/test_code.py
@@ -82,7 +82,7 @@
import unittest
import weakref
-import _testcapi
+from test.test_support import run_doctest, run_unittest, cpython_only
def consts(t):
@@ -104,7 +104,9 @@
class CodeTest(unittest.TestCase):
+ @cpython_only
def test_newempty(self):
+ import _testcapi
co = _testcapi.code_newempty("filename", "funcname", 15)
self.assertEqual(co.co_filename, "filename")
self.assertEqual(co.co_name, "funcname")
@@ -137,7 +139,6 @@
def test_main(verbose=None):
- from test.test_support import run_doctest, run_unittest
from test import test_code
run_doctest(test_code, verbose)
run_unittest(CodeTest, CodeWeakRefTest)
diff -r 3a1db0d2747e Lib/test/test_codecencodings_cn.py
--- a/Lib/test/test_codecencodings_cn.py
+++ b/Lib/test/test_codecencodings_cn.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecencodings_cn.py
# Codec encoding tests for PRC encodings.
diff -r 3a1db0d2747e Lib/test/test_codecencodings_hk.py
--- a/Lib/test/test_codecencodings_hk.py
+++ b/Lib/test/test_codecencodings_hk.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecencodings_hk.py
# Codec encoding tests for HongKong encodings.
diff -r 3a1db0d2747e Lib/test/test_codecencodings_iso2022.py
--- a/Lib/test/test_codecencodings_iso2022.py
+++ b/Lib/test/test_codecencodings_iso2022.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# Codec encoding tests for ISO 2022 encodings.
from test import test_support
@@ -36,6 +34,7 @@
# iso2022_kr.txt cannot be used to test "chunk coding": the escape
# sequence is only written on the first line
+ @unittest.skip('iso2022_kr.txt cannot be used to test "chunk coding"')
def test_chunkcoding(self):
pass
diff -r 3a1db0d2747e Lib/test/test_codecencodings_jp.py
--- a/Lib/test/test_codecencodings_jp.py
+++ b/Lib/test/test_codecencodings_jp.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecencodings_jp.py
# Codec encoding tests for Japanese encodings.
diff -r 3a1db0d2747e Lib/test/test_codecencodings_kr.py
--- a/Lib/test/test_codecencodings_kr.py
+++ b/Lib/test/test_codecencodings_kr.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecencodings_kr.py
# Codec encoding tests for ROK encodings.
diff -r 3a1db0d2747e Lib/test/test_codecencodings_tw.py
--- a/Lib/test/test_codecencodings_tw.py
+++ b/Lib/test/test_codecencodings_tw.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecencodings_tw.py
# Codec encoding tests for ROC encodings.
diff -r 3a1db0d2747e Lib/test/test_codecmaps_cn.py
--- a/Lib/test/test_codecmaps_cn.py
+++ b/Lib/test/test_codecmaps_cn.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecmaps_cn.py
# Codec mapping tests for PRC encodings
diff -r 3a1db0d2747e Lib/test/test_codecmaps_hk.py
--- a/Lib/test/test_codecmaps_hk.py
+++ b/Lib/test/test_codecmaps_hk.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecmaps_hk.py
# Codec mapping tests for HongKong encodings
diff -r 3a1db0d2747e Lib/test/test_codecmaps_jp.py
--- a/Lib/test/test_codecmaps_jp.py
+++ b/Lib/test/test_codecmaps_jp.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecmaps_jp.py
# Codec mapping tests for Japanese encodings
diff -r 3a1db0d2747e Lib/test/test_codecmaps_kr.py
--- a/Lib/test/test_codecmaps_kr.py
+++ b/Lib/test/test_codecmaps_kr.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecmaps_kr.py
# Codec mapping tests for ROK encodings
diff -r 3a1db0d2747e Lib/test/test_codecmaps_tw.py
--- a/Lib/test/test_codecmaps_tw.py
+++ b/Lib/test/test_codecmaps_tw.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# test_codecmaps_tw.py
# Codec mapping tests for ROC encodings
diff -r 3a1db0d2747e Lib/test/test_codecs.py
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -2,7 +2,7 @@
import unittest
import codecs
import locale
-import sys, StringIO, _testcapi
+import sys, StringIO
def coding_checker(self, coder):
def check(input, expect):
@@ -97,19 +97,20 @@
self.assertEqual(readalllines(s, True, 10), sexpected)
self.assertEqual(readalllines(s, False, 10), sexpectednoends)
+ lineends = ("\n", "\r\n", "\r", u"\u2028")
# Test long lines (multiple calls to read() in readline())
vw = []
vwo = []
- for (i, lineend) in enumerate(u"\n \r\n \r \u2028".split()):
- vw.append((i*200)*u"\3042" + lineend)
- vwo.append((i*200)*u"\3042")
- self.assertEqual(readalllines("".join(vw), True), "".join(vw))
- self.assertEqual(readalllines("".join(vw), False),"".join(vwo))
+ for (i, lineend) in enumerate(lineends):
+ vw.append((i*200+200)*u"\u3042" + lineend)
+ vwo.append((i*200+200)*u"\u3042")
+ self.assertEqual(readalllines("".join(vw), True), "|".join(vw))
+ self.assertEqual(readalllines("".join(vw), False), "|".join(vwo))
# Test lines where the first read might end with \r, so the
# reader has to look ahead whether this is a lone \r or a \r\n
for size in xrange(80):
- for lineend in u"\n \r\n \r \u2028".split():
+ for lineend in lineends:
s = 10*(size*u"a" + lineend + u"xxx\n")
reader = getreader(s)
for i in xrange(10):
@@ -117,12 +118,54 @@
reader.readline(keepends=True),
size*u"a" + lineend,
)
+ self.assertEqual(
+ reader.readline(keepends=True),
+ "xxx\n",
+ )
reader = getreader(s)
for i in xrange(10):
self.assertEqual(
reader.readline(keepends=False),
size*u"a",
)
+ self.assertEqual(
+ reader.readline(keepends=False),
+ "xxx",
+ )
+
+ def test_mixed_readline_and_read(self):
+ lines = ["Humpty Dumpty sat on a wall,\n",
+ "Humpty Dumpty had a great fall.\r\n",
+ "All the king's horses and all the king's men\r",
+ "Couldn't put Humpty together again."]
+ data = ''.join(lines)
+ def getreader():
+ stream = StringIO.StringIO(data.encode(self.encoding))
+ return codecs.getreader(self.encoding)(stream)
+
+ # Issue #8260: Test readline() followed by read()
+ f = getreader()
+ self.assertEqual(f.readline(), lines[0])
+ self.assertEqual(f.read(), ''.join(lines[1:]))
+ self.assertEqual(f.read(), '')
+
+ # Issue #16636: Test readline() followed by readlines()
+ f = getreader()
+ self.assertEqual(f.readline(), lines[0])
+ self.assertEqual(f.readlines(), lines[1:])
+ self.assertEqual(f.read(), '')
+
+ # Test read() followed by read()
+ f = getreader()
+ self.assertEqual(f.read(size=40, chars=5), data[:5])
+ self.assertEqual(f.read(), data[5:])
+ self.assertEqual(f.read(), '')
+
+ # Issue #12446: Test read() followed by readlines()
+ f = getreader()
+ self.assertEqual(f.read(size=40, chars=5), data[:5])
+ self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:])
+ self.assertEqual(f.read(), '')
def test_bug1175396(self):
s = [
@@ -1496,7 +1539,7 @@
class BasicUnicodeTest(unittest.TestCase):
def test_basics(self):
- s = u"abc123" # all codecs should be able to encode these
+ s = u"abc123" # all codecs should be able to encode these
for encoding in all_unicode_encodings:
name = codecs.lookup(encoding).name
if encoding.endswith("_codec"):
@@ -1505,9 +1548,9 @@
name = "latin_1"
self.assertEqual(encoding.replace("_", "-"), name.replace("_", "-"))
(bytes, size) = codecs.getencoder(encoding)(s)
- self.assertEqual(size, len(s), "%r != %r (encoding=%r)" % (size, len(s), encoding))
+ self.assertEqual(size, len(s), "encoding=%r" % encoding)
(chars, size) = codecs.getdecoder(encoding)(bytes)
- self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding))
+ self.assertEqual(chars, s, "encoding=%r" % encoding)
if encoding not in broken_unicode_with_streams:
# check stream reader/writer
@@ -1523,15 +1566,13 @@
for c in encodedresult:
q.write(c)
decodedresult += reader.read()
- self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+ self.assertEqual(decodedresult, s, "encoding=%r" % encoding)
if encoding not in broken_incremental_coders:
- # check incremental decoder/encoder (fetched via the Python
- # and C API) and iterencode()/iterdecode()
+ # check incremental decoder/encoder and iterencode()/iterdecode()
try:
encoder = codecs.getincrementalencoder(encoding)()
- cencoder = _testcapi.codec_incrementalencoder(encoding)
- except LookupError: # no IncrementalEncoder
+ except LookupError: # no IncrementalEncoder
pass
else:
# check incremental decoder/encoder
@@ -1544,45 +1585,71 @@
for c in encodedresult:
decodedresult += decoder.decode(c)
decodedresult += decoder.decode("", True)
- self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
-
- # check C API
- encodedresult = ""
- for c in s:
- encodedresult += cencoder.encode(c)
- encodedresult += cencoder.encode(u"", True)
- cdecoder = _testcapi.codec_incrementaldecoder(encoding)
- decodedresult = u""
- for c in encodedresult:
- decodedresult += cdecoder.decode(c)
- decodedresult += cdecoder.decode("", True)
- self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+ self.assertEqual(decodedresult, s,
+ "encoding=%r" % encoding)
# check iterencode()/iterdecode()
- result = u"".join(codecs.iterdecode(codecs.iterencode(s, encoding), encoding))
- self.assertEqual(result, s, "%r != %r (encoding=%r)" % (result, s, encoding))
+ result = u"".join(codecs.iterdecode(
+ codecs.iterencode(s, encoding), encoding))
+ self.assertEqual(result, s, "encoding=%r" % encoding)
# check iterencode()/iterdecode() with empty string
- result = u"".join(codecs.iterdecode(codecs.iterencode(u"", encoding), encoding))
+ result = u"".join(codecs.iterdecode(
+ codecs.iterencode(u"", encoding), encoding))
self.assertEqual(result, u"")
if encoding not in only_strict_mode:
# check incremental decoder/encoder with errors argument
try:
encoder = codecs.getincrementalencoder(encoding)("ignore")
- cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore")
- except LookupError: # no IncrementalEncoder
+ except LookupError: # no IncrementalEncoder
pass
else:
encodedresult = "".join(encoder.encode(c) for c in s)
decoder = codecs.getincrementaldecoder(encoding)("ignore")
- decodedresult = u"".join(decoder.decode(c) for c in encodedresult)
- self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+ decodedresult = u"".join(decoder.decode(c)
+ for c in encodedresult)
+ self.assertEqual(decodedresult, s,
+ "encoding=%r" % encoding)
+ @test_support.cpython_only
+ def test_basics_capi(self):
+ from _testcapi import codec_incrementalencoder, codec_incrementaldecoder
+ s = u"abc123" # all codecs should be able to encode these
+ for encoding in all_unicode_encodings:
+ if encoding not in broken_incremental_coders:
+ # check incremental decoder/encoder and iterencode()/iterdecode()
+ try:
+ cencoder = codec_incrementalencoder(encoding)
+ except LookupError: # no IncrementalEncoder
+ pass
+ else:
+ # check C API
+ encodedresult = ""
+ for c in s:
+ encodedresult += cencoder.encode(c)
+ encodedresult += cencoder.encode(u"", True)
+ cdecoder = codec_incrementaldecoder(encoding)
+ decodedresult = u""
+ for c in encodedresult:
+ decodedresult += cdecoder.decode(c)
+ decodedresult += cdecoder.decode("", True)
+ self.assertEqual(decodedresult, s,
+ "encoding=%r" % encoding)
+
+ if encoding not in only_strict_mode:
+ # check incremental decoder/encoder with errors argument
+ try:
+ cencoder = codec_incrementalencoder(encoding, "ignore")
+ except LookupError: # no IncrementalEncoder
+ pass
+ else:
encodedresult = "".join(cencoder.encode(c) for c in s)
- cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore")
- decodedresult = u"".join(cdecoder.decode(c) for c in encodedresult)
- self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+ cdecoder = codec_incrementaldecoder(encoding, "ignore")
+ decodedresult = u"".join(cdecoder.decode(c)
+ for c in encodedresult)
+ self.assertEqual(decodedresult, s,
+ "encoding=%r" % encoding)
def test_seek(self):
# all codecs should be able to encode these
diff -r 3a1db0d2747e Lib/test/test_collections.py
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -594,6 +594,35 @@
s |= s
self.assertEqual(s, full)
+ def test_issue16373(self):
+ # Recursion error comparing comparable and noncomparable
+ # Set instances
+ class MyComparableSet(Set):
+ def __contains__(self, x):
+ return False
+ def __len__(self):
+ return 0
+ def __iter__(self):
+ return iter([])
+ class MyNonComparableSet(Set):
+ def __contains__(self, x):
+ return False
+ def __len__(self):
+ return 0
+ def __iter__(self):
+ return iter([])
+ def __le__(self, x):
+ return NotImplemented
+ def __lt__(self, x):
+ return NotImplemented
+
+ cs = MyComparableSet()
+ ncs = MyNonComparableSet()
+ self.assertFalse(ncs < cs)
+ self.assertFalse(ncs <= cs)
+ self.assertFalse(cs > ncs)
+ self.assertFalse(cs >= ncs)
+
def test_Mapping(self):
for sample in [dict]:
self.assertIsInstance(sample(), Mapping)
diff -r 3a1db0d2747e Lib/test/test_compileall.py
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -31,11 +31,10 @@
compare = struct.pack('<4sl', imp.get_magic(), mtime)
return data, compare
+ @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
def recreation_check(self, metadata):
"""Check that compileall recreates bytecode when the new metadata is
used."""
- if not hasattr(os, 'stat'):
- return
py_compile.compile(self.source_path)
self.assertEqual(*self.data())
with open(self.bc_path, 'rb') as file:
diff -r 3a1db0d2747e Lib/test/test_cookielib.py
--- a/Lib/test/test_cookielib.py
+++ b/Lib/test/test_cookielib.py
@@ -26,8 +26,9 @@
az = time2isoz()
bz = time2isoz(500000)
for text in (az, bz):
- self.assertTrue(re.search(r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$", text),
- "bad time2isoz format: %s %s" % (az, bz))
+ self.assertRegexpMatches(text,
+ r"^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$",
+ "bad time2isoz format: %s %s" % (az, bz))
def test_http2time(self):
from cookielib import http2time
@@ -75,12 +76,9 @@
"%s => '%s' (%s)" % (test_t, result, expected))
for s in tests:
- t = http2time(s)
- t2 = http2time(s.lower())
- t3 = http2time(s.upper())
-
- self.assertTrue(t == t2 == t3 == test_t,
- "'%s' => %s, %s, %s (%s)" % (s, t, t2, t3, test_t))
+ self.assertEqual(http2time(s), test_t, s)
+ self.assertEqual(http2time(s.lower()), test_t, s.lower())
+ self.assertEqual(http2time(s.upper()), test_t, s.upper())
def test_http2time_garbage(self):
from cookielib import http2time
@@ -367,7 +365,7 @@
request = urllib2.Request(url)
r = pol.domain_return_ok(domain, request)
if ok: self.assertTrue(r)
- else: self.assertTrue(not r)
+ else: self.assertFalse(r)
def test_missing_value(self):
from cookielib import MozillaCookieJar, lwp_cookie_str
@@ -379,10 +377,10 @@
interact_netscape(c, "http://www.acme.com/", 'eggs')
interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/')
cookie = c._cookies["www.acme.com"]["/"]["eggs"]
- self.assertTrue(cookie.value is None)
+ self.assertIsNone(cookie.value)
self.assertEqual(cookie.name, "eggs")
cookie = c._cookies["www.acme.com"]['/foo/']['"spam"']
- self.assertTrue(cookie.value is None)
+ self.assertIsNone(cookie.value)
self.assertEqual(cookie.name, '"spam"')
self.assertEqual(lwp_cookie_str(cookie), (
r'"spam"; path="/foo/"; domain="www.acme.com"; '
@@ -426,7 +424,7 @@
try:
cookie = c._cookies["www.example.com"]["/"]["ni"]
except KeyError:
- self.assertTrue(version is None) # didn't expect a stored cookie
+ self.assertIsNone(version) # didn't expect a stored cookie
else:
self.assertEqual(cookie.version, version)
# 2965 cookies are unaffected
@@ -452,26 +450,26 @@
self.assertEqual(cookie.domain, ".acme.com")
self.assertTrue(cookie.domain_specified)
self.assertEqual(cookie.port, DEFAULT_HTTP_PORT)
- self.assertTrue(not cookie.port_specified)
+ self.assertFalse(cookie.port_specified)
# case is preserved
- self.assertTrue(cookie.has_nonstandard_attr("blArgh") and
- not cookie.has_nonstandard_attr("blargh"))
+ self.assertTrue(cookie.has_nonstandard_attr("blArgh"))
+ self.assertFalse(cookie.has_nonstandard_attr("blargh"))
cookie = c._cookies["www.acme.com"]["/"]["ni"]
self.assertEqual(cookie.domain, "www.acme.com")
- self.assertTrue(not cookie.domain_specified)
+ self.assertFalse(cookie.domain_specified)
self.assertEqual(cookie.port, "80,8080")
self.assertTrue(cookie.port_specified)
cookie = c._cookies["www.acme.com"]["/"]["nini"]
- self.assertTrue(cookie.port is None)
- self.assertTrue(not cookie.port_specified)
+ self.assertIsNone(cookie.port)
+ self.assertFalse(cookie.port_specified)
# invalid expires should not cause cookie to be dropped
foo = c._cookies["www.acme.com"]["/"]["foo"]
spam = c._cookies["www.acme.com"]["/"]["foo"]
- self.assertTrue(foo.expires is None)
- self.assertTrue(spam.expires is None)
+ self.assertIsNone(foo.expires)
+ self.assertIsNone(spam.expires)
def test_ns_parser_special_names(self):
# names such as 'expires' are not special in first name=value pair
@@ -655,12 +653,12 @@
from cookielib import is_HDN
self.assertTrue(is_HDN("foo.bar.com"))
self.assertTrue(is_HDN("1foo2.3bar4.5com"))
- self.assertTrue(not is_HDN("192.168.1.1"))
- self.assertTrue(not is_HDN(""))
- self.assertTrue(not is_HDN("."))
- self.assertTrue(not is_HDN(".foo.bar.com"))
- self.assertTrue(not is_HDN("..foo"))
- self.assertTrue(not is_HDN("foo."))
+ self.assertFalse(is_HDN("192.168.1.1"))
+ self.assertFalse(is_HDN(""))
+ self.assertFalse(is_HDN("."))
+ self.assertFalse(is_HDN(".foo.bar.com"))
+ self.assertFalse(is_HDN("..foo"))
+ self.assertFalse(is_HDN("foo."))
def test_reach(self):
from cookielib import reach
@@ -676,39 +674,39 @@
def test_domain_match(self):
from cookielib import domain_match, user_domain_match
self.assertTrue(domain_match("192.168.1.1", "192.168.1.1"))
- self.assertTrue(not domain_match("192.168.1.1", ".168.1.1"))
+ self.assertFalse(domain_match("192.168.1.1", ".168.1.1"))
self.assertTrue(domain_match("x.y.com", "x.Y.com"))
self.assertTrue(domain_match("x.y.com", ".Y.com"))
- self.assertTrue(not domain_match("x.y.com", "Y.com"))
+ self.assertFalse(domain_match("x.y.com", "Y.com"))
self.assertTrue(domain_match("a.b.c.com", ".c.com"))
- self.assertTrue(not domain_match(".c.com", "a.b.c.com"))
+ self.assertFalse(domain_match(".c.com", "a.b.c.com"))
self.assertTrue(domain_match("example.local", ".local"))
- self.assertTrue(not domain_match("blah.blah", ""))
- self.assertTrue(not domain_match("", ".rhubarb.rhubarb"))
+ self.assertFalse(domain_match("blah.blah", ""))
+ self.assertFalse(domain_match("", ".rhubarb.rhubarb"))
self.assertTrue(domain_match("", ""))
self.assertTrue(user_domain_match("acme.com", "acme.com"))
- self.assertTrue(not user_domain_match("acme.com", ".acme.com"))
+ self.assertFalse(user_domain_match("acme.com", ".acme.com"))
self.assertTrue(user_domain_match("rhubarb.acme.com", ".acme.com"))
self.assertTrue(user_domain_match("www.rhubarb.acme.com", ".acme.com"))
self.assertTrue(user_domain_match("x.y.com", "x.Y.com"))
self.assertTrue(user_domain_match("x.y.com", ".Y.com"))
- self.assertTrue(not user_domain_match("x.y.com", "Y.com"))
+ self.assertFalse(user_domain_match("x.y.com", "Y.com"))
self.assertTrue(user_domain_match("y.com", "Y.com"))
- self.assertTrue(not user_domain_match(".y.com", "Y.com"))
+ self.assertFalse(user_domain_match(".y.com", "Y.com"))
self.assertTrue(user_domain_match(".y.com", ".Y.com"))
self.assertTrue(user_domain_match("x.y.com", ".com"))
- self.assertTrue(not user_domain_match("x.y.com", "com"))
- self.assertTrue(not user_domain_match("x.y.com", "m"))
- self.assertTrue(not user_domain_match("x.y.com", ".m"))
- self.assertTrue(not user_domain_match("x.y.com", ""))
- self.assertTrue(not user_domain_match("x.y.com", "."))
+ self.assertFalse(user_domain_match("x.y.com", "com"))
+ self.assertFalse(user_domain_match("x.y.com", "m"))
+ self.assertFalse(user_domain_match("x.y.com", ".m"))
+ self.assertFalse(user_domain_match("x.y.com", ""))
+ self.assertFalse(user_domain_match("x.y.com", "."))
self.assertTrue(user_domain_match("192.168.1.1", "192.168.1.1"))
# not both HDNs, so must string-compare equal to match
- self.assertTrue(not user_domain_match("192.168.1.1", ".168.1.1"))
- self.assertTrue(not user_domain_match("192.168.1.1", "."))
+ self.assertFalse(user_domain_match("192.168.1.1", ".168.1.1"))
+ self.assertFalse(user_domain_match("192.168.1.1", "."))
# empty string is a special case
- self.assertTrue(not user_domain_match("192.168.1.1", ""))
+ self.assertFalse(user_domain_match("192.168.1.1", ""))
def test_wrong_domain(self):
# Cookies whose effective request-host name does not domain-match the
@@ -865,7 +863,7 @@
self.assertEqual(len(c), 2)
# ... and check is doesn't get returned
c.add_cookie_header(req)
- self.assertTrue(not req.has_header("Cookie"))
+ self.assertFalse(req.has_header("Cookie"))
def test_domain_block(self):
from cookielib import CookieJar, DefaultCookiePolicy
@@ -892,8 +890,8 @@
self.assertEqual(len(c), 1)
req = Request("http://www.roadrunner.net/")
c.add_cookie_header(req)
- self.assertTrue((req.has_header("Cookie") and
- req.has_header("Cookie2")))
+ self.assertTrue(req.has_header("Cookie"))
+ self.assertTrue(req.has_header("Cookie2"))
c.clear()
pol.set_blocked_domains([".acme.com"])
@@ -908,7 +906,7 @@
self.assertEqual(len(c), 2)
# ... and check is doesn't get returned
c.add_cookie_header(req)
- self.assertTrue(not req.has_header("Cookie"))
+ self.assertFalse(req.has_header("Cookie"))
def test_secure(self):
from cookielib import CookieJar, DefaultCookiePolicy
@@ -928,8 +926,8 @@
url = "http://www.acme.com/"
int(c, url, "foo1=bar%s%s" % (vs, whitespace))
int(c, url, "foo2=bar%s; secure%s" % (vs, whitespace))
- self.assertTrue(
- not c._cookies["www.acme.com"]["/"]["foo1"].secure,
+ self.assertFalse(
+ c._cookies["www.acme.com"]["/"]["foo1"].secure,
"non-secure cookie registered secure")
self.assertTrue(
c._cookies["www.acme.com"]["/"]["foo2"].secure,
@@ -1011,8 +1009,8 @@
url = "http://foo.bar.com/"
interact_2965(c, url, "spam=eggs; Version=1; Port")
h = interact_2965(c, url)
- self.assertTrue(re.search("\$Port([^=]|$)", h),
- "port with no value not returned with no value")
+ self.assertRegexpMatches(h, "\$Port([^=]|$)",
+ "port with no value not returned with no value")
c = CookieJar(pol)
url = "http://foo.bar.com/"
@@ -1038,8 +1036,7 @@
'Comment="does anybody read these?"; '
'CommentURL="http://foo.bar.net/comment.html"')
h = interact_2965(c, url)
- self.assertTrue(
- "Comment" not in h,
+ self.assertNotIn("Comment", h,
"Comment or CommentURL cookie-attributes returned to server")
def test_Cookie_iterator(self):
@@ -1128,7 +1125,7 @@
headers = ["Set-Cookie: c=foo; expires=Foo Bar 12 33:22:11 2000"]
c = cookiejar_from_cookie_headers(headers)
cookie = c._cookies["www.example.com"]["/"]["c"]
- self.assertTrue(cookie.expires is None)
+ self.assertIsNone(cookie.expires)
class LWPCookieTests(TestCase):
@@ -1278,9 +1275,9 @@
req = Request("http://www.acme.com/ammo")
c.add_cookie_header(req)
- self.assertTrue(re.search(r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
- "PART_NUMBER=ROCKET_LAUNCHER_0001",
- req.get_header("Cookie")))
+ self.assertRegexpMatches(req.get_header("Cookie"),
+ r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
+ "PART_NUMBER=ROCKET_LAUNCHER_0001")
def test_ietf_example_1(self):
from cookielib import CookieJar, DefaultCookiePolicy
@@ -1314,7 +1311,7 @@
cookie = interact_2965(
c, 'http://www.acme.com/acme/login',
'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
- self.assertTrue(not cookie)
+ self.assertFalse(cookie)
#
# 3. User Agent -> Server
@@ -1336,9 +1333,8 @@
cookie = interact_2965(c, 'http://www.acme.com/acme/pickitem',
'Part_Number="Rocket_Launcher_0001"; '
'Version="1"; Path="/acme"');
- self.assertTrue(re.search(
- r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$',
- cookie))
+ self.assertRegexpMatches(cookie,
+ r'^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$')
#
# 5. User Agent -> Server
@@ -1361,11 +1357,11 @@
cookie = interact_2965(c, "http://www.acme.com/acme/shipping",
'Shipping="FedEx"; Version="1"; Path="/acme"')
- self.assertTrue(re.search(r'^\$Version="?1"?;', cookie))
- self.assertTrue(re.search(r'Part_Number="?Rocket_Launcher_0001"?;'
- '\s*\$Path="\/acme"', cookie))
- self.assertTrue(re.search(r'Customer="?WILE_E_COYOTE"?;\s*\$Path="\/acme"',
- cookie))
+ self.assertRegexpMatches(cookie, r'^\$Version="?1"?;')
+ self.assertRegexpMatches(cookie,
+ r'Part_Number="?Rocket_Launcher_0001"?;\s*\$Path="\/acme"')
+ self.assertRegexpMatches(cookie,
+ r'Customer="?WILE_E_COYOTE"?;\s*\$Path="\/acme"')
#
# 7. User Agent -> Server
@@ -1386,9 +1382,9 @@
# Transaction is complete.
cookie = interact_2965(c, "http://www.acme.com/acme/process")
- self.assertTrue(
- re.search(r'Shipping="?FedEx"?;\s*\$Path="\/acme"', cookie) and
- "WILE_E_COYOTE" in cookie)
+ self.assertRegexpMatches(cookie,
+ r'Shipping="?FedEx"?;\s*\$Path="\/acme"')
+ self.assertIn("WILE_E_COYOTE", cookie)
#
# The user agent makes a series of requests on the origin server, after
@@ -1437,8 +1433,8 @@
# than once.
cookie = interact_2965(c, "http://www.acme.com/acme/ammo/...")
- self.assertTrue(
- re.search(r"Riding_Rocket_0023.*Rocket_Launcher_0001", cookie))
+ self.assertRegexpMatches(cookie,
+ r"Riding_Rocket_0023.*Rocket_Launcher_0001")
# A subsequent request by the user agent to the (same) server for a URL of
# the form /acme/parts/ would include the following request header:
@@ -1466,7 +1462,7 @@
# illegal domain (no embedded dots)
cookie = interact_2965(c, "http://www.acme.com",
'foo=bar; domain=".com"; version=1')
- self.assertTrue(not c)
+ self.assertFalse(c)
# legal domain
cookie = interact_2965(c, "http://www.acme.com",
@@ -1559,11 +1555,12 @@
c, "http://www.acme.com/foo%2f%25/<<%0anew/",
'bar=baz; path="/foo/"; version=1');
version_re = re.compile(r'^\$version=\"?1\"?', re.I)
- self.assertTrue("foo=bar" in cookie and version_re.search(cookie))
+ self.assertIn("foo=bar", cookie)
+ self.assertRegexpMatches(cookie, version_re)
cookie = interact_2965(
c, "http://www.acme.com/foo/%25/<<%0anew/")
- self.assertTrue(not cookie)
+ self.assertFalse(cookie)
# unicode URL doesn't raise exception
cookie = interact_2965(c, u"http://www.acme.com/\xfc")
@@ -1740,13 +1737,12 @@
key = "%s_after" % cookie.value
counter[key] = counter[key] + 1
- self.assertTrue(not (
- # a permanent cookie got lost accidentally
- counter["perm_after"] != counter["perm_before"] or
+ # a permanent cookie got lost accidently
+ self.assertEqual(counter["perm_after"], counter["perm_before"])
# a session cookie hasn't been cleared
- counter["session_after"] != 0 or
+ self.assertEqual(counter["session_after"], 0)
# we didn't have session cookies in the first place
- counter["session_before"] == 0))
+ self.assertNotEqual(counter["session_before"], 0)
def test_main(verbose=None):
diff -r 3a1db0d2747e Lib/test/test_csv.py
--- a/Lib/test/test_csv.py
+++ b/Lib/test/test_csv.py
@@ -630,6 +630,23 @@
fileobj = StringIO()
self.assertRaises(TypeError, csv.DictWriter, fileobj)
+ def test_write_fields_not_in_fieldnames(self):
+ fd, name = tempfile.mkstemp()
+ fileobj = os.fdopen(fd, "w+b")
+ try:
+ writer = csv.DictWriter(fileobj, fieldnames = ["f1", "f2", "f3"])
+ # Of special note is the non-string key (issue 19449)
+ with self.assertRaises(ValueError) as cx:
+ writer.writerow({"f4": 10, "f2": "spam", 1: "abc"})
+ exception = str(cx.exception)
+ self.assertIn("fieldnames", exception)
+ self.assertIn("'f4'", exception)
+ self.assertNotIn("'f2'", exception)
+ self.assertIn("1", exception)
+ finally:
+ fileobj.close()
+ os.unlink(name)
+
def test_read_dict_fields(self):
fd, name = tempfile.mkstemp()
fileobj = os.fdopen(fd, "w+b")
@@ -853,6 +870,7 @@
lineterminator = '\r\n'
quoting = csv.QUOTE_NONE
d = mydialect()
+ self.assertEqual(d.quoting, csv.QUOTE_NONE)
mydialect.quoting = None
self.assertRaises(csv.Error, mydialect)
@@ -861,12 +879,21 @@
mydialect.quoting = csv.QUOTE_ALL
mydialect.quotechar = '"'
d = mydialect()
+ self.assertEqual(d.quoting, csv.QUOTE_ALL)
+ self.assertEqual(d.quotechar, '"')
+ self.assertTrue(d.doublequote)
mydialect.quotechar = "''"
- self.assertRaises(csv.Error, mydialect)
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"quotechar" must be an 1-character string')
mydialect.quotechar = 4
- self.assertRaises(csv.Error, mydialect)
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"quotechar" must be string, not int')
def test_delimiter(self):
class mydialect(csv.Dialect):
@@ -877,12 +904,31 @@
lineterminator = '\r\n'
quoting = csv.QUOTE_NONE
d = mydialect()
+ self.assertEqual(d.delimiter, ";")
mydialect.delimiter = ":::"
- self.assertRaises(csv.Error, mydialect)
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"delimiter" must be an 1-character string')
+
+ mydialect.delimiter = ""
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"delimiter" must be an 1-character string')
+
+ mydialect.delimiter = u","
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"delimiter" must be string, not unicode')
mydialect.delimiter = 4
- self.assertRaises(csv.Error, mydialect)
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"delimiter" must be string, not int')
def test_lineterminator(self):
class mydialect(csv.Dialect):
@@ -893,12 +939,17 @@
lineterminator = '\r\n'
quoting = csv.QUOTE_NONE
d = mydialect()
+ self.assertEqual(d.lineterminator, '\r\n')
mydialect.lineterminator = ":::"
d = mydialect()
+ self.assertEqual(d.lineterminator, ":::")
mydialect.lineterminator = 4
- self.assertRaises(csv.Error, mydialect)
+ with self.assertRaises(csv.Error) as cm:
+ mydialect()
+ self.assertEqual(str(cm.exception),
+ '"lineterminator" must be a string')
class TestSniffer(unittest.TestCase):
@@ -1014,78 +1065,77 @@
dialect = sniffer.sniff(self.sample9)
self.assertTrue(dialect.doublequote)
-if not hasattr(sys, "gettotalrefcount"):
- if test_support.verbose: print "*** skipping leakage tests ***"
-else:
- class NUL:
- def write(s, *args):
- pass
- writelines = write
+class NUL:
+ def write(s, *args):
+ pass
+ writelines = write
- class TestLeaks(unittest.TestCase):
- def test_create_read(self):
- delta = 0
- lastrc = sys.gettotalrefcount()
- for i in xrange(20):
- gc.collect()
- self.assertEqual(gc.garbage, [])
- rc = sys.gettotalrefcount()
- csv.reader(["a,b,c\r\n"])
- csv.reader(["a,b,c\r\n"])
- csv.reader(["a,b,c\r\n"])
- delta = rc-lastrc
- lastrc = rc
- # if csv.reader() leaks, last delta should be 3 or more
- self.assertEqual(delta < 3, True)
+@unittest.skipUnless(hasattr(sys, "gettotalrefcount"),
+ 'requires sys.gettotalrefcount()')
+class TestLeaks(unittest.TestCase):
+ def test_create_read(self):
+ delta = 0
+ lastrc = sys.gettotalrefcount()
+ for i in xrange(20):
+ gc.collect()
+ self.assertEqual(gc.garbage, [])
+ rc = sys.gettotalrefcount()
+ csv.reader(["a,b,c\r\n"])
+ csv.reader(["a,b,c\r\n"])
+ csv.reader(["a,b,c\r\n"])
+ delta = rc-lastrc
+ lastrc = rc
+ # if csv.reader() leaks, last delta should be 3 or more
+ self.assertEqual(delta < 3, True)
- def test_create_write(self):
- delta = 0
- lastrc = sys.gettotalrefcount()
- s = NUL()
- for i in xrange(20):
- gc.collect()
- self.assertEqual(gc.garbage, [])
- rc = sys.gettotalrefcount()
- csv.writer(s)
- csv.writer(s)
- csv.writer(s)
- delta = rc-lastrc
- lastrc = rc
- # if csv.writer() leaks, last delta should be 3 or more
- self.assertEqual(delta < 3, True)
+ def test_create_write(self):
+ delta = 0
+ lastrc = sys.gettotalrefcount()
+ s = NUL()
+ for i in xrange(20):
+ gc.collect()
+ self.assertEqual(gc.garbage, [])
+ rc = sys.gettotalrefcount()
+ csv.writer(s)
+ csv.writer(s)
+ csv.writer(s)
+ delta = rc-lastrc
+ lastrc = rc
+ # if csv.writer() leaks, last delta should be 3 or more
+ self.assertEqual(delta < 3, True)
- def test_read(self):
- delta = 0
- rows = ["a,b,c\r\n"]*5
- lastrc = sys.gettotalrefcount()
- for i in xrange(20):
- gc.collect()
- self.assertEqual(gc.garbage, [])
- rc = sys.gettotalrefcount()
- rdr = csv.reader(rows)
- for row in rdr:
- pass
- delta = rc-lastrc
- lastrc = rc
- # if reader leaks during read, delta should be 5 or more
- self.assertEqual(delta < 5, True)
+ def test_read(self):
+ delta = 0
+ rows = ["a,b,c\r\n"]*5
+ lastrc = sys.gettotalrefcount()
+ for i in xrange(20):
+ gc.collect()
+ self.assertEqual(gc.garbage, [])
+ rc = sys.gettotalrefcount()
+ rdr = csv.reader(rows)
+ for row in rdr:
+ pass
+ delta = rc-lastrc
+ lastrc = rc
+ # if reader leaks during read, delta should be 5 or more
+ self.assertEqual(delta < 5, True)
- def test_write(self):
- delta = 0
- rows = [[1,2,3]]*5
- s = NUL()
- lastrc = sys.gettotalrefcount()
- for i in xrange(20):
- gc.collect()
- self.assertEqual(gc.garbage, [])
- rc = sys.gettotalrefcount()
- writer = csv.writer(s)
- for row in rows:
- writer.writerow(row)
- delta = rc-lastrc
- lastrc = rc
- # if writer leaks during write, last delta should be 5 or more
- self.assertEqual(delta < 5, True)
+ def test_write(self):
+ delta = 0
+ rows = [[1,2,3]]*5
+ s = NUL()
+ lastrc = sys.gettotalrefcount()
+ for i in xrange(20):
+ gc.collect()
+ self.assertEqual(gc.garbage, [])
+ rc = sys.gettotalrefcount()
+ writer = csv.writer(s)
+ for row in rows:
+ writer.writerow(row)
+ delta = rc-lastrc
+ lastrc = rc
+ # if writer leaks during write, last delta should be 5 or more
+ self.assertEqual(delta < 5, True)
# commented out for now - csv module doesn't yet support Unicode
## class TestUnicode(unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/test_datetime.py
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -101,11 +101,11 @@
# carry no data), but they need to be picklable anyway else
# concrete subclasses can't be pickled.
orig = tzinfo.__new__(tzinfo)
- self.assertTrue(type(orig) is tzinfo)
+ self.assertIs(type(orig), tzinfo)
for pickler, unpickler, proto in pickle_choices:
green = pickler.dumps(orig, proto)
derived = unpickler.loads(green)
- self.assertTrue(type(derived) is tzinfo)
+ self.assertIs(type(derived), tzinfo)
def test_pickling_subclass(self):
# Make sure we can pickle/unpickle an instance of a subclass.
@@ -328,9 +328,9 @@
self.assertTrue(t1 == t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
- self.assertTrue(not t1 != t2)
- self.assertTrue(not t1 < t2)
- self.assertTrue(not t1 > t2)
+ self.assertFalse(t1 != t2)
+ self.assertFalse(t1 < t2)
+ self.assertFalse(t1 > t2)
self.assertEqual(cmp(t1, t2), 0)
self.assertEqual(cmp(t2, t1), 0)
@@ -342,12 +342,12 @@
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
- self.assertTrue(not t1 == t2)
- self.assertTrue(not t2 == t1)
- self.assertTrue(not t1 > t2)
- self.assertTrue(not t2 < t1)
- self.assertTrue(not t1 >= t2)
- self.assertTrue(not t2 <= t1)
+ self.assertFalse(t1 == t2)
+ self.assertFalse(t2 == t1)
+ self.assertFalse(t1 > t2)
+ self.assertFalse(t2 < t1)
+ self.assertFalse(t1 >= t2)
+ self.assertFalse(t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
@@ -459,7 +459,7 @@
self.assertTrue(timedelta(0, 1))
self.assertTrue(timedelta(0, 0, 1))
self.assertTrue(timedelta(microseconds=1))
- self.assertTrue(not timedelta(0))
+ self.assertFalse(timedelta(0))
def test_subclass_timedelta(self):
@@ -475,17 +475,17 @@
return round(sum)
t1 = T(days=1)
- self.assertTrue(type(t1) is T)
+ self.assertIs(type(t1), T)
self.assertEqual(t1.as_hours(), 24)
t2 = T(days=-1, seconds=-3600)
- self.assertTrue(type(t2) is T)
+ self.assertIs(type(t2), T)
self.assertEqual(t2.as_hours(), -25)
t3 = t1 + t2
- self.assertTrue(type(t3) is timedelta)
+ self.assertIs(type(t3), timedelta)
t4 = T.from_td(t3)
- self.assertTrue(type(t4) is T)
+ self.assertIs(type(t4), T)
self.assertEqual(t3.days, t4.days)
self.assertEqual(t3.seconds, t4.seconds)
self.assertEqual(t3.microseconds, t4.microseconds)
@@ -783,8 +783,9 @@
# It worked or it didn't. If it didn't, assume it's reason #2, and
# let the test pass if they're within half a second of each other.
- self.assertTrue(today == todayagain or
- abs(todayagain - today) < timedelta(seconds=0.5))
+ if today != todayagain:
+ self.assertAlmostEqual(todayagain, today,
+ delta=timedelta(seconds=0.5))
def test_weekday(self):
for i in range(7):
@@ -974,9 +975,9 @@
self.assertTrue(t1 == t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
- self.assertTrue(not t1 != t2)
- self.assertTrue(not t1 < t2)
- self.assertTrue(not t1 > t2)
+ self.assertFalse(t1 != t2)
+ self.assertFalse(t1 < t2)
+ self.assertFalse(t1 > t2)
self.assertEqual(cmp(t1, t2), 0)
self.assertEqual(cmp(t2, t1), 0)
@@ -988,12 +989,12 @@
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
- self.assertTrue(not t1 == t2)
- self.assertTrue(not t2 == t1)
- self.assertTrue(not t1 > t2)
- self.assertTrue(not t2 < t1)
- self.assertTrue(not t1 >= t2)
- self.assertTrue(not t2 <= t1)
+ self.assertFalse(t1 == t2)
+ self.assertFalse(t2 == t1)
+ self.assertFalse(t1 > t2)
+ self.assertFalse(t2 < t1)
+ self.assertFalse(t1 >= t2)
+ self.assertFalse(t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
@@ -1444,9 +1445,9 @@
self.assertTrue(t1 == t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
- self.assertTrue(not t1 != t2)
- self.assertTrue(not t1 < t2)
- self.assertTrue(not t1 > t2)
+ self.assertFalse(t1 != t2)
+ self.assertFalse(t1 < t2)
+ self.assertFalse(t1 > t2)
self.assertEqual(cmp(t1, t2), 0)
self.assertEqual(cmp(t2, t1), 0)
@@ -1460,12 +1461,12 @@
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
- self.assertTrue(not t1 == t2)
- self.assertTrue(not t2 == t1)
- self.assertTrue(not t1 > t2)
- self.assertTrue(not t2 < t1)
- self.assertTrue(not t1 >= t2)
- self.assertTrue(not t2 <= t1)
+ self.assertFalse(t1 == t2)
+ self.assertFalse(t2 == t1)
+ self.assertFalse(t1 > t2)
+ self.assertFalse(t2 < t1)
+ self.assertFalse(t1 >= t2)
+ self.assertFalse(t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
@@ -1541,7 +1542,7 @@
if abs(from_timestamp - from_now) <= tolerance:
break
# Else try again a few times.
- self.assertTrue(abs(from_timestamp - from_now) <= tolerance)
+ self.assertLessEqual(abs(from_timestamp - from_now), tolerance)
def test_strptime(self):
import _strptime
@@ -1727,9 +1728,9 @@
self.assertTrue(t1 == t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
- self.assertTrue(not t1 != t2)
- self.assertTrue(not t1 < t2)
- self.assertTrue(not t1 > t2)
+ self.assertFalse(t1 != t2)
+ self.assertFalse(t1 < t2)
+ self.assertFalse(t1 > t2)
self.assertEqual(cmp(t1, t2), 0)
self.assertEqual(cmp(t2, t1), 0)
@@ -1743,12 +1744,12 @@
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
- self.assertTrue(not t1 == t2)
- self.assertTrue(not t2 == t1)
- self.assertTrue(not t1 > t2)
- self.assertTrue(not t2 < t1)
- self.assertTrue(not t1 >= t2)
- self.assertTrue(not t2 <= t1)
+ self.assertFalse(t1 == t2)
+ self.assertFalse(t2 == t1)
+ self.assertFalse(t1 > t2)
+ self.assertFalse(t2 < t1)
+ self.assertFalse(t1 >= t2)
+ self.assertFalse(t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
@@ -1928,8 +1929,8 @@
self.assertTrue(cls(0, 1))
self.assertTrue(cls(0, 0, 1))
self.assertTrue(cls(0, 0, 0, 1))
- self.assertTrue(not cls(0))
- self.assertTrue(not cls())
+ self.assertFalse(cls(0))
+ self.assertFalse(cls())
def test_replace(self):
cls = self.theclass
@@ -2026,7 +2027,7 @@
def utcoffset(self, dt): pass
b = BetterTry()
t = cls(1, 1, 1, tzinfo=b)
- self.assertTrue(t.tzinfo is b)
+ self.assertIs(t.tzinfo, b)
def test_utc_offset_out_of_bounds(self):
class Edgy(tzinfo):
@@ -2065,9 +2066,9 @@
for t in (cls(1, 1, 1),
cls(1, 1, 1, tzinfo=None),
cls(1, 1, 1, tzinfo=C1())):
- self.assertTrue(t.utcoffset() is None)
- self.assertTrue(t.dst() is None)
- self.assertTrue(t.tzname() is None)
+ self.assertIsNone(t.utcoffset())
+ self.assertIsNone(t.dst())
+ self.assertIsNone(t.tzname())
class C3(tzinfo):
def utcoffset(self, dt): return timedelta(minutes=-1439)
@@ -2161,7 +2162,7 @@
self.assertEqual(t.minute, 0)
self.assertEqual(t.second, 0)
self.assertEqual(t.microsecond, 0)
- self.assertTrue(t.tzinfo is None)
+ self.assertIsNone(t.tzinfo)
def test_zones(self):
est = FixedOffset(-300, "EST", 1)
@@ -2176,25 +2177,25 @@
self.assertEqual(t1.tzinfo, est)
self.assertEqual(t2.tzinfo, utc)
self.assertEqual(t3.tzinfo, met)
- self.assertTrue(t4.tzinfo is None)
+ self.assertIsNone(t4.tzinfo)
self.assertEqual(t5.tzinfo, utc)
self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
- self.assertTrue(t4.utcoffset() is None)
+ self.assertIsNone(t4.utcoffset())
self.assertRaises(TypeError, t1.utcoffset, "no args")
self.assertEqual(t1.tzname(), "EST")
self.assertEqual(t2.tzname(), "UTC")
self.assertEqual(t3.tzname(), "MET")
- self.assertTrue(t4.tzname() is None)
+ self.assertIsNone(t4.tzname())
self.assertRaises(TypeError, t1.tzname, "no args")
self.assertEqual(t1.dst(), timedelta(minutes=1))
self.assertEqual(t2.dst(), timedelta(minutes=-2))
self.assertEqual(t3.dst(), timedelta(minutes=3))
- self.assertTrue(t4.dst() is None)
+ self.assertIsNone(t4.dst())
self.assertRaises(TypeError, t1.dst, "no args")
self.assertEqual(hash(t1), hash(t2))
@@ -2285,10 +2286,10 @@
self.assertTrue(t)
t = cls(5, tzinfo=FixedOffset(300, ""))
- self.assertTrue(not t)
+ self.assertFalse(t)
t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, ""))
- self.assertTrue(not t)
+ self.assertFalse(t)
# Mostly ensuring this doesn't overflow internally.
t = cls(0, tzinfo=FixedOffset(23*60 + 59, ""))
@@ -2326,13 +2327,13 @@
# Ensure we can get rid of a tzinfo.
self.assertEqual(base.tzname(), "+100")
base2 = base.replace(tzinfo=None)
- self.assertTrue(base2.tzinfo is None)
- self.assertTrue(base2.tzname() is None)
+ self.assertIsNone(base2.tzinfo)
+ self.assertIsNone(base2.tzname())
# Ensure we can add one.
base3 = base2.replace(tzinfo=z100)
self.assertEqual(base, base3)
- self.assertTrue(base.tzinfo is base3.tzinfo)
+ self.assertIs(base.tzinfo, base3.tzinfo)
# Out of bounds.
base = cls(1)
@@ -2567,7 +2568,7 @@
tz55 = FixedOffset(-330, "west 5:30")
timeaware = now.time().replace(tzinfo=tz55)
nowaware = self.theclass.combine(now.date(), timeaware)
- self.assertTrue(nowaware.tzinfo is tz55)
+ self.assertIs(nowaware.tzinfo, tz55)
self.assertEqual(nowaware.timetz(), timeaware)
# Can't mix aware and non-aware.
@@ -2586,15 +2587,15 @@
# Adding a delta should preserve tzinfo.
delta = timedelta(weeks=1, minutes=12, microseconds=5678)
nowawareplus = nowaware + delta
- self.assertTrue(nowaware.tzinfo is tz55)
+ self.assertIs(nowaware.tzinfo, tz55)
nowawareplus2 = delta + nowaware
- self.assertTrue(nowawareplus2.tzinfo is tz55)
+ self.assertIs(nowawareplus2.tzinfo, tz55)
self.assertEqual(nowawareplus, nowawareplus2)
# that - delta should be what we started with, and that - what we
# started with should be delta.
diff = nowawareplus - delta
- self.assertTrue(diff.tzinfo is tz55)
+ self.assertIs(diff.tzinfo, tz55)
self.assertEqual(nowaware, diff)
self.assertRaises(TypeError, lambda: delta - nowawareplus)
self.assertEqual(nowawareplus - nowaware, delta)
@@ -2603,7 +2604,7 @@
tzr = FixedOffset(random.randrange(-1439, 1440), "randomtimezone")
# Attach it to nowawareplus.
nowawareplus = nowawareplus.replace(tzinfo=tzr)
- self.assertTrue(nowawareplus.tzinfo is tzr)
+ self.assertIs(nowawareplus.tzinfo, tzr)
# Make sure the difference takes the timezone adjustments into account.
got = nowaware - nowawareplus
# Expected: (nowaware base - nowaware offset) -
@@ -2630,7 +2631,7 @@
off42 = FixedOffset(42, "42")
another = meth(off42)
again = meth(tz=off42)
- self.assertTrue(another.tzinfo is again.tzinfo)
+ self.assertIs(another.tzinfo, again.tzinfo)
self.assertEqual(another.utcoffset(), timedelta(minutes=42))
# Bad argument with and w/o naming the keyword.
self.assertRaises(TypeError, meth, 16)
@@ -2647,7 +2648,7 @@
utc = FixedOffset(0, "utc", 0)
for dummy in range(3):
now = datetime.now(weirdtz)
- self.assertTrue(now.tzinfo is weirdtz)
+ self.assertIs(now.tzinfo, weirdtz)
utcnow = datetime.utcnow().replace(tzinfo=utc)
now2 = utcnow.astimezone(weirdtz)
if abs(now - now2) < timedelta(seconds=30):
@@ -2668,7 +2669,7 @@
off42 = FixedOffset(42, "42")
another = meth(ts, off42)
again = meth(ts, tz=off42)
- self.assertTrue(another.tzinfo is again.tzinfo)
+ self.assertIs(another.tzinfo, again.tzinfo)
self.assertEqual(another.utcoffset(), timedelta(minutes=42))
# Bad argument with and w/o naming the keyword.
self.assertRaises(TypeError, meth, ts, 16)
@@ -2862,13 +2863,13 @@
# Ensure we can get rid of a tzinfo.
self.assertEqual(base.tzname(), "+100")
base2 = base.replace(tzinfo=None)
- self.assertTrue(base2.tzinfo is None)
- self.assertTrue(base2.tzname() is None)
+ self.assertIsNone(base2.tzinfo)
+ self.assertIsNone(base2.tzname())
# Ensure we can add one.
base3 = base2.replace(tzinfo=z100)
self.assertEqual(base, base3)
- self.assertTrue(base.tzinfo is base3.tzinfo)
+ self.assertIs(base.tzinfo, base3.tzinfo)
# Out of bounds.
base = cls(2000, 2, 29)
@@ -2881,20 +2882,20 @@
fm5h = FixedOffset(-timedelta(hours=5), "m300")
dt = self.theclass.now(tz=f44m)
- self.assertTrue(dt.tzinfo is f44m)
+ self.assertIs(dt.tzinfo, f44m)
# Replacing with degenerate tzinfo raises an exception.
self.assertRaises(ValueError, dt.astimezone, fnone)
# Ditto with None tz.
self.assertRaises(TypeError, dt.astimezone, None)
# Replacing with same tzinfo makes no change.
x = dt.astimezone(dt.tzinfo)
- self.assertTrue(x.tzinfo is f44m)
+ self.assertIs(x.tzinfo, f44m)
self.assertEqual(x.date(), dt.date())
self.assertEqual(x.time(), dt.time())
# Replacing with different tzinfo does adjust.
got = dt.astimezone(fm5h)
- self.assertTrue(got.tzinfo is fm5h)
+ self.assertIs(got.tzinfo, fm5h)
self.assertEqual(got.utcoffset(), timedelta(hours=-5))
expected = dt - dt.utcoffset() # in effect, convert to UTC
expected += fm5h.utcoffset(dt) # and from there to local time
@@ -2902,7 +2903,7 @@
self.assertEqual(got.date(), expected.date())
self.assertEqual(got.time(), expected.time())
self.assertEqual(got.timetz(), expected.timetz())
- self.assertTrue(got.tzinfo is expected.tzinfo)
+ self.assertIs(got.tzinfo, expected.tzinfo)
self.assertEqual(got, expected)
def test_aware_subtract(self):
@@ -3330,8 +3331,8 @@
as_datetime = datetime.combine(as_date, time())
self.assertTrue(as_date != as_datetime)
self.assertTrue(as_datetime != as_date)
- self.assertTrue(not as_date == as_datetime)
- self.assertTrue(not as_datetime == as_date)
+ self.assertFalse(as_date == as_datetime)
+ self.assertFalse(as_datetime == as_date)
self.assertRaises(TypeError, lambda: as_date < as_datetime)
self.assertRaises(TypeError, lambda: as_datetime < as_date)
self.assertRaises(TypeError, lambda: as_date <= as_datetime)
@@ -3345,8 +3346,7 @@
# projection if use of a date method is forced.
self.assertTrue(as_date.__eq__(as_datetime))
different_day = (as_date.day + 1) % 20 + 1
- self.assertTrue(not as_date.__eq__(as_datetime.replace(day=
- different_day)))
+ self.assertFalse(as_date.__eq__(as_datetime.replace(day=different_day)))
# And date should compare with other subclasses of date. If a
# subclass wants to stop this, it's up to the subclass to do so.
diff -r 3a1db0d2747e Lib/test/test_decimal.py
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -223,7 +223,6 @@
global skip_expected
if skip_expected:
raise unittest.SkipTest
- return
with open(file) as f:
for line in f:
line = line.replace('\r\n', '').replace('\n', '')
@@ -234,7 +233,6 @@
#Exception raised where there shouldn't have been one.
self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
- return
def eval_line(self, s):
if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'):
@@ -391,7 +389,6 @@
'Incorrect answer for ' + s + ' -- got ' + result)
self.assertItemsEqual(myexceptions, theirexceptions,
'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
- return
def getexceptions(self):
return [e for e in Signals if self.context.flags[e]]
@@ -834,7 +831,7 @@
try:
from locale import CHAR_MAX
except ImportError:
- return
+ self.skipTest('locale.CHAR_MAX not available')
# Set up some localeconv-like dictionaries
en_US = {
@@ -1196,7 +1193,6 @@
cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
cls.assertEqual(test2, Decimal('0.3333333333333333333333333333'))
- return
def thfunc2(cls):
d1 = Decimal(1)
@@ -1210,17 +1206,12 @@
cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
cls.assertEqual(test2, Decimal('0.333333333333333333'))
- return
+@unittest.skipUnless(threading, 'threading required')
class DecimalUseOfContextTest(unittest.TestCase):
'''Unit tests for Use of Context cases in Decimal.'''
- try:
- import threading
- except ImportError:
- threading = None
-
# Take care executing this test from IDLE, there's an issue in threading
# that hangs IDLE and I couldn't find it
@@ -1239,10 +1230,6 @@
self.finish1.wait()
self.finish2.wait()
- return
-
- if threading is None:
- del test_threading
class DecimalUsabilityTest(unittest.TestCase):
@@ -1540,7 +1527,6 @@
self.assertEqual(d1._sign, b1._sign)
self.assertEqual(d1._int, b1._int)
self.assertEqual(d1._exp, b1._exp)
- return
Decimal(d1)
self.assertEqual(d1._sign, b1._sign)
diff -r 3a1db0d2747e Lib/test/test_descr.py
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -398,13 +398,21 @@
class ClassPropertiesAndMethods(unittest.TestCase):
+ def assertHasAttr(self, obj, name):
+ self.assertTrue(hasattr(obj, name),
+ '%r has no attribute %r' % (obj, name))
+
+ def assertNotHasAttr(self, obj, name):
+ self.assertFalse(hasattr(obj, name),
+ '%r has unexpected attribute %r' % (obj, name))
+
def test_python_dicts(self):
# Testing Python subclass of dict...
self.assertTrue(issubclass(dict, dict))
self.assertIsInstance({}, dict)
d = dict()
self.assertEqual(d, {})
- self.assertTrue(d.__class__ is dict)
+ self.assertIs(d.__class__, dict)
self.assertIsInstance(d, dict)
class C(dict):
state = -1
@@ -585,7 +593,7 @@
def _set_x(self, x):
self.__x = -x
a = A()
- self.assertTrue(not hasattr(a, "x"))
+ self.assertNotHasAttr(a, "x")
a.x = 12
self.assertEqual(a.x, 12)
self.assertEqual(a._A__x, -12)
@@ -934,14 +942,14 @@
self.assertEqual(type(a), object)
b = object()
self.assertNotEqual(a, b)
- self.assertFalse(hasattr(a, "foo"))
+ self.assertNotHasAttr(a, "foo")
try:
a.foo = 12
except (AttributeError, TypeError):
pass
else:
self.fail("object() should not allow setting a foo attribute")
- self.assertFalse(hasattr(object(), "__dict__"))
+ self.assertNotHasAttr(object(), "__dict__")
class Cdict(object):
pass
@@ -956,28 +964,28 @@
class C0(object):
__slots__ = []
x = C0()
- self.assertFalse(hasattr(x, "__dict__"))
- self.assertFalse(hasattr(x, "foo"))
+ self.assertNotHasAttr(x, "__dict__")
+ self.assertNotHasAttr(x, "foo")
class C1(object):
__slots__ = ['a']
x = C1()
- self.assertFalse(hasattr(x, "__dict__"))
- self.assertFalse(hasattr(x, "a"))
+ self.assertNotHasAttr(x, "__dict__")
+ self.assertNotHasAttr(x, "a")
x.a = 1
self.assertEqual(x.a, 1)
x.a = None
self.assertEqual(x.a, None)
del x.a
- self.assertFalse(hasattr(x, "a"))
+ self.assertNotHasAttr(x, "a")
class C3(object):
__slots__ = ['a', 'b', 'c']
x = C3()
- self.assertFalse(hasattr(x, "__dict__"))
- self.assertFalse(hasattr(x, 'a'))
- self.assertFalse(hasattr(x, 'b'))
- self.assertFalse(hasattr(x, 'c'))
+ self.assertNotHasAttr(x, "__dict__")
+ self.assertNotHasAttr(x, 'a')
+ self.assertNotHasAttr(x, 'b')
+ self.assertNotHasAttr(x, 'c')
x.a = 1
x.b = 2
x.c = 3
@@ -993,8 +1001,8 @@
def get(self):
return self.__a
x = C4(5)
- self.assertFalse(hasattr(x, '__dict__'))
- self.assertFalse(hasattr(x, '__a'))
+ self.assertNotHasAttr(x, '__dict__')
+ self.assertNotHasAttr(x, '__a')
self.assertEqual(x.get(), 5)
try:
x.__a = 6
@@ -1051,11 +1059,12 @@
c.abc = 5
self.assertEqual(c.abc, 5)
+ def test_unicode_slots(self):
# Test unicode slot names
try:
unicode
except NameError:
- pass
+ self.skipTest('no unicode support')
else:
# Test a single unicode string is not expanded as a sequence.
class C(object):
@@ -1164,16 +1173,16 @@
class D(object):
__slots__ = ["__dict__"]
a = D()
- self.assertTrue(hasattr(a, "__dict__"))
- self.assertFalse(hasattr(a, "__weakref__"))
+ self.assertHasAttr(a, "__dict__")
+ self.assertNotHasAttr(a, "__weakref__")
a.foo = 42
self.assertEqual(a.__dict__, {"foo": 42})
class W(object):
__slots__ = ["__weakref__"]
a = W()
- self.assertTrue(hasattr(a, "__weakref__"))
- self.assertFalse(hasattr(a, "__dict__"))
+ self.assertHasAttr(a, "__weakref__")
+ self.assertNotHasAttr(a, "__dict__")
try:
a.foo = 42
except AttributeError:
@@ -1184,16 +1193,16 @@
class C1(W, D):
__slots__ = []
a = C1()
- self.assertTrue(hasattr(a, "__dict__"))
- self.assertTrue(hasattr(a, "__weakref__"))
+ self.assertHasAttr(a, "__dict__")
+ self.assertHasAttr(a, "__weakref__")
a.foo = 42
self.assertEqual(a.__dict__, {"foo": 42})
class C2(D, W):
__slots__ = []
a = C2()
- self.assertTrue(hasattr(a, "__dict__"))
- self.assertTrue(hasattr(a, "__weakref__"))
+ self.assertHasAttr(a, "__dict__")
+ self.assertHasAttr(a, "__weakref__")
a.foo = 42
self.assertEqual(a.__dict__, {"foo": 42})
@@ -1241,7 +1250,7 @@
class C(object):
pass
a = C()
- self.assertFalse(hasattr(a, "foobar"))
+ self.assertNotHasAttr(a, "foobar")
C.foobar = 2
self.assertEqual(a.foobar, 2)
C.method = lambda self: 42
@@ -1251,7 +1260,7 @@
C.__int__ = lambda self: 100
self.assertEqual(int(a), 100)
self.assertEqual(a.foobar, 2)
- self.assertFalse(hasattr(a, "spam"))
+ self.assertNotHasAttr(a, "spam")
def mygetattr(self, name):
if name == "spam":
return "spam"
@@ -1521,7 +1530,7 @@
self.assertEqual(a.x, 10)
self.assertEqual(a.x, 11)
del a.x
- self.assertEqual(hasattr(a, 'x'), 0)
+ self.assertNotHasAttr(a, 'x')
def test_newslots(self):
# Testing __new__ slot override...
@@ -1797,18 +1806,18 @@
raise IndexError
c1 = C()
c2 = C()
- self.assertTrue(not not c1) # What?
+ self.assertFalse(not c1)
self.assertNotEqual(id(c1), id(c2))
hash(c1)
hash(c2)
self.assertEqual(cmp(c1, c2), cmp(id(c1), id(c2)))
self.assertEqual(c1, c1)
self.assertTrue(c1 != c2)
- self.assertTrue(not c1 != c1)
- self.assertTrue(not c1 == c2)
+ self.assertFalse(c1 != c1)
+ self.assertFalse(c1 == c2)
# Note that the module name appears in str/repr, and that varies
# depending on whether this test is run standalone or from a framework.
- self.assertTrue(str(c1).find('C object at ') >= 0)
+ self.assertGreaterEqual(str(c1).find('C object at '), 0)
self.assertEqual(str(c1), repr(c1))
self.assertNotIn(-1, c1)
for i in range(10):
@@ -1821,18 +1830,18 @@
raise IndexError
d1 = D()
d2 = D()
- self.assertTrue(not not d1)
+ self.assertFalse(not d1)
self.assertNotEqual(id(d1), id(d2))
hash(d1)
hash(d2)
self.assertEqual(cmp(d1, d2), cmp(id(d1), id(d2)))
self.assertEqual(d1, d1)
self.assertNotEqual(d1, d2)
- self.assertTrue(not d1 != d1)
- self.assertTrue(not d1 == d2)
+ self.assertFalse(d1 != d1)
+ self.assertFalse(d1 == d2)
# Note that the module name appears in str/repr, and that varies
# depending on whether this test is run standalone or from a framework.
- self.assertTrue(str(d1).find('D object at ') >= 0)
+ self.assertGreaterEqual(str(d1).find('D object at '), 0)
self.assertEqual(str(d1), repr(d1))
self.assertNotIn(-1, d1)
for i in range(10):
@@ -1862,11 +1871,11 @@
p1 = Proxy(1)
p_1 = Proxy(-1)
self.assertFalse(p0)
- self.assertTrue(not not p1)
+ self.assertFalse(not p1)
self.assertEqual(hash(p0), hash(0))
self.assertEqual(p0, p0)
self.assertNotEqual(p0, p1)
- self.assertTrue(not p0 != p0)
+ self.assertFalse(p0 != p0)
self.assertEqual(not p0, p1)
self.assertEqual(cmp(p0, p1), -1)
self.assertEqual(cmp(p0, p0), 0)
@@ -1902,7 +1911,7 @@
p1 = DProxy(1)
p_1 = DProxy(-1)
self.assertFalse(p0)
- self.assertTrue(not not p1)
+ self.assertFalse(not p1)
self.assertEqual(hash(p0), hash(0))
self.assertEqual(p0, p0)
self.assertNotEqual(p0, p1)
@@ -1995,7 +2004,7 @@
try:
weakref.ref(no)
except TypeError, msg:
- self.assertTrue(str(msg).find("weak reference") >= 0)
+ self.assertIn("weak reference", str(msg))
else:
self.fail("weakref.ref(no) should be illegal")
class Weak(object):
@@ -2019,17 +2028,17 @@
del self.__x
x = property(getx, setx, delx, doc="I'm the x property.")
a = C()
- self.assertFalse(hasattr(a, "x"))
+ self.assertNotHasAttr(a, "x")
a.x = 42
self.assertEqual(a._C__x, 42)
self.assertEqual(a.x, 42)
del a.x
- self.assertFalse(hasattr(a, "x"))
- self.assertFalse(hasattr(a, "_C__x"))
+ self.assertNotHasAttr(a, "x")
+ self.assertNotHasAttr(a, "_C__x")
C.x.__set__(a, 100)
self.assertEqual(C.x.__get__(a), 100)
C.x.__delete__(a)
- self.assertFalse(hasattr(a, "x"))
+ self.assertNotHasAttr(a, "x")
raw = C.__dict__['x']
self.assertIsInstance(raw, property)
@@ -2041,9 +2050,9 @@
self.assertIn("fdel", attrs)
self.assertEqual(raw.__doc__, "I'm the x property.")
- self.assertTrue(raw.fget is C.__dict__['getx'])
- self.assertTrue(raw.fset is C.__dict__['setx'])
- self.assertTrue(raw.fdel is C.__dict__['delx'])
+ self.assertIs(raw.fget, C.__dict__['getx'])
+ self.assertIs(raw.fset, C.__dict__['setx'])
+ self.assertIs(raw.fdel, C.__dict__['delx'])
for attr in "__doc__", "fget", "fset", "fdel":
try:
@@ -2083,6 +2092,7 @@
prop2 = property(fset=setter)
self.assertEqual(prop2.__doc__, None)
+ @test_support.cpython_only
def test_testcapi_no_segfault(self):
# this segfaulted in 2.5b2
try:
@@ -2107,14 +2117,14 @@
del self._foo
c = C()
self.assertEqual(C.foo.__doc__, "hello")
- self.assertFalse(hasattr(c, "foo"))
+ self.assertNotHasAttr(c, "foo")
c.foo = -42
- self.assertTrue(hasattr(c, '_foo'))
+ self.assertHasAttr(c, '_foo')
self.assertEqual(c._foo, 42)
self.assertEqual(c.foo, 42)
del c.foo
- self.assertFalse(hasattr(c, '_foo'))
- self.assertFalse(hasattr(c, "foo"))
+ self.assertNotHasAttr(c, '_foo')
+ self.assertNotHasAttr(c, "foo")
class D(C):
@C.foo.deleter
@@ -2500,13 +2510,13 @@
a = hexint(12345)
self.assertEqual(a, 12345)
self.assertEqual(int(a), 12345)
- self.assertTrue(int(a).__class__ is int)
+ self.assertIs(int(a).__class__, int)
self.assertEqual(hash(a), hash(12345))
- self.assertTrue((+a).__class__ is int)
- self.assertTrue((a >> 0).__class__ is int)
- self.assertTrue((a << 0).__class__ is int)
- self.assertTrue((hexint(0) << 12).__class__ is int)
- self.assertTrue((hexint(0) >> 12).__class__ is int)
+ self.assertIs((+a).__class__, int)
+ self.assertIs((a >> 0).__class__, int)
+ self.assertIs((a << 0).__class__, int)
+ self.assertIs((hexint(0) << 12).__class__, int)
+ self.assertIs((hexint(0) >> 12).__class__, int)
class octlong(long):
__slots__ = []
@@ -2526,31 +2536,31 @@
self.assertEqual(a, 12345L)
self.assertEqual(long(a), 12345L)
self.assertEqual(hash(a), hash(12345L))
- self.assertTrue(long(a).__class__ is long)
- self.assertTrue((+a).__class__ is long)
- self.assertTrue((-a).__class__ is long)
- self.assertTrue((-octlong(0)).__class__ is long)
- self.assertTrue((a >> 0).__class__ is long)
- self.assertTrue((a << 0).__class__ is long)
- self.assertTrue((a - 0).__class__ is long)
- self.assertTrue((a * 1).__class__ is long)
- self.assertTrue((a ** 1).__class__ is long)
- self.assertTrue((a // 1).__class__ is long)
- self.assertTrue((1 * a).__class__ is long)
- self.assertTrue((a | 0).__class__ is long)
- self.assertTrue((a ^ 0).__class__ is long)
- self.assertTrue((a & -1L).__class__ is long)
- self.assertTrue((octlong(0) << 12).__class__ is long)
- self.assertTrue((octlong(0) >> 12).__class__ is long)
- self.assertTrue(abs(octlong(0)).__class__ is long)
+ self.assertIs(long(a).__class__, long)
+ self.assertIs((+a).__class__, long)
+ self.assertIs((-a).__class__, long)
+ self.assertIs((-octlong(0)).__class__, long)
+ self.assertIs((a >> 0).__class__, long)
+ self.assertIs((a << 0).__class__, long)
+ self.assertIs((a - 0).__class__, long)
+ self.assertIs((a * 1).__class__, long)
+ self.assertIs((a ** 1).__class__, long)
+ self.assertIs((a // 1).__class__, long)
+ self.assertIs((1 * a).__class__, long)
+ self.assertIs((a | 0).__class__, long)
+ self.assertIs((a ^ 0).__class__, long)
+ self.assertIs((a & -1L).__class__, long)
+ self.assertIs((octlong(0) << 12).__class__, long)
+ self.assertIs((octlong(0) >> 12).__class__, long)
+ self.assertIs(abs(octlong(0)).__class__, long)
# Because octlong overrides __add__, we can't check the absence of +0
# optimizations using octlong.
class longclone(long):
pass
a = longclone(1)
- self.assertTrue((a + 0).__class__ is long)
- self.assertTrue((0 + a).__class__ is long)
+ self.assertIs((a + 0).__class__, long)
+ self.assertIs((0 + a).__class__, long)
# Check that negative clones don't segfault
a = longclone(-1)
@@ -2567,9 +2577,9 @@
a = precfloat(12345)
self.assertEqual(a, 12345.0)
self.assertEqual(float(a), 12345.0)
- self.assertTrue(float(a).__class__ is float)
+ self.assertIs(float(a).__class__, float)
self.assertEqual(hash(a), hash(12345.0))
- self.assertTrue((+a).__class__ is float)
+ self.assertIs((+a).__class__, float)
class madcomplex(complex):
def __repr__(self):
@@ -2617,20 +2627,20 @@
self.assertEqual(v, t)
a = madtuple((1,2,3,4,5))
self.assertEqual(tuple(a), (1,2,3,4,5))
- self.assertTrue(tuple(a).__class__ is tuple)
+ self.assertIs(tuple(a).__class__, tuple)
self.assertEqual(hash(a), hash((1,2,3,4,5)))
- self.assertTrue(a[:].__class__ is tuple)
- self.assertTrue((a * 1).__class__ is tuple)
- self.assertTrue((a * 0).__class__ is tuple)
- self.assertTrue((a + ()).__class__ is tuple)
+ self.assertIs(a[:].__class__, tuple)
+ self.assertIs((a * 1).__class__, tuple)
+ self.assertIs((a * 0).__class__, tuple)
+ self.assertIs((a + ()).__class__, tuple)
a = madtuple(())
self.assertEqual(tuple(a), ())
- self.assertTrue(tuple(a).__class__ is tuple)
- self.assertTrue((a + a).__class__ is tuple)
- self.assertTrue((a * 0).__class__ is tuple)
- self.assertTrue((a * 1).__class__ is tuple)
- self.assertTrue((a * 2).__class__ is tuple)
- self.assertTrue(a[:].__class__ is tuple)
+ self.assertIs(tuple(a).__class__, tuple)
+ self.assertIs((a + a).__class__, tuple)
+ self.assertIs((a * 0).__class__, tuple)
+ self.assertIs((a * 1).__class__, tuple)
+ self.assertIs((a * 2).__class__, tuple)
+ self.assertIs(a[:].__class__, tuple)
class madstring(str):
_rev = None
@@ -2652,51 +2662,51 @@
self.assertEqual(u, s)
s = madstring("12345")
self.assertEqual(str(s), "12345")
- self.assertTrue(str(s).__class__ is str)
+ self.assertIs(str(s).__class__, str)
base = "\x00" * 5
s = madstring(base)
self.assertEqual(s, base)
self.assertEqual(str(s), base)
- self.assertTrue(str(s).__class__ is str)
+ self.assertIs(str(s).__class__, str)
self.assertEqual(hash(s), hash(base))
self.assertEqual({s: 1}[base], 1)
self.assertEqual({base: 1}[s], 1)
- self.assertTrue((s + "").__class__ is str)
+ self.assertIs((s + "").__class__, str)
self.assertEqual(s + "", base)
- self.assertTrue(("" + s).__class__ is str)
+ self.assertIs(("" + s).__class__, str)
self.assertEqual("" + s, base)
- self.assertTrue((s * 0).__class__ is str)
+ self.assertIs((s * 0).__class__, str)
self.assertEqual(s * 0, "")
- self.assertTrue((s * 1).__class__ is str)
+ self.assertIs((s * 1).__class__, str)
self.assertEqual(s * 1, base)
- self.assertTrue((s * 2).__class__ is str)
+ self.assertIs((s * 2).__class__, str)
self.assertEqual(s * 2, base + base)
- self.assertTrue(s[:].__class__ is str)
+ self.assertIs(s[:].__class__, str)
self.assertEqual(s[:], base)
- self.assertTrue(s[0:0].__class__ is str)
+ self.assertIs(s[0:0].__class__, str)
self.assertEqual(s[0:0], "")
- self.assertTrue(s.strip().__class__ is str)
+ self.assertIs(s.strip().__class__, str)
self.assertEqual(s.strip(), base)
- self.assertTrue(s.lstrip().__class__ is str)
+ self.assertIs(s.lstrip().__class__, str)
self.assertEqual(s.lstrip(), base)
- self.assertTrue(s.rstrip().__class__ is str)
+ self.assertIs(s.rstrip().__class__, str)
self.assertEqual(s.rstrip(), base)
identitytab = ''.join([chr(i) for i in range(256)])
- self.assertTrue(s.translate(identitytab).__class__ is str)
+ self.assertIs(s.translate(identitytab).__class__, str)
self.assertEqual(s.translate(identitytab), base)
- self.assertTrue(s.translate(identitytab, "x").__class__ is str)
+ self.assertIs(s.translate(identitytab, "x").__class__, str)
self.assertEqual(s.translate(identitytab, "x"), base)
self.assertEqual(s.translate(identitytab, "\x00"), "")
- self.assertTrue(s.replace("x", "x").__class__ is str)
+ self.assertIs(s.replace("x", "x").__class__, str)
self.assertEqual(s.replace("x", "x"), base)
- self.assertTrue(s.ljust(len(s)).__class__ is str)
+ self.assertIs(s.ljust(len(s)).__class__, str)
self.assertEqual(s.ljust(len(s)), base)
- self.assertTrue(s.rjust(len(s)).__class__ is str)
+ self.assertIs(s.rjust(len(s)).__class__, str)
self.assertEqual(s.rjust(len(s)), base)
- self.assertTrue(s.center(len(s)).__class__ is str)
+ self.assertIs(s.center(len(s)).__class__, str)
self.assertEqual(s.center(len(s)), base)
- self.assertTrue(s.lower().__class__ is str)
+ self.assertIs(s.lower().__class__, str)
self.assertEqual(s.lower(), base)
class madunicode(unicode):
@@ -2715,47 +2725,47 @@
base = u"12345"
u = madunicode(base)
self.assertEqual(unicode(u), base)
- self.assertTrue(unicode(u).__class__ is unicode)
+ self.assertIs(unicode(u).__class__, unicode)
self.assertEqual(hash(u), hash(base))
self.assertEqual({u: 1}[base], 1)
self.assertEqual({base: 1}[u], 1)
- self.assertTrue(u.strip().__class__ is unicode)
+ self.assertIs(u.strip().__class__, unicode)
self.assertEqual(u.strip(), base)
- self.assertTrue(u.lstrip().__class__ is unicode)
+ self.assertIs(u.lstrip().__class__, unicode)
self.assertEqual(u.lstrip(), base)
- self.assertTrue(u.rstrip().__class__ is unicode)
+ self.assertIs(u.rstrip().__class__, unicode)
self.assertEqual(u.rstrip(), base)
- self.assertTrue(u.replace(u"x", u"x").__class__ is unicode)
+ self.assertIs(u.replace(u"x", u"x").__class__, unicode)
self.assertEqual(u.replace(u"x", u"x"), base)
- self.assertTrue(u.replace(u"xy", u"xy").__class__ is unicode)
+ self.assertIs(u.replace(u"xy", u"xy").__class__, unicode)
self.assertEqual(u.replace(u"xy", u"xy"), base)
- self.assertTrue(u.center(len(u)).__class__ is unicode)
+ self.assertIs(u.center(len(u)).__class__, unicode)
self.assertEqual(u.center(len(u)), base)
- self.assertTrue(u.ljust(len(u)).__class__ is unicode)
+ self.assertIs(u.ljust(len(u)).__class__, unicode)
self.assertEqual(u.ljust(len(u)), base)
- self.assertTrue(u.rjust(len(u)).__class__ is unicode)
+ self.assertIs(u.rjust(len(u)).__class__, unicode)
self.assertEqual(u.rjust(len(u)), base)
- self.assertTrue(u.lower().__class__ is unicode)
+ self.assertIs(u.lower().__class__, unicode)
self.assertEqual(u.lower(), base)
- self.assertTrue(u.upper().__class__ is unicode)
+ self.assertIs(u.upper().__class__, unicode)
self.assertEqual(u.upper(), base)
- self.assertTrue(u.capitalize().__class__ is unicode)
+ self.assertIs(u.capitalize().__class__, unicode)
self.assertEqual(u.capitalize(), base)
- self.assertTrue(u.title().__class__ is unicode)
+ self.assertIs(u.title().__class__, unicode)
self.assertEqual(u.title(), base)
- self.assertTrue((u + u"").__class__ is unicode)
+ self.assertIs((u + u"").__class__, unicode)
self.assertEqual(u + u"", base)
- self.assertTrue((u"" + u).__class__ is unicode)
+ self.assertIs((u"" + u).__class__, unicode)
self.assertEqual(u"" + u, base)
- self.assertTrue((u * 0).__class__ is unicode)
+ self.assertIs((u * 0).__class__, unicode)
self.assertEqual(u * 0, u"")
- self.assertTrue((u * 1).__class__ is unicode)
+ self.assertIs((u * 1).__class__, unicode)
self.assertEqual(u * 1, base)
- self.assertTrue((u * 2).__class__ is unicode)
+ self.assertIs((u * 2).__class__, unicode)
self.assertEqual(u * 2, base + base)
- self.assertTrue(u[:].__class__ is unicode)
+ self.assertIs(u[:].__class__, unicode)
self.assertEqual(u[:], base)
- self.assertTrue(u[0:0].__class__ is unicode)
+ self.assertIs(u[0:0].__class__, unicode)
self.assertEqual(u[0:0], u"")
class sublist(list):
@@ -2901,12 +2911,16 @@
c = {1: c1, 2: c2, 3: c3}
for x in 1, 2, 3:
for y in 1, 2, 3:
- self.assertTrue(cmp(c[x], c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
+ self.assertEqual(cmp(c[x], c[y]), cmp(x, y),
+ "x=%d, y=%d" % (x, y))
for op in "<", "<=", "==", "!=", ">", ">=":
- self.assertTrue(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
- "x=%d, y=%d" % (x, y))
- self.assertTrue(cmp(c[x], y) == cmp(x, y), "x=%d, y=%d" % (x, y))
- self.assertTrue(cmp(x, c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y))
+ self.assertEqual(eval("c[x] %s c[y]" % op),
+ eval("x %s y" % op),
+ "x=%d, y=%d" % (x, y))
+ self.assertEqual(cmp(c[x], y), cmp(x, y),
+ "x=%d, y=%d" % (x, y))
+ self.assertEqual(cmp(x, c[y]), cmp(x, y),
+ "x=%d, y=%d" % (x, y))
def test_rich_comparisons(self):
# Testing rich comparisons...
@@ -2979,12 +2993,15 @@
for x in 1, 2, 3:
for y in 1, 2, 3:
for op in "<", "<=", "==", "!=", ">", ">=":
- self.assertTrue(eval("c[x] %s c[y]" % op) == eval("x %s y" % op),
- "x=%d, y=%d" % (x, y))
- self.assertTrue(eval("c[x] %s y" % op) == eval("x %s y" % op),
- "x=%d, y=%d" % (x, y))
- self.assertTrue(eval("x %s c[y]" % op) == eval("x %s y" % op),
- "x=%d, y=%d" % (x, y))
+ self.assertEqual(eval("c[x] %s c[y]" % op),
+ eval("x %s y" % op),
+ "x=%d, y=%d" % (x, y))
+ self.assertEqual(eval("c[x] %s y" % op),
+ eval("x %s y" % op),
+ "x=%d, y=%d" % (x, y))
+ self.assertEqual(eval("x %s c[y]" % op),
+ eval("x %s y" % op),
+ "x=%d, y=%d" % (x, y))
def test_coercions(self):
# Testing coercions...
@@ -3049,9 +3066,9 @@
for cls2 in C, D, E, F:
x = cls()
x.__class__ = cls2
- self.assertTrue(x.__class__ is cls2)
+ self.assertIs(x.__class__, cls2)
x.__class__ = cls
- self.assertTrue(x.__class__ is cls)
+ self.assertIs(x.__class__, cls)
def cant(x, C):
try:
x.__class__ = C
@@ -3113,11 +3130,11 @@
x = cls()
x.a = 1
x.__class__ = cls2
- self.assertTrue(x.__class__ is cls2,
+ self.assertIs(x.__class__, cls2,
"assigning %r as __class__ for %r silently failed" % (cls2, x))
self.assertEqual(x.a, 1)
x.__class__ = cls
- self.assertTrue(x.__class__ is cls,
+ self.assertIs(x.__class__, cls,
"assigning %r as __class__ for %r silently failed" % (cls, x))
self.assertEqual(x.a, 1)
for cls in G, J, K, L, M, N, P, R, list, Int:
@@ -3287,7 +3304,7 @@
for cls in C, C1, C2:
s = p.dumps(cls, bin)
cls2 = p.loads(s)
- self.assertTrue(cls2 is cls)
+ self.assertIs(cls2, cls)
a = C1(1, 2); a.append(42); a.append(24)
b = C2("hello", "world", 42)
@@ -3317,7 +3334,7 @@
import copy
for cls in C, C1, C2:
cls2 = copy.deepcopy(cls)
- self.assertTrue(cls2 is cls)
+ self.assertIs(cls2, cls)
a = C1(1, 2); a.append(42); a.append(24)
b = C2("hello", "world", 42)
@@ -3388,9 +3405,9 @@
# Now it should work
x = C()
y = pickle.loads(pickle.dumps(x))
- self.assertEqual(hasattr(y, 'a'), 0)
+ self.assertNotHasAttr(y, 'a')
y = cPickle.loads(cPickle.dumps(x))
- self.assertEqual(hasattr(y, 'a'), 0)
+ self.assertNotHasAttr(y, 'a')
x.a = 42
y = pickle.loads(pickle.dumps(x))
self.assertEqual(y.a, 42)
@@ -3706,9 +3723,9 @@
from types import ModuleType as M
m = M.__new__(M)
str(m)
- self.assertEqual(hasattr(m, "__name__"), 0)
- self.assertEqual(hasattr(m, "__file__"), 0)
- self.assertEqual(hasattr(m, "foo"), 0)
+ self.assertNotHasAttr(m, "__name__")
+ self.assertNotHasAttr(m, "__file__")
+ self.assertNotHasAttr(m, "foo")
self.assertFalse(m.__dict__) # None or {} are both reasonable answers
m.foo = 1
self.assertEqual(m.__dict__, {"foo": 1})
@@ -3888,8 +3905,8 @@
__slots__=()
if test_support.check_impl_detail():
self.assertEqual(C.__basicsize__, B.__basicsize__)
- self.assertTrue(hasattr(C, '__dict__'))
- self.assertTrue(hasattr(C, '__weakref__'))
+ self.assertHasAttr(C, '__dict__')
+ self.assertHasAttr(C, '__weakref__')
C().x = 2
def test_rmul(self):
@@ -4390,7 +4407,7 @@
self.assertEqual(c.attr, 1)
# this makes a crash more likely:
test_support.gc_collect()
- self.assertEqual(hasattr(c, 'attr'), False)
+ self.assertNotHasAttr(c, 'attr')
def test_init(self):
# SF 1155938
@@ -4411,17 +4428,17 @@
l = []
self.assertEqual(l.__add__, l.__add__)
self.assertEqual(l.__add__, [].__add__)
- self.assertTrue(l.__add__ != [5].__add__)
- self.assertTrue(l.__add__ != l.__mul__)
- self.assertTrue(l.__add__.__name__ == '__add__')
+ self.assertNotEqual(l.__add__, [5].__add__)
+ self.assertNotEqual(l.__add__, l.__mul__)
+ self.assertEqual(l.__add__.__name__, '__add__')
if hasattr(l.__add__, '__self__'):
# CPython
- self.assertTrue(l.__add__.__self__ is l)
- self.assertTrue(l.__add__.__objclass__ is list)
+ self.assertIs(l.__add__.__self__, l)
+ self.assertIs(l.__add__.__objclass__, list)
else:
# Python implementations where [].__add__ is a normal bound method
- self.assertTrue(l.__add__.im_self is l)
- self.assertTrue(l.__add__.im_class is list)
+ self.assertIs(l.__add__.im_self, l)
+ self.assertIs(l.__add__.im_class, list)
self.assertEqual(l.__add__.__doc__, list.__add__.__doc__)
try:
hash(l.__add__)
@@ -4604,7 +4621,7 @@
fake_str = FakeStr()
# isinstance() reads __class__ on new style classes
- self.assertTrue(isinstance(fake_str, str))
+ self.assertIsInstance(fake_str, str)
# call a method descriptor
with self.assertRaises(TypeError):
diff -r 3a1db0d2747e Lib/test/test_dis.py
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -125,6 +125,8 @@
# so fails if the tests are run with -O. Skip this test then.
if __debug__:
self.do_disassembly_test(bug1333982, dis_bug1333982)
+ else:
+ self.skipTest('need asserts, run without -O')
def test_big_linenos(self):
def func(count):
diff -r 3a1db0d2747e Lib/test/test_dl.py
--- a/Lib/test/test_dl.py
+++ b/Lib/test/test_dl.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test dlmodule.c
Roger E. Masse revised strategy by Barry Warsaw
"""
diff -r 3a1db0d2747e Lib/test/test_doctest.py
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -1019,6 +1019,33 @@
ValueError: message
TestResults(failed=1, attempted=1)
+If the exception does not have a message, you can still use
+IGNORE_EXCEPTION_DETAIL to normalize the modules between Python 2 and 3:
+
+ >>> def f(x):
+ ... r'''
+ ... >>> from Queue import Empty
+ ... >>> raise Empty() #doctest: +IGNORE_EXCEPTION_DETAIL
+ ... Traceback (most recent call last):
+ ... foo.bar.Empty
+ ... '''
+ >>> test = doctest.DocTestFinder().find(f)[0]
+ >>> doctest.DocTestRunner(verbose=False).run(test)
+ TestResults(failed=0, attempted=2)
+
+Note that a trailing colon doesn't matter either:
+
+ >>> def f(x):
+ ... r'''
+ ... >>> from Queue import Empty
+ ... >>> raise Empty() #doctest: +IGNORE_EXCEPTION_DETAIL
+ ... Traceback (most recent call last):
+ ... foo.bar.Empty:
+ ... '''
+ >>> test = doctest.DocTestFinder().find(f)[0]
+ >>> doctest.DocTestRunner(verbose=False).run(test)
+ TestResults(failed=0, attempted=2)
+
If an exception is raised but not expected, then it is reported as an
unexpected exception:
diff -r 3a1db0d2747e Lib/test/test_dumbdbm.py
--- a/Lib/test/test_dumbdbm.py
+++ b/Lib/test/test_dumbdbm.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for the dumbdbm module
Original by Roger E. Masse
"""
@@ -38,11 +37,9 @@
self.read_helper(f)
f.close()
+ @unittest.skipUnless(hasattr(os, 'chmod'), 'os.chmod not available')
+ @unittest.skipUnless(hasattr(os, 'umask'), 'os.umask not available')
def test_dumbdbm_creation_mode(self):
- # On platforms without chmod, don't do anything.
- if not (hasattr(os, 'chmod') and hasattr(os, 'umask')):
- return
-
try:
old_umask = os.umask(0002)
f = dumbdbm.open(_fname, 'c', 0637)
diff -r 3a1db0d2747e Lib/test/test_enumerate.py
--- a/Lib/test/test_enumerate.py
+++ b/Lib/test/test_enumerate.py
@@ -188,11 +188,10 @@
self.assertRaises(TypeError, reversed)
self.assertRaises(TypeError, reversed, [], 'extra')
+ @unittest.skipUnless(hasattr(sys, 'getrefcount'), 'test needs sys.getrefcount()')
def test_bug1229429(self):
# this bug was never in reversed, it was in
# PyObject_CallMethod, and reversed_new calls that sometimes.
- if not hasattr(sys, "getrefcount"):
- return
def f():
pass
r = f.__reversed__ = object()
diff -r 3a1db0d2747e Lib/test/test_eof.py
--- a/Lib/test/test_eof.py
+++ b/Lib/test/test_eof.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""test script for a few new invalid token catches"""
import unittest
diff -r 3a1db0d2747e Lib/test/test_errno.py
--- a/Lib/test/test_errno.py
+++ b/Lib/test/test_errno.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test the errno module
Roger E. Masse
"""
diff -r 3a1db0d2747e Lib/test/test_fcntl.py
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -6,10 +6,9 @@
import os
import struct
import sys
-import _testcapi
import unittest
from test.test_support import (verbose, TESTFN, unlink, run_unittest,
- import_module)
+ import_module, cpython_only)
# Skip test if no fcntl module.
fcntl = import_module('fcntl')
@@ -52,6 +51,12 @@
lockdata = get_lockdata()
+class BadFile:
+ def __init__(self, fn):
+ self.fn = fn
+ def fileno(self):
+ return self.fn
+
class TestFcntl(unittest.TestCase):
def setUp(self):
@@ -83,24 +88,27 @@
self.f.close()
def test_fcntl_bad_file(self):
- class F:
- def __init__(self, fn):
- self.fn = fn
- def fileno(self):
- return self.fn
- self.assertRaises(ValueError, fcntl.fcntl, -1, fcntl.F_SETFL, os.O_NONBLOCK)
- self.assertRaises(ValueError, fcntl.fcntl, F(-1), fcntl.F_SETFL, os.O_NONBLOCK)
- self.assertRaises(TypeError, fcntl.fcntl, 'spam', fcntl.F_SETFL, os.O_NONBLOCK)
- self.assertRaises(TypeError, fcntl.fcntl, F('spam'), fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(ValueError):
+ fcntl.fcntl(-1, fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(ValueError):
+ fcntl.fcntl(BadFile(-1), fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(TypeError):
+ fcntl.fcntl('spam', fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(TypeError):
+ fcntl.fcntl(BadFile('spam'), fcntl.F_SETFL, os.O_NONBLOCK)
+
+ @cpython_only
+ def test_fcntl_bad_file_overflow(self):
+ from _testcapi import INT_MAX, INT_MIN
# Issue 15989
- self.assertRaises(ValueError, fcntl.fcntl, _testcapi.INT_MAX + 1,
- fcntl.F_SETFL, os.O_NONBLOCK)
- self.assertRaises(ValueError, fcntl.fcntl, F(_testcapi.INT_MAX + 1),
- fcntl.F_SETFL, os.O_NONBLOCK)
- self.assertRaises(ValueError, fcntl.fcntl, _testcapi.INT_MIN - 1,
- fcntl.F_SETFL, os.O_NONBLOCK)
- self.assertRaises(ValueError, fcntl.fcntl, F(_testcapi.INT_MIN - 1),
- fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(ValueError):
+ fcntl.fcntl(INT_MAX + 1, fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(ValueError):
+ fcntl.fcntl(BadFile(INT_MAX + 1), fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(ValueError):
+ fcntl.fcntl(INT_MIN - 1, fcntl.F_SETFL, os.O_NONBLOCK)
+ with self.assertRaises(ValueError):
+ fcntl.fcntl(BadFile(INT_MIN - 1), fcntl.F_SETFL, os.O_NONBLOCK)
def test_fcntl_64_bit(self):
# Issue #1309352: fcntl shouldn't fail when the third arg fits in a
@@ -113,7 +121,10 @@
self.skipTest("F_NOTIFY or DN_MULTISHOT unavailable")
fd = os.open(os.path.dirname(os.path.abspath(TESTFN)), os.O_RDONLY)
try:
+ # This will raise OverflowError if issue1309352 is present.
fcntl.fcntl(fd, cmd, flags)
+ except IOError:
+ pass # Running on a system that doesn't support these flags.
finally:
os.close(fd)
diff -r 3a1db0d2747e Lib/test/test_file2k.py
--- a/Lib/test/test_file2k.py
+++ b/Lib/test/test_file2k.py
@@ -415,6 +415,20 @@
finally:
os.unlink(TESTFN)
+ @unittest.skipUnless(os.name == 'posix', 'test requires a posix system.')
+ def test_write_full(self):
+ # Issue #17976
+ try:
+ f = open('/dev/full', 'w', 1)
+ except IOError:
+ self.skipTest("requires '/dev/full'")
+ try:
+ with self.assertRaises(IOError):
+ f.write('hello')
+ f.write('\n')
+ finally:
+ f.close()
+
class FileSubclassTests(unittest.TestCase):
def testExit(self):
diff -r 3a1db0d2747e Lib/test/test_fileinput.py
--- a/Lib/test/test_fileinput.py
+++ b/Lib/test/test_fileinput.py
@@ -218,8 +218,49 @@
finally:
remove_tempfiles(t1)
+ def test_readline(self):
+ with open(TESTFN, 'wb') as f:
+ f.write('A\nB\r\nC\r')
+ # Fill TextIOWrapper buffer.
+ f.write('123456789\n' * 1000)
+ # Issue #20501: readline() shouldn't read whole file.
+ f.write('\x80')
+ self.addCleanup(safe_unlink, TESTFN)
+
+ fi = FileInput(files=TESTFN, openhook=hook_encoded('ascii'), bufsize=8)
+ # The most likely failure is a UnicodeDecodeError due to the entire
+ # file being read when it shouldn't have been.
+ self.assertEqual(fi.readline(), u'A\n')
+ self.assertEqual(fi.readline(), u'B\r\n')
+ self.assertEqual(fi.readline(), u'C\r')
+ with self.assertRaises(UnicodeDecodeError):
+ # Read to the end of file.
+ list(fi)
+ fi.close()
+
+class Test_hook_encoded(unittest.TestCase):
+ """Unit tests for fileinput.hook_encoded()"""
+
+ def test_modes(self):
+ with open(TESTFN, 'wb') as f:
+ # UTF-7 is a convenient, seldom used encoding
+ f.write('A\nB\r\nC\rD+IKw-')
+ self.addCleanup(safe_unlink, TESTFN)
+
+ def check(mode, expected_lines):
+ fi = FileInput(files=TESTFN, mode=mode,
+ openhook=hook_encoded('utf-7'))
+ lines = list(fi)
+ fi.close()
+ self.assertEqual(lines, expected_lines)
+
+ check('r', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+ check('rU', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+ check('U', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+ check('rb', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+
def test_main():
- run_unittest(BufferSizesTests, FileInputTests)
+ run_unittest(BufferSizesTests, FileInputTests, Test_hook_encoded)
if __name__ == "__main__":
test_main()
diff -r 3a1db0d2747e Lib/test/test_fileio.py
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -10,10 +10,9 @@
from weakref import proxy
from functools import wraps
from UserList import UserList
-import _testcapi
from test.test_support import TESTFN, check_warnings, run_unittest, make_bad_fd
-from test.test_support import py3k_bytes as bytes
+from test.test_support import py3k_bytes as bytes, cpython_only
from test.script_helper import run_python
from _io import FileIO as _FileIO
@@ -283,28 +282,29 @@
self.assertEqual(f.seekable(), True)
self.assertEqual(f.isatty(), False)
f.close()
-
- if sys.platform != "win32":
- try:
- f = _FileIO("/dev/tty", "a")
- except EnvironmentError:
- # When run in a cron job there just aren't any
- # ttys, so skip the test. This also handles other
- # OS'es that don't support /dev/tty.
- pass
- else:
- self.assertEqual(f.readable(), False)
- self.assertEqual(f.writable(), True)
- if sys.platform != "darwin" and \
- 'bsd' not in sys.platform and \
- not sys.platform.startswith('sunos'):
- # Somehow /dev/tty appears seekable on some BSDs
- self.assertEqual(f.seekable(), False)
- self.assertEqual(f.isatty(), True)
- f.close()
finally:
os.unlink(TESTFN)
+ @unittest.skipIf(sys.platform == 'win32', 'no ttys on Windows')
+ def testAblesOnTTY(self):
+ try:
+ f = _FileIO("/dev/tty", "a")
+ except EnvironmentError:
+ # When run in a cron job there just aren't any
+ # ttys, so skip the test. This also handles other
+ # OS'es that don't support /dev/tty.
+ self.skipTest('need /dev/tty')
+ else:
+ self.assertEqual(f.readable(), False)
+ self.assertEqual(f.writable(), True)
+ if sys.platform != "darwin" and \
+ 'bsd' not in sys.platform and \
+ not sys.platform.startswith('sunos'):
+ # Somehow /dev/tty appears seekable on some BSDs
+ self.assertEqual(f.seekable(), False)
+ self.assertEqual(f.isatty(), True)
+ f.close()
+
def testInvalidModeStrings(self):
# check invalid mode strings
for mode in ("", "aU", "wU+", "rw", "rt"):
@@ -342,8 +342,7 @@
try:
fn = TESTFN.encode("ascii")
except UnicodeEncodeError:
- # Skip test
- return
+ self.skipTest('could not encode %r to ascii' % TESTFN)
f = _FileIO(fn, "w")
try:
f.write(b"abc")
@@ -359,7 +358,11 @@
if sys.platform == 'win32':
import msvcrt
self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
+
+ @cpython_only
+ def testInvalidFd_overflow(self):
# Issue 15989
+ import _testcapi
self.assertRaises(TypeError, _FileIO, _testcapi.INT_MAX + 1)
self.assertRaises(TypeError, _FileIO, _testcapi.INT_MIN - 1)
diff -r 3a1db0d2747e Lib/test/test_float.py
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -101,7 +101,7 @@
# it still has to accept the normal python syntax
import locale
if not locale.localeconv()['decimal_point'] == ',':
- return
+ self.skipTest('decimal_point is not ","')
self.assertEqual(float(" 3.14 "), 3.14)
self.assertEqual(float("+3.14 "), 3.14)
diff -r 3a1db0d2747e Lib/test/test_format.py
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -303,21 +303,31 @@
test_support.run_unittest(FormatTest)
def test_precision(self):
- INT_MAX = 2147483647
-
f = 1.2
self.assertEqual(format(f, ".0f"), "1")
self.assertEqual(format(f, ".3f"), "1.200")
with self.assertRaises(ValueError) as cm:
- format(f, ".%sf" % (INT_MAX + 1))
+ format(f, ".%sf" % (sys.maxsize + 1))
self.assertEqual(str(cm.exception), "precision too big")
c = complex(f)
- self.assertEqual(format(f, ".0f"), "1")
- self.assertEqual(format(f, ".3f"), "1.200")
+ self.assertEqual(format(c, ".0f"), "1+0j")
+ self.assertEqual(format(c, ".3f"), "1.200+0.000j")
+ with self.assertRaises(ValueError) as cm:
+ format(c, ".%sf" % (sys.maxsize + 1))
+ self.assertEqual(str(cm.exception), "precision too big")
+
+ @test_support.cpython_only
+ def test_precision_c_limits(self):
+ from _testcapi import INT_MAX
+
+ f = 1.2
with self.assertRaises(ValueError) as cm:
format(f, ".%sf" % (INT_MAX + 1))
- self.assertEqual(str(cm.exception), "precision too big")
+
+ c = complex(f)
+ with self.assertRaises(ValueError) as cm:
+ format(c, ".%sf" % (INT_MAX + 1))
if __name__ == "__main__":
diff -r 3a1db0d2747e Lib/test/test_ftplib.py
--- a/Lib/test/test_ftplib.py
+++ b/Lib/test/test_ftplib.py
@@ -15,7 +15,7 @@
except ImportError:
ssl = None
-from unittest import TestCase
+from unittest import TestCase, SkipTest, skipUnless
from test import test_support
from test.test_support import HOST, HOSTv6
threading = test_support.import_module('threading')
@@ -579,8 +579,16 @@
self.assertRaises(ftplib.Error, self.client.storlines, 'stor', f)
+@skipUnless(socket.has_ipv6, "IPv6 not enabled")
class TestIPv6Environment(TestCase):
+ @classmethod
+ def setUpClass(cls):
+ try:
+ DummyFTPServer((HOST, 0), af=socket.AF_INET6)
+ except socket.error:
+ raise SkipTest("IPv6 not enabled")
+
def setUp(self):
self.server = DummyFTPServer((HOSTv6, 0), af=socket.AF_INET6)
self.server.start()
@@ -615,6 +623,7 @@
retr()
+@skipUnless(ssl, "SSL not available")
class TestTLS_FTPClassMixin(TestFTPClass):
"""Repeat TestFTPClass tests starting the TLS layer for both control
and data connections first.
@@ -630,6 +639,7 @@
self.client.prot_p()
+@skipUnless(ssl, "SSL not available")
class TestTLS_FTPClass(TestCase):
"""Specific TLS_FTP class tests."""
@@ -730,7 +740,7 @@
def testTimeoutDefault(self):
# default -- use global socket timeout
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
ftp = ftplib.FTP(HOST)
@@ -742,13 +752,13 @@
def testTimeoutNone(self):
# no timeout -- do not use global socket timeout
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
ftp = ftplib.FTP(HOST, timeout=None)
finally:
socket.setdefaulttimeout(None)
- self.assertTrue(ftp.sock.gettimeout() is None)
+ self.assertIsNone(ftp.sock.gettimeout())
self.evt.wait()
ftp.close()
@@ -783,17 +793,9 @@
def test_main():
- tests = [TestFTPClass, TestTimeouts]
- if socket.has_ipv6:
- try:
- DummyFTPServer((HOST, 0), af=socket.AF_INET6)
- except socket.error:
- pass
- else:
- tests.append(TestIPv6Environment)
-
- if ssl is not None:
- tests.extend([TestTLS_FTPClassMixin, TestTLS_FTPClass])
+ tests = [TestFTPClass, TestTimeouts,
+ TestIPv6Environment,
+ TestTLS_FTPClassMixin, TestTLS_FTPClass]
thread_info = test_support.threading_setup()
try:
diff -r 3a1db0d2747e Lib/test/test_functools.py
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -43,8 +43,6 @@
self.assertEqual(p.args, (1, 2))
self.assertEqual(p.keywords, dict(a=10, b=20))
# attributes should not be writable
- if not isinstance(self.thetype, type):
- return
self.assertRaises(TypeError, setattr, p, 'func', map)
self.assertRaises(TypeError, setattr, p, 'args', (1, 2))
self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2))
@@ -180,8 +178,10 @@
thetype = PythonPartial
# the python version isn't picklable
- def test_pickle(self): pass
- def test_setstate_refcount(self): pass
+ test_pickle = test_setstate_refcount = None
+
+ # the python version isn't a type
+ test_attributes = None
class TestUpdateWrapper(unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/test_gdb.py
--- a/Lib/test/test_gdb.py
+++ b/Lib/test/test_gdb.py
@@ -49,7 +49,7 @@
return out, err
# Verify that "gdb" was built with the embedded python support enabled:
-gdbpy_version, _ = run_gdb("--eval-command=python import sys; print sys.version_info")
+gdbpy_version, _ = run_gdb("--eval-command=python import sys; print(sys.version_info)")
if not gdbpy_version:
raise unittest.SkipTest("gdb not built with embedded python support")
@@ -214,7 +214,7 @@
# matches repr(value) in this process:
gdb_repr, gdb_output = self.get_gdb_repr('print ' + repr(val),
cmds_after_breakpoint)
- self.assertEqual(gdb_repr, repr(val), gdb_output)
+ self.assertEqual(gdb_repr, repr(val))
def test_int(self):
'Verify the pretty-printing of various "int" values'
diff -r 3a1db0d2747e Lib/test/test_genericpath.py
--- a/Lib/test/test_genericpath.py
+++ b/Lib/test/test_genericpath.py
@@ -199,13 +199,40 @@
self.assertEqual(expandvars("$[foo]bar"), "$[foo]bar")
self.assertEqual(expandvars("$bar bar"), "$bar bar")
self.assertEqual(expandvars("$?bar"), "$?bar")
- self.assertEqual(expandvars("${foo}bar"), "barbar")
self.assertEqual(expandvars("$foo}bar"), "bar}bar")
self.assertEqual(expandvars("${foo"), "${foo")
self.assertEqual(expandvars("${{foo}}"), "baz1}")
self.assertEqual(expandvars("$foo$foo"), "barbar")
self.assertEqual(expandvars("$bar$bar"), "$bar$bar")
+ @unittest.skipUnless(test_support.FS_NONASCII, 'need test_support.FS_NONASCII')
+ def test_expandvars_nonascii(self):
+ if self.pathmodule.__name__ == 'macpath':
+ self.skipTest('macpath.expandvars is a stub')
+ expandvars = self.pathmodule.expandvars
+ def check(value, expected):
+ self.assertEqual(expandvars(value), expected)
+ encoding = sys.getfilesystemencoding()
+ with test_support.EnvironmentVarGuard() as env:
+ env.clear()
+ unonascii = test_support.FS_NONASCII
+ snonascii = unonascii.encode(encoding)
+ env['spam'] = snonascii
+ env[snonascii] = 'ham' + snonascii
+ check(snonascii, snonascii)
+ check('$spam bar', '%s bar' % snonascii)
+ check('${spam}bar', '%sbar' % snonascii)
+ check('${%s}bar' % snonascii, 'ham%sbar' % snonascii)
+ check('$bar%s bar' % snonascii, '$bar%s bar' % snonascii)
+ check('$spam}bar', '%s}bar' % snonascii)
+
+ check(unonascii, unonascii)
+ check(u'$spam bar', u'%s bar' % unonascii)
+ check(u'${spam}bar', u'%sbar' % unonascii)
+ check(u'${%s}bar' % unonascii, u'ham%sbar' % unonascii)
+ check(u'$bar%s bar' % unonascii, u'$bar%s bar' % unonascii)
+ check(u'$spam}bar', u'%s}bar' % unonascii)
+
def test_abspath(self):
self.assertIn("foo", self.pathmodule.abspath("foo"))
diff -r 3a1db0d2747e Lib/test/test_getargs2.py
--- a/Lib/test/test_getargs2.py
+++ b/Lib/test/test_getargs2.py
@@ -1,5 +1,7 @@
import unittest
from test import test_support
+# Skip this test if the _testcapi module isn't available.
+test_support.import_module('_testcapi')
from _testcapi import getargs_keywords
import warnings
@@ -42,6 +44,13 @@
INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
SHRT_MIN, SHRT_MAX
+try:
+ from _testcapi import getargs_L, getargs_K
+except ImportError:
+ _PY_LONG_LONG_available = False
+else:
+ _PY_LONG_LONG_available = True
+
# fake, they are not defined in Python's header files
LLONG_MAX = 2**63-1
LLONG_MIN = -2**63
@@ -208,6 +217,7 @@
self.assertRaises(OverflowError, getargs_n, VERY_LARGE)
+@unittest.skipUnless(_PY_LONG_LONG_available, 'PY_LONG_LONG not available')
class LongLong_TestCase(unittest.TestCase):
def test_L(self):
from _testcapi import getargs_L
@@ -322,13 +332,8 @@
self.fail('TypeError should have been raised')
def test_main():
- tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase, Keywords_TestCase]
- try:
- from _testcapi import getargs_L, getargs_K
- except ImportError:
- pass # PY_LONG_LONG not available
- else:
- tests.append(LongLong_TestCase)
+ tests = [Signed_TestCase, Unsigned_TestCase, LongLong_TestCase,
+ Tuple_TestCase, Keywords_TestCase]
test_support.run_unittest(*tests)
if __name__ == "__main__":
diff -r 3a1db0d2747e Lib/test/test_gl.py
--- a/Lib/test/test_gl.py
+++ b/Lib/test/test_gl.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Very simple test script for the SGI gl library extension module
taken mostly from the documentation.
Roger E. Masse
diff -r 3a1db0d2747e Lib/test/test_grp.py
--- a/Lib/test/test_grp.py
+++ b/Lib/test/test_grp.py
@@ -26,8 +26,10 @@
for e in entries:
self.check_value(e)
+ def test_values_extended(self):
+ entries = grp.getgrall()
if len(entries) > 1000: # Huge group file (NIS?) -- skip the rest
- return
+ self.skipTest('huge group file, extended test skipped')
for e in entries:
e2 = grp.getgrgid(e.gr_gid)
diff -r 3a1db0d2747e Lib/test/test_gzip.py
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for the gzip module.
"""
diff -r 3a1db0d2747e Lib/test/test_hashlib.py
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -207,30 +207,20 @@
self.check('md5', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'd174ab98d277d9f5a5611c2c9f419d9f')
- @precisionbigmemtest(size=_4G + 5, memuse=1)
+ @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems')
+ @precisionbigmemtest(size=_4G + 5, memuse=1, dry_run=False)
def test_case_md5_huge(self, size):
- if size == _4G + 5:
- try:
- self.check('md5', 'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
- except OverflowError:
- pass # 32-bit arch
+ self.check('md5', 'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
- @precisionbigmemtest(size=_4G + 5, memuse=1)
+ @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems')
+ @precisionbigmemtest(size=_4G + 5, memuse=1, dry_run=False)
def test_case_md5_huge_update(self, size):
- if size == _4G + 5:
- try:
- self.check_update('md5', 'A'*size,
- 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
- except OverflowError:
- pass # 32-bit arch
+ self.check_update('md5', 'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
- @precisionbigmemtest(size=_4G - 1, memuse=1)
+ @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems')
+ @precisionbigmemtest(size=_4G - 1, memuse=1, dry_run=False)
def test_case_md5_uintmax(self, size):
- if size == _4G - 1:
- try:
- self.check('md5', 'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
- except OverflowError:
- pass # 32-bit arch
+ self.check('md5', 'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
# use the three examples from Federal Information Processing Standards
# Publication 180-1, Secure Hash Standard, 1995 April 17
diff -r 3a1db0d2747e Lib/test/test_htmlparser.py
--- a/Lib/test/test_htmlparser.py
+++ b/Lib/test/test_htmlparser.py
@@ -206,8 +206,7 @@
self._run_check("</$>", [('comment', '$')])
self._run_check("</", [('data', '</')])
self._run_check("</a", [('data', '</a')])
- # XXX this might be wrong
- self._run_check("<a<a>", [('data', '<a'), ('starttag', 'a', [])])
+ self._run_check("<a<a>", [('starttag', 'a<a', [])])
self._run_check("</a<a>", [('endtag', 'a<a')])
self._run_check("<!", [('data', '<!')])
self._run_check("<a", [('data', '<a')])
@@ -215,6 +214,11 @@
self._run_check("<a foo='bar", [('data', "<a foo='bar")])
self._run_check("<a foo='>'", [('data', "<a foo='>'")])
self._run_check("<a foo='>", [('data', "<a foo='>")])
+ self._run_check("<a$>", [('starttag', 'a$', [])])
+ self._run_check("<a$b>", [('starttag', 'a$b', [])])
+ self._run_check("<a$b/>", [('startendtag', 'a$b', [])])
+ self._run_check("<a$b >", [('starttag', 'a$b', [])])
+ self._run_check("<a$b />", [('startendtag', 'a$b', [])])
def test_valid_doctypes(self):
# from http://www.w3.org/QA/2002/04/valid-dtd-list.html
@@ -390,6 +394,12 @@
("data", "&#bad;"),
("endtag", "p"),
])
+ # add the [] as a workaround to avoid buffering (see #20288)
+ self._run_check(["<div>&#bad;</div>"], [
+ ("starttag", "div", []),
+ ("data", "&#bad;"),
+ ("endtag", "div"),
+ ])
def test_unescape_function(self):
parser = HTMLParser.HTMLParser()
diff -r 3a1db0d2747e Lib/test/test_httplib.py
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -123,7 +123,7 @@
conn.sock = FakeSocket(None)
conn.putrequest('GET','/')
conn.putheader('Content-length',42)
- self.assertTrue('Content-length: 42' in conn._buffer)
+ self.assertIn('Content-length: 42', conn._buffer)
def test_ipv6host_header(self):
# Default host header on IPv6 transaction should wrapped by [] if
@@ -153,6 +153,8 @@
sock = FakeSocket(body)
resp = httplib.HTTPResponse(sock)
resp.begin()
+ self.assertEqual(resp.read(0), '') # Issue #20007
+ self.assertFalse(resp.isclosed())
self.assertEqual(resp.read(), 'Text')
self.assertTrue(resp.isclosed())
@@ -464,7 +466,7 @@
HTTPConnection and into the socket.
'''
# default -- use global socket timeout
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
@@ -475,7 +477,7 @@
httpConn.close()
# no timeout -- do not use global socket default
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
diff -r 3a1db0d2747e Lib/test/test_httpservers.py
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -114,7 +114,7 @@
def verify_http_server_response(self, response):
match = self.HTTPResponseMatch.search(response)
- self.assertTrue(match is not None)
+ self.assertIsNotNone(match)
def test_http_1_1(self):
result = self.send_typical_request('GET / HTTP/1.1\r\n\r\n')
diff -r 3a1db0d2747e Lib/test/test_idle.py
--- a/Lib/test/test_idle.py
+++ b/Lib/test/test_idle.py
@@ -14,6 +14,7 @@
try:
root = tk.Tk()
root.destroy()
+ del root
except tk.TclError:
while 'gui' in use_resources:
use_resources.remove('gui')
@@ -23,6 +24,10 @@
# load_tests() if it finds it. (Unittest.main does the same.)
load_tests = idletest.load_tests
+# pre-3.3 regrtest does not support the load_tests protocol. use test_main
+def test_main():
+ support.run_unittest(unittest.TestLoader().loadTestsFromModule(idletest))
+
if __name__ == '__main__':
# Until unittest supports resources, we emulate regrtest's -ugui
# so loaded tests run the same as if textually present here.
diff -r 3a1db0d2747e Lib/test/test_imageop.py
--- a/Lib/test/test_imageop.py
+++ b/Lib/test/test_imageop.py
@@ -1,5 +1,3 @@
-#! /usr/bin/env python
-
"""Test script for the imageop module. This has the side
effect of partially testing the imgfile module as well.
Roger E. Masse
diff -r 3a1db0d2747e Lib/test/test_imaplib.py
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -165,6 +165,16 @@
self.imap_class, *server.server_address)
+ def test_linetoolong(self):
+ class TooLongHandler(SimpleIMAPHandler):
+ def handle(self):
+ # Send a very long response line
+ self.wfile.write('* OK ' + imaplib._MAXLINE*'x' + '\r\n')
+
+ with self.reaped_server(TooLongHandler) as server:
+ self.assertRaises(imaplib.IMAP4.error,
+ self.imap_class, *server.server_address)
+
class ThreadedNetworkedTests(BaseThreadedNetworkedTests):
server_class = SocketServer.TCPServer
@@ -177,6 +187,9 @@
server_class = SecureTCPServer
imap_class = IMAP4_SSL
+ def test_linetoolong(self):
+ raise unittest.SkipTest("test is not reliable on 2.7; see issue 20118")
+
class RemoteIMAPTest(unittest.TestCase):
host = 'cyrus.andrew.cmu.edu'
diff -r 3a1db0d2747e Lib/test/test_imgfile.py
--- a/Lib/test/test_imgfile.py
+++ b/Lib/test/test_imgfile.py
@@ -1,5 +1,3 @@
-#! /usr/bin/env python
-
"""Simple test script for imgfile.c
Roger E. Masse
"""
diff -r 3a1db0d2747e Lib/test/test_imghdr.py
--- /dev/null
+++ b/Lib/test/test_imghdr.py
@@ -0,0 +1,120 @@
+import imghdr
+import io
+import sys
+import unittest
+from test.test_support import findfile, TESTFN, unlink, run_unittest
+
+TEST_FILES = (
+ ('python.png', 'png'),
+ ('python.gif', 'gif'),
+ ('python.bmp', 'bmp'),
+ ('python.ppm', 'ppm'),
+ ('python.pgm', 'pgm'),
+ ('python.pbm', 'pbm'),
+ ('python.jpg', 'jpeg'),
+ ('python.ras', 'rast'),
+ ('python.sgi', 'rgb'),
+ ('python.tiff', 'tiff'),
+ ('python.xbm', 'xbm')
+)
+
+class UnseekableIO(io.FileIO):
+ def tell(self):
+ raise io.UnsupportedOperation
+
+ def seek(self, *args, **kwargs):
+ raise io.UnsupportedOperation
+
+class TestImghdr(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.testfile = findfile('python.png', subdir='imghdrdata')
+ with open(cls.testfile, 'rb') as stream:
+ cls.testdata = stream.read()
+
+ def tearDown(self):
+ unlink(TESTFN)
+
+ def test_data(self):
+ for filename, expected in TEST_FILES:
+ filename = findfile(filename, subdir='imghdrdata')
+ self.assertEqual(imghdr.what(filename), expected)
+ ufilename = filename.decode(sys.getfilesystemencoding())
+ self.assertEqual(imghdr.what(ufilename), expected)
+ with open(filename, 'rb') as stream:
+ self.assertEqual(imghdr.what(stream), expected)
+ with open(filename, 'rb') as stream:
+ data = stream.read()
+ self.assertEqual(imghdr.what(None, data), expected)
+
+ def test_register_test(self):
+ def test_jumbo(h, file):
+ if h.startswith(b'eggs'):
+ return 'ham'
+ imghdr.tests.append(test_jumbo)
+ self.addCleanup(imghdr.tests.pop)
+ self.assertEqual(imghdr.what(None, b'eggs'), 'ham')
+
+ def test_file_pos(self):
+ with open(TESTFN, 'wb') as stream:
+ stream.write(b'ababagalamaga')
+ pos = stream.tell()
+ stream.write(self.testdata)
+ with open(TESTFN, 'rb') as stream:
+ stream.seek(pos)
+ self.assertEqual(imghdr.what(stream), 'png')
+ self.assertEqual(stream.tell(), pos)
+
+ def test_bad_args(self):
+ with self.assertRaises(TypeError):
+ imghdr.what()
+ with self.assertRaises(AttributeError):
+ imghdr.what(None)
+ with self.assertRaises(TypeError):
+ imghdr.what(self.testfile, 1)
+ with open(self.testfile, 'rb') as f:
+ with self.assertRaises(AttributeError):
+ imghdr.what(f.fileno())
+
+ def test_invalid_headers(self):
+ for header in (b'\211PN\r\n',
+ b'\001\331',
+ b'\x59\xA6',
+ b'cutecat',
+ b'000000JFI',
+ b'GIF80'):
+ self.assertIsNone(imghdr.what(None, header))
+
+ def test_missing_file(self):
+ with self.assertRaises(IOError):
+ imghdr.what('missing')
+
+ def test_closed_file(self):
+ stream = open(self.testfile, 'rb')
+ stream.close()
+ with self.assertRaises(ValueError) as cm:
+ imghdr.what(stream)
+ stream = io.BytesIO(self.testdata)
+ stream.close()
+ with self.assertRaises(ValueError) as cm:
+ imghdr.what(stream)
+
+ def test_unseekable(self):
+ with open(TESTFN, 'wb') as stream:
+ stream.write(self.testdata)
+ with UnseekableIO(TESTFN, 'rb') as stream:
+ with self.assertRaises(io.UnsupportedOperation):
+ imghdr.what(stream)
+
+ def test_output_stream(self):
+ with open(TESTFN, 'wb') as stream:
+ stream.write(self.testdata)
+ stream.seek(0)
+ with self.assertRaises(IOError) as cm:
+ imghdr.what(stream)
+
+def test_main():
+ run_unittest(TestImghdr)
+
+if __name__ == '__main__':
+ test_main()
diff -r 3a1db0d2747e Lib/test/test_imp.py
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -2,7 +2,12 @@
import unittest
from test import test_support
+try:
+ import thread
+except ImportError:
+ thread = None
+@unittest.skipUnless(thread, 'threading not available')
class LockTests(unittest.TestCase):
"""Very basic test of import lock functions."""
@@ -68,13 +73,8 @@
def test_main():
tests = [
ReloadTests,
+ LockTests,
]
- try:
- import thread
- except ImportError:
- pass
- else:
- tests.append(LockTests)
test_support.run_unittest(*tests)
if __name__ == "__main__":
diff -r 3a1db0d2747e Lib/test/test_index.py
--- a/Lib/test/test_index.py
+++ b/Lib/test/test_index.py
@@ -91,7 +91,7 @@
self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3])
self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4])
- def test_slice_bug7532(self):
+ def test_slice_bug7532a(self):
seqlen = len(self.seq)
self.o.ind = int(seqlen * 1.5)
self.n.ind = seqlen + 2
@@ -99,9 +99,12 @@
self.assertEqual(self.seq[:self.o], self.seq)
self.assertEqual(self.seq[self.n:], self.seq[0:0])
self.assertEqual(self.seq[:self.n], self.seq)
+
+ def test_slice_bug7532b(self):
if isinstance(self.seq, ClassicSeq):
- return
+ self.skipTest('test fails for ClassicSeq')
# These tests fail for ClassicSeq (see bug #7532)
+ seqlen = len(self.seq)
self.o2.ind = -seqlen - 2
self.n2.ind = -int(seqlen * 1.5)
self.assertEqual(self.seq[self.o2:], self.seq)
diff -r 3a1db0d2747e Lib/test/test_io.py
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -393,14 +393,9 @@
# a long time to build the >2GB file and takes >2GB of disk space
# therefore the resource must be enabled to run this test.
if sys.platform[:3] == 'win' or sys.platform == 'darwin':
- if not support.is_resource_enabled("largefile"):
- print("\nTesting large file ops skipped on %s." % sys.platform,
- file=sys.stderr)
- print("It requires %d bytes and a long time." % self.LARGE,
- file=sys.stderr)
- print("Use 'regrtest.py -u largefile test_io' to run it.",
- file=sys.stderr)
- return
+ support.requires(
+ 'largefile',
+ 'test requires %s bytes and a long time to run' % self.LARGE)
with self.open(support.TESTFN, "w+b", 0) as f:
self.large_file_ops(f)
with self.open(support.TESTFN, "w+b") as f:
@@ -650,6 +645,7 @@
self.assertEqual(42, bufio.fileno())
+ @unittest.skip('test having existential crisis')
def test_no_fileno(self):
# XXX will we always have fileno() function? If so, kill
# this test. Else, write it.
@@ -797,6 +793,16 @@
bufio.__init__(rawio)
self.assertEqual(b"abc", bufio.read())
+ def test_uninitialized(self):
+ bufio = self.tp.__new__(self.tp)
+ del bufio
+ bufio = self.tp.__new__(self.tp)
+ self.assertRaisesRegexp((ValueError, AttributeError),
+ 'uninitialized|has no attribute',
+ bufio.read, 0)
+ bufio.__init__(self.MockRawIO())
+ self.assertEqual(bufio.read(0), b'')
+
def test_read(self):
for arg in (None, 7):
rawio = self.MockRawIO((b"abc", b"d", b"efg"))
@@ -1033,6 +1039,16 @@
bufio.flush()
self.assertEqual(b"".join(rawio._write_stack), b"abcghi")
+ def test_uninitialized(self):
+ bufio = self.tp.__new__(self.tp)
+ del bufio
+ bufio = self.tp.__new__(self.tp)
+ self.assertRaisesRegexp((ValueError, AttributeError),
+ 'uninitialized|has no attribute',
+ bufio.write, b'')
+ bufio.__init__(self.MockRawIO())
+ self.assertEqual(bufio.write(b''), 0)
+
def test_detach_flush(self):
raw = self.MockRawIO()
buf = self.tp(raw)
@@ -1317,6 +1333,20 @@
pair = self.tp(self.MockRawIO(), self.MockRawIO())
self.assertFalse(pair.closed)
+ def test_uninitialized(self):
+ pair = self.tp.__new__(self.tp)
+ del pair
+ pair = self.tp.__new__(self.tp)
+ self.assertRaisesRegexp((ValueError, AttributeError),
+ 'uninitialized|has no attribute',
+ pair.read, 0)
+ self.assertRaisesRegexp((ValueError, AttributeError),
+ 'uninitialized|has no attribute',
+ pair.write, b'')
+ pair.__init__(self.MockRawIO(), self.MockRawIO())
+ self.assertEqual(pair.read(0), b'')
+ self.assertEqual(pair.write(b''), 0)
+
def test_detach(self):
pair = self.tp(self.MockRawIO(), self.MockRawIO())
self.assertRaises(self.UnsupportedOperation, pair.detach)
@@ -1444,6 +1474,10 @@
BufferedReaderTest.test_constructor(self)
BufferedWriterTest.test_constructor(self)
+ def test_uninitialized(self):
+ BufferedReaderTest.test_uninitialized(self)
+ BufferedWriterTest.test_uninitialized(self)
+
def test_read_and_write(self):
raw = self.MockRawIO((b"asdf", b"ghjk"))
rw = self.tp(raw, 8)
diff -r 3a1db0d2747e Lib/test/test_iter.py
--- a/Lib/test/test_iter.py
+++ b/Lib/test/test_iter.py
@@ -526,7 +526,7 @@
d = {"one": 1, "two": 2, "three": 3}
self.assertEqual(reduce(add, d), "".join(d.keys()))
- # This test case will be removed if we don't have Unicode
+ @unittest.skipUnless(have_unicode, 'needs unicode support')
def test_unicode_join_endcase(self):
# This class inserts a Unicode object into its argument's natural
@@ -567,8 +567,6 @@
unlink(TESTFN)
except OSError:
pass
- if not have_unicode:
- def test_unicode_join_endcase(self): pass
# Test iterators with 'x in y' and 'x not in y'.
def test_in_and_not_in(self):
diff -r 3a1db0d2747e Lib/test/test_locale.py
--- a/Lib/test/test_locale.py
+++ b/Lib/test/test_locale.py
@@ -372,6 +372,77 @@
self.assertEqual('\xec\xa0\xbc'.split(), ['\xec\xa0\xbc'])
+class NormalizeTest(unittest.TestCase):
+ def check(self, localename, expected):
+ self.assertEqual(locale.normalize(localename), expected, msg=localename)
+
+ def test_locale_alias(self):
+ for localename, alias in locale.locale_alias.items():
+ self.check(localename, alias)
+
+ def test_empty(self):
+ self.check('', '')
+
+ def test_c(self):
+ self.check('c', 'C')
+ self.check('posix', 'C')
+
+ def test_english(self):
+ self.check('en', 'en_US.ISO8859-1')
+ self.check('EN', 'en_US.ISO8859-1')
+ self.check('en_US', 'en_US.ISO8859-1')
+ self.check('en_us', 'en_US.ISO8859-1')
+ self.check('en_GB', 'en_GB.ISO8859-1')
+ self.check('en_US.UTF-8', 'en_US.UTF-8')
+ self.check('en_US.utf8', 'en_US.UTF-8')
+ self.check('en_US:UTF-8', 'en_US.UTF-8')
+ self.check('en_US.ISO8859-1', 'en_US.ISO8859-1')
+ self.check('en_US.US-ASCII', 'en_US.ISO8859-1')
+ self.check('english', 'en_EN.ISO8859-1')
+
+ def test_hyphenated_encoding(self):
+ self.check('az_AZ.iso88599e', 'az_AZ.ISO8859-9E')
+ self.check('az_AZ.ISO8859-9E', 'az_AZ.ISO8859-9E')
+ self.check('tt_RU.koi8c', 'tt_RU.KOI8-C')
+ self.check('tt_RU.KOI8-C', 'tt_RU.KOI8-C')
+ self.check('lo_LA.cp1133', 'lo_LA.IBM-CP1133')
+ self.check('lo_LA.ibmcp1133', 'lo_LA.IBM-CP1133')
+ self.check('lo_LA.IBM-CP1133', 'lo_LA.IBM-CP1133')
+ self.check('uk_ua.microsoftcp1251', 'uk_UA.CP1251')
+ self.check('uk_ua.microsoft-cp1251', 'uk_UA.CP1251')
+ self.check('ka_ge.georgianacademy', 'ka_GE.GEORGIAN-ACADEMY')
+ self.check('ka_GE.GEORGIAN-ACADEMY', 'ka_GE.GEORGIAN-ACADEMY')
+ self.check('cs_CZ.iso88592', 'cs_CZ.ISO8859-2')
+ self.check('cs_CZ.ISO8859-2', 'cs_CZ.ISO8859-2')
+
+ def test_euro_modifier(self):
+ self.check('de_DE@euro', 'de_DE.ISO8859-15')
+ self.check('en_US.ISO8859-15@euro', 'en_US.ISO8859-15')
+
+ def test_latin_modifier(self):
+ self.check('be_BY.UTF-8@latin', 'be_BY.UTF-8@latin')
+ self.check('sr_RS.UTF-8@latin', 'sr_RS.UTF-8@latin')
+
+ def test_valencia_modifier(self):
+ self.check('ca_ES.UTF-8@valencia', 'ca_ES.UTF-8@valencia')
+ self.check('ca_ES@valencia', 'ca_ES.ISO8859-1@valencia')
+ self.check('ca@valencia', 'ca_ES.ISO8859-1@valencia')
+
+ def test_devanagari_modifier(self):
+ self.check('ks_IN.UTF-8@devanagari', 'ks_IN.UTF-8@devanagari')
+ self.check('ks_IN@devanagari', 'ks_IN.UTF-8@devanagari')
+ self.check('ks@devanagari', 'ks_IN.UTF-8@devanagari')
+ self.check('ks_IN.UTF-8', 'ks_IN.UTF-8')
+ self.check('ks_IN', 'ks_IN.UTF-8')
+ self.check('ks', 'ks_IN.UTF-8')
+ self.check('sd_IN.UTF-8@devanagari', 'sd_IN.UTF-8@devanagari')
+ self.check('sd_IN@devanagari', 'sd_IN.UTF-8@devanagari')
+ self.check('sd@devanagari', 'sd_IN.UTF-8@devanagari')
+ self.check('sd_IN.UTF-8', 'sd_IN.UTF-8')
+ self.check('sd_IN', 'sd_IN.UTF-8')
+ self.check('sd', 'sd_IN.UTF-8')
+
+
class TestMiscellaneous(unittest.TestCase):
def test_getpreferredencoding(self):
# Invoke getpreferredencoding to make sure it does not cause exceptions.
@@ -400,13 +471,21 @@
# Issue #1813: setting and getting the locale under a Turkish locale
oldlocale = locale.getlocale()
self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale)
- try:
- locale.setlocale(locale.LC_CTYPE, 'tr_TR')
- except locale.Error:
+ for loc in ('tr_TR', 'tr_TR.UTF-8', 'tr_TR.ISO8859-9'):
+ try:
+ locale.setlocale(locale.LC_CTYPE, loc)
+ break
+ except locale.Error:
+ continue
+ else:
# Unsupported locale on this system
self.skipTest('test needs Turkish locale')
loc = locale.getlocale()
- locale.setlocale(locale.LC_CTYPE, loc)
+ try:
+ locale.setlocale(locale.LC_CTYPE, loc)
+ except Exception as e:
+ self.fail("Failed to set locale %r (default locale is %r): %r" %
+ (loc, oldlocale, e))
self.assertEqual(loc, locale.getlocale())
def test_normalize_issue12752(self):
diff -r 3a1db0d2747e Lib/test/test_logging.py
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
diff -r 3a1db0d2747e Lib/test/test_long.py
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -90,7 +90,7 @@
# The sign of the number is also random.
def getran(self, ndigits):
- self.assertTrue(ndigits > 0)
+ self.assertGreater(ndigits, 0)
nbits_hi = ndigits * SHIFT
nbits_lo = nbits_hi - SHIFT + 1
answer = 0L
@@ -588,7 +588,7 @@
pass
x = long2(1L<<100)
y = int(x)
- self.assertTrue(type(y) is long,
+ self.assertIs(type(y), long,
"overflowing int conversion must return long not long subtype")
# long -> Py_ssize_t conversion
diff -r 3a1db0d2747e Lib/test/test_macos.py
--- a/Lib/test/test_macos.py
+++ b/Lib/test/test_macos.py
@@ -8,11 +8,9 @@
TESTFN2 = test_support.TESTFN + '2'
class TestMacOS(unittest.TestCase):
-
+ @unittest.skipUnless(os.path.exists('/Developer/Tools/SetFile'),
+ '/Developer/Tools/SetFile does not exist')
def testGetCreatorAndType(self):
- if not os.path.exists('/Developer/Tools/SetFile'):
- return
-
try:
fp = open(test_support.TESTFN, 'w')
fp.write('\n')
@@ -29,10 +27,9 @@
finally:
os.unlink(test_support.TESTFN)
+ @unittest.skipUnless(os.path.exists('/Developer/Tools/GetFileInfo'),
+ '/Developer/Tools/GetFileInfo does not exist')
def testSetCreatorAndType(self):
- if not os.path.exists('/Developer/Tools/GetFileInfo'):
- return
-
try:
fp = open(test_support.TESTFN, 'w')
fp.write('\n')
diff -r 3a1db0d2747e Lib/test/test_macostools.py
--- a/Lib/test/test_macostools.py
+++ b/Lib/test/test_macostools.py
@@ -12,6 +12,8 @@
TESTFN2 = test_support.TESTFN + '2'
+requires_32bit = unittest.skipUnless(sys.maxint < 2**32, '32-bit only test')
+
class TestMacostools(unittest.TestCase):
def setUp(self):
@@ -51,30 +53,32 @@
DeprecationWarning), quiet=True):
macostools.touched(test_support.TESTFN)
- if sys.maxint < 2**32:
- def test_copy(self):
- test_support.unlink(TESTFN2)
- macostools.copy(test_support.TESTFN, TESTFN2)
- self.assertEqual(self.compareData(), '')
+ @requires_32bit
+ def test_copy(self):
+ test_support.unlink(TESTFN2)
+ macostools.copy(test_support.TESTFN, TESTFN2)
+ self.assertEqual(self.compareData(), '')
- if sys.maxint < 2**32:
- def test_mkalias(self):
- test_support.unlink(TESTFN2)
- macostools.mkalias(test_support.TESTFN, TESTFN2)
- fss, _, _ = Carbon.File.ResolveAliasFile(TESTFN2, 0)
- self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN))
+ @requires_32bit
+ def test_mkalias(self):
+ test_support.unlink(TESTFN2)
+ macostools.mkalias(test_support.TESTFN, TESTFN2)
+ fss, _, _ = Carbon.File.ResolveAliasFile(TESTFN2, 0)
+ self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN))
- def test_mkalias_relative(self):
- test_support.unlink(TESTFN2)
- # If the directory doesn't exist, then chances are this is a new
- # install of Python so don't create it since the user might end up
- # running ``sudo make install`` and creating the directory here won't
- # leave it with the proper permissions.
- if not os.path.exists(sys.prefix):
- return
- macostools.mkalias(test_support.TESTFN, TESTFN2, sys.prefix)
- fss, _, _ = Carbon.File.ResolveAliasFile(TESTFN2, 0)
- self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN))
+ @requires_32bit
+ # If the directory doesn't exist, then chances are this is a new
+ # install of Python so don't create it since the user might end up
+ # running ``sudo make install`` and creating the directory here won't
+ # leave it with the proper permissions.
+ @unittest.skipUnless(os.path.exists(sys.prefix),
+ "%r doesn't exist" % sys.prefix)
+ def test_mkalias_relative(self):
+ test_support.unlink(TESTFN2)
+
+ macostools.mkalias(test_support.TESTFN, TESTFN2, sys.prefix)
+ fss, _, _ = Carbon.File.ResolveAliasFile(TESTFN2, 0)
+ self.assertEqual(fss.as_pathname(), os.path.realpath(test_support.TESTFN))
def test_main():
diff -r 3a1db0d2747e Lib/test/test_mailbox.py
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -138,7 +138,7 @@
msg = self._box.get(key0)
self.assertEqual(msg['from'], 'foo')
self.assertEqual(msg.get_payload(), '0\n')
- self.assertIs(self._box.get('foo'), None)
+ self.assertIsNone(self._box.get('foo'))
self.assertFalse(self._box.get('foo', False))
self._box.close()
self._box = self._factory(self._path, factory=rfc822.Message)
@@ -249,8 +249,7 @@
count = 0
for value in returned_values:
self.assertEqual(value['from'], 'foo')
- self.assertTrue(int(value.get_payload()) < repetitions,
- (value.get_payload(), repetitions))
+ self.assertLess(int(value.get_payload()), repetitions)
count += 1
self.assertEqual(len(values), count)
@@ -664,7 +663,7 @@
"tmp")),
"File in wrong location: '%s'" % head)
match = pattern.match(tail)
- self.assertTrue(match is not None, "Invalid file name: '%s'" % tail)
+ self.assertIsNotNone(match, "Invalid file name: '%s'" % tail)
groups = match.groups()
if previous_groups is not None:
self.assertGreaterEqual(int(groups[0]), int(previous_groups[0]),
@@ -674,22 +673,22 @@
self.assertGreaterEqual(int(groups[1]), int(previous_groups[1]),
"Non-monotonic milliseconds: '%s' before '%s'" %
(previous_groups[1], groups[1]))
- self.assertTrue(int(groups[2]) == pid,
+ self.assertEqual(int(groups[2]), pid,
"Process ID mismatch: '%s' should be '%s'" %
(groups[2], pid))
- self.assertTrue(int(groups[3]) == int(previous_groups[3]) + 1,
+ self.assertEqual(int(groups[3]), int(previous_groups[3]) + 1,
"Non-sequential counter: '%s' before '%s'" %
(previous_groups[3], groups[3]))
- self.assertTrue(groups[4] == hostname,
+ self.assertEqual(groups[4], hostname,
"Host name mismatch: '%s' should be '%s'" %
(groups[4], hostname))
previous_groups = groups
tmp_file.write(_sample_message)
tmp_file.seek(0)
- self.assertTrue(tmp_file.read() == _sample_message)
+ self.assertEqual(tmp_file.read(), _sample_message)
tmp_file.close()
file_count = len(os.listdir(os.path.join(self._path, "tmp")))
- self.assertTrue(file_count == repetitions,
+ self.assertEqual(file_count, repetitions,
"Wrong file count: '%s' should be '%s'" %
(file_count, repetitions))
@@ -772,10 +771,10 @@
for msg in self._box:
pass
+ @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+ @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
def test_file_permissions(self):
# Verify that message files are created without execute permissions
- if not hasattr(os, "stat") or not hasattr(os, "umask"):
- return
msg = mailbox.MaildirMessage(self._template % 0)
orig_umask = os.umask(0)
try:
@@ -786,12 +785,11 @@
mode = os.stat(path).st_mode
self.assertEqual(mode & 0111, 0)
+ @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+ @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
def test_folder_file_perms(self):
# From bug #3228, we want to verify that the file created inside a Maildir
# subfolder isn't marked as executable.
- if not hasattr(os, "stat") or not hasattr(os, "umask"):
- return
-
orig_umask = os.umask(0)
try:
subfolder = self._box.add_folder('subfolder')
@@ -991,24 +989,25 @@
_factory = lambda self, path, factory=None: mailbox.mbox(path, factory)
+ @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+ @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
def test_file_perms(self):
# From bug #3228, we want to verify that the mailbox file isn't executable,
# even if the umask is set to something that would leave executable bits set.
# We only run this test on platforms that support umask.
- if hasattr(os, 'umask') and hasattr(os, 'stat'):
- try:
- old_umask = os.umask(0077)
- self._box.close()
- os.unlink(self._path)
- self._box = mailbox.mbox(self._path, create=True)
- self._box.add('')
- self._box.close()
- finally:
- os.umask(old_umask)
+ try:
+ old_umask = os.umask(0077)
+ self._box.close()
+ os.unlink(self._path)
+ self._box = mailbox.mbox(self._path, create=True)
+ self._box.add('')
+ self._box.close()
+ finally:
+ os.umask(old_umask)
- st = os.stat(self._path)
- perms = st.st_mode
- self.assertFalse((perms & 0111)) # Execute bits should all be off.
+ st = os.stat(self._path)
+ perms = st.st_mode
+ self.assertFalse((perms & 0111)) # Execute bits should all be off.
def test_terminating_newline(self):
message = email.message.Message()
@@ -1240,7 +1239,7 @@
self.assertIsInstance(msg, self._factory)
self.assertEqual(msg.keys(), [])
self.assertFalse(msg.is_multipart())
- self.assertEqual(msg.get_payload(), None)
+ self.assertIsNone(msg.get_payload())
def test_initialize_incorrectly(self):
# Initialize with invalid argument
@@ -1313,7 +1312,7 @@
# Use get_date() and set_date()
msg = mailbox.MaildirMessage(_sample_message)
diff = msg.get_date() - time.time()
- self.assertTrue(abs(diff) < 60, diff)
+ self.assertLess(abs(diff), 60, diff)
msg.set_date(0.0)
self.assertEqual(msg.get_date(), 0.0)
@@ -1388,8 +1387,9 @@
# Check contents of "From " line
if sender is None:
sender = "MAILER-DAEMON"
- self.assertTrue(re.match(sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:"
- r"\d{2} \d{4}", msg.get_from()))
+ self.assertIsNotNone(re.match(
+ sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:\d{2} \d{4}",
+ msg.get_from()))
class TestMboxMessage(_TestMboxMMDFMessage, TestMessage):
@@ -1463,7 +1463,7 @@
msg = mailbox.BabylMessage(_sample_message)
visible = msg.get_visible()
self.assertEqual(visible.keys(), [])
- self.assertIs(visible.get_payload(), None)
+ self.assertIsNone(visible.get_payload())
visible['User-Agent'] = 'FooBar 1.0'
visible['X-Whatever'] = 'Blah'
self.assertEqual(msg.get_visible().keys(), [])
@@ -1472,10 +1472,10 @@
self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever'])
self.assertEqual(visible['User-Agent'], 'FooBar 1.0')
self.assertEqual(visible['X-Whatever'], 'Blah')
- self.assertIs(visible.get_payload(), None)
+ self.assertIsNone(visible.get_payload())
msg.update_visible()
self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever'])
- self.assertIs(visible.get_payload(), None)
+ self.assertIsNone(visible.get_payload())
visible = msg.get_visible()
self.assertEqual(visible.keys(), ['User-Agent', 'Date', 'From', 'To',
'Subject'])
@@ -1971,43 +1971,43 @@
# Make sure the boxes attribute actually gets set.
self.mbox = mailbox.Maildir(test_support.TESTFN)
#self.assertTrue(hasattr(self.mbox, "boxes"))
- #self.assertTrue(len(self.mbox.boxes) == 0)
- self.assertIs(self.mbox.next(), None)
- self.assertIs(self.mbox.next(), None)
+ #self.assertEqual(len(self.mbox.boxes), 0)
+ self.assertIsNone(self.mbox.next())
+ self.assertIsNone(self.mbox.next())
def test_nonempty_maildir_cur(self):
self.createMessage("cur")
self.mbox = mailbox.Maildir(test_support.TESTFN)
- #self.assertTrue(len(self.mbox.boxes) == 1)
+ #self.assertEqual(len(self.mbox.boxes), 1)
msg = self.mbox.next()
- self.assertIsNot(msg, None)
+ self.assertIsNotNone(msg)
msg.fp.close()
- self.assertIs(self.mbox.next(), None)
- self.assertIs(self.mbox.next(), None)
+ self.assertIsNone(self.mbox.next())
+ self.assertIsNone(self.mbox.next())
def test_nonempty_maildir_new(self):
self.createMessage("new")
self.mbox = mailbox.Maildir(test_support.TESTFN)
- #self.assertTrue(len(self.mbox.boxes) == 1)
+ #self.assertEqual(len(self.mbox.boxes), 1)
msg = self.mbox.next()
- self.assertIsNot(msg, None)
+ self.assertIsNotNone(msg)
msg.fp.close()
- self.assertIs(self.mbox.next(), None)
- self.assertIs(self.mbox.next(), None)
+ self.assertIsNone(self.mbox.next())
+ self.assertIsNone(self.mbox.next())
def test_nonempty_maildir_both(self):
self.createMessage("cur")
self.createMessage("new")
self.mbox = mailbox.Maildir(test_support.TESTFN)
- #self.assertTrue(len(self.mbox.boxes) == 2)
+ #self.assertEqual(len(self.mbox.boxes), 2)
msg = self.mbox.next()
- self.assertIsNot(msg, None)
+ self.assertIsNotNone(msg)
msg.fp.close()
msg = self.mbox.next()
- self.assertIsNot(msg, None)
+ self.assertIsNotNone(msg)
msg.fp.close()
- self.assertIs(self.mbox.next(), None)
- self.assertIs(self.mbox.next(), None)
+ self.assertIsNone(self.mbox.next())
+ self.assertIsNone(self.mbox.next())
def test_unix_mbox(self):
### should be better!
diff -r 3a1db0d2747e Lib/test/test_marshal.py
--- a/Lib/test/test_marshal.py
+++ b/Lib/test/test_marshal.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from test import test_support
@@ -286,7 +285,7 @@
self.check_unmarshallable('x' * size)
@test_support.precisionbigmemtest(size=LARGE_SIZE,
- memuse=character_size, dry_run=False)
+ memuse=character_size + 2, dry_run=False)
def test_unicode(self, size):
self.check_unmarshallable(u'x' * size)
diff -r 3a1db0d2747e Lib/test/test_math.py
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -906,38 +906,37 @@
# still fails this part of the test on some platforms. For now, we only
# *run* test_exceptions() in verbose mode, so that this isn't normally
# tested.
+ @unittest.skipUnless(verbose, 'requires verbose mode')
+ def test_exceptions(self):
+ try:
+ x = math.exp(-1000000000)
+ except:
+ # mathmodule.c is failing to weed out underflows from libm, or
+ # we've got an fp format with huge dynamic range
+ self.fail("underflowing exp() should not have raised "
+ "an exception")
+ if x != 0:
+ self.fail("underflowing exp() should have returned 0")
- if verbose:
- def test_exceptions(self):
- try:
- x = math.exp(-1000000000)
- except:
- # mathmodule.c is failing to weed out underflows from libm, or
- # we've got an fp format with huge dynamic range
- self.fail("underflowing exp() should not have raised "
- "an exception")
- if x != 0:
- self.fail("underflowing exp() should have returned 0")
+ # If this fails, probably using a strict IEEE-754 conforming libm, and x
+ # is +Inf afterwards. But Python wants overflows detected by default.
+ try:
+ x = math.exp(1000000000)
+ except OverflowError:
+ pass
+ else:
+ self.fail("overflowing exp() didn't trigger OverflowError")
- # If this fails, probably using a strict IEEE-754 conforming libm, and x
- # is +Inf afterwards. But Python wants overflows detected by default.
- try:
- x = math.exp(1000000000)
- except OverflowError:
- pass
- else:
- self.fail("overflowing exp() didn't trigger OverflowError")
-
- # If this fails, it could be a puzzle. One odd possibility is that
- # mathmodule.c's macros are getting confused while comparing
- # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
- # as a result (and so raising OverflowError instead).
- try:
- x = math.sqrt(-1.0)
- except ValueError:
- pass
- else:
- self.fail("sqrt(-1) didn't raise ValueError")
+ # If this fails, it could be a puzzle. One odd possibility is that
+ # mathmodule.c's macros are getting confused while comparing
+ # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
+ # as a result (and so raising OverflowError instead).
+ try:
+ x = math.sqrt(-1.0)
+ except ValueError:
+ pass
+ else:
+ self.fail("sqrt(-1) didn't raise ValueError")
@requires_IEEE_754
def test_testfile(self):
diff -r 3a1db0d2747e Lib/test/test_memoryio.py
--- a/Lib/test/test_memoryio.py
+++ b/Lib/test/test_memoryio.py
@@ -522,6 +522,17 @@
self.assertIsNone(memio.errors)
self.assertFalse(memio.line_buffering)
+ def test_newline_default(self):
+ memio = self.ioclass("a\nb\r\nc\rd")
+ self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
+ self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
+
+ memio = self.ioclass()
+ self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
+ memio.seek(0)
+ self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
+ self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
+
def test_newline_none(self):
# newline=None
memio = self.ioclass("a\nb\r\nc\rd", newline=None)
@@ -531,12 +542,16 @@
self.assertEqual(memio.read(2), "\nb")
self.assertEqual(memio.read(2), "\nc")
self.assertEqual(memio.read(1), "\n")
+ self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
+
memio = self.ioclass(newline=None)
self.assertEqual(2, memio.write("a\n"))
self.assertEqual(3, memio.write("b\r\n"))
self.assertEqual(3, memio.write("c\rd"))
memio.seek(0)
self.assertEqual(memio.read(), "a\nb\nc\nd")
+ self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
+
memio = self.ioclass("a\r\nb", newline=None)
self.assertEqual(memio.read(3), "a\nb")
@@ -548,6 +563,8 @@
self.assertEqual(memio.read(4), "a\nb\r")
self.assertEqual(memio.read(2), "\nc")
self.assertEqual(memio.read(1), "\r")
+ self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
+
memio = self.ioclass(newline="")
self.assertEqual(2, memio.write("a\n"))
self.assertEqual(2, memio.write("b\r"))
@@ -555,11 +572,19 @@
self.assertEqual(2, memio.write("\rd"))
memio.seek(0)
self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
+ self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
def test_newline_lf(self):
# newline="\n"
- memio = self.ioclass("a\nb\r\nc\rd")
+ memio = self.ioclass("a\nb\r\nc\rd", newline="\n")
self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
+ self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
+
+ memio = self.ioclass(newline="\n")
+ self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
+ memio.seek(0)
+ self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
+ self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
def test_newline_cr(self):
# newline="\r"
@@ -567,6 +592,15 @@
self.assertEqual(memio.read(), "a\rb\r\rc\rd")
memio.seek(0)
self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
+ self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
+
+ memio = self.ioclass(newline="\r")
+ self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
+ memio.seek(0)
+ self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
+ memio.seek(0)
+ self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"])
+ self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
def test_newline_crlf(self):
# newline="\r\n"
@@ -574,11 +608,21 @@
self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
memio.seek(0)
self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
+ memio.seek(0)
+ self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"])
+ self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
+
+ memio = self.ioclass(newline="\r\n")
+ self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
+ memio.seek(0)
+ self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
+ self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
def test_issue5265(self):
# StringIO can duplicate newlines in universal newlines mode
memio = self.ioclass("a\r\nb\r\n", newline=None)
self.assertEqual(memio.read(5), "a\nb\n")
+ self.assertEqual(memio.getvalue(), "a\nb\n")
class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin,
@@ -588,6 +632,16 @@
UnsupportedOperation = pyio.UnsupportedOperation
EOF = ""
+ def test_lone_surrogates(self):
+ # Issue #20424
+ surrogate = unichr(0xd800)
+ memio = self.ioclass(surrogate)
+ self.assertEqual(memio.read(), surrogate)
+
+ memio = self.ioclass()
+ memio.write(surrogate)
+ self.assertEqual(memio.getvalue(), surrogate)
+
class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase):
"""Test if pickle restores properly the internal state of StringIO.
diff -r 3a1db0d2747e Lib/test/test_memoryview.py
--- a/Lib/test/test_memoryview.py
+++ b/Lib/test/test_memoryview.py
@@ -63,7 +63,7 @@
def test_setitem_readonly(self):
if not self.ro_type:
- return
+ self.skipTest("no read-only type to test")
b = self.ro_type(self._source)
oldrefcount = sys.getrefcount(b)
m = self._view(b)
@@ -77,7 +77,7 @@
def test_setitem_writable(self):
if not self.rw_type:
- return
+ self.skipTest("no writable type to test")
tp = self.rw_type
b = self.rw_type(self._source)
oldrefcount = sys.getrefcount(b)
@@ -183,13 +183,13 @@
def test_attributes_readonly(self):
if not self.ro_type:
- return
+ self.skipTest("no read-only type to test")
m = self.check_attributes_with_type(self.ro_type)
self.assertEqual(m.readonly, True)
def test_attributes_writable(self):
if not self.rw_type:
- return
+ self.skipTest("no writable type to test")
m = self.check_attributes_with_type(self.rw_type)
self.assertEqual(m.readonly, False)
@@ -236,7 +236,7 @@
# buffer as writable causing a segfault if using mmap
tp = self.ro_type
if tp is None:
- return
+ self.skipTest("no read-only type to test")
b = tp(self._source)
m = self._view(b)
i = io.BytesIO(b'ZZZZ')
diff -r 3a1db0d2747e Lib/test/test_minidom.py
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -340,19 +340,6 @@
and el.getAttribute("spam2") == "bam2")
dom.unlink()
- def testGetAttrList(self):
- pass
-
- def testGetAttrValues(self): pass
-
- def testGetAttrLength(self): pass
-
- def testGetAttribute(self): pass
-
- def testGetAttributeNS(self): pass
-
- def testGetAttributeNode(self): pass
-
def testGetElementsByTagNameNS(self):
d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
<minidom:myelem/>
@@ -423,8 +410,6 @@
self.confirm(str(node) == repr(node))
dom.unlink()
- def testTextNodeRepr(self): pass
-
def testWriteXML(self):
str = '<?xml version="1.0" ?><a b="c"/>'
dom = parseString(str)
@@ -488,14 +473,6 @@
and pi.localName is None
and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
- def testProcessingInstructionRepr(self): pass
-
- def testTextRepr(self): pass
-
- def testWriteText(self): pass
-
- def testDocumentElement(self): pass
-
def testTooManyDocumentElements(self):
doc = parseString("<doc/>")
elem = doc.createElement("extra")
@@ -504,26 +481,6 @@
elem.unlink()
doc.unlink()
- def testCreateElementNS(self): pass
-
- def testCreateAttributeNS(self): pass
-
- def testParse(self): pass
-
- def testParseString(self): pass
-
- def testComment(self): pass
-
- def testAttrListItem(self): pass
-
- def testAttrListItems(self): pass
-
- def testAttrListItemNS(self): pass
-
- def testAttrListKeys(self): pass
-
- def testAttrListKeysNS(self): pass
-
def testRemoveNamedItem(self):
doc = parseString("<doc a=''/>")
e = doc.documentElement
@@ -543,32 +500,6 @@
self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItemNS,
"http://xml.python.org/", "b")
- def testAttrListValues(self): pass
-
- def testAttrListLength(self): pass
-
- def testAttrList__getitem__(self): pass
-
- def testAttrList__setitem__(self): pass
-
- def testSetAttrValueandNodeValue(self): pass
-
- def testParseElement(self): pass
-
- def testParseAttributes(self): pass
-
- def testParseElementNamespaces(self): pass
-
- def testParseAttributeNamespaces(self): pass
-
- def testParseProcessingInstructions(self): pass
-
- def testChildNodes(self): pass
-
- def testFirstChild(self): pass
-
- def testHasChildNodes(self): pass
-
def _testCloneElementCopiesAttributes(self, e1, e2, test):
attrs1 = e1.attributes
attrs2 = e2.attributes
diff -r 3a1db0d2747e Lib/test/test_mmap.py
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -320,26 +320,25 @@
mf.close()
f.close()
+ @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()")
def test_entire_file(self):
# test mapping of entire file by passing 0 for map length
- if hasattr(os, "stat"):
- f = open(TESTFN, "w+")
+ f = open(TESTFN, "w+")
- f.write(2**16 * 'm') # Arbitrary character
- f.close()
+ f.write(2**16 * 'm') # Arbitrary character
+ f.close()
- f = open(TESTFN, "rb+")
- mf = mmap.mmap(f.fileno(), 0)
- self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
- self.assertEqual(mf.read(2**16), 2**16 * "m")
- mf.close()
- f.close()
+ f = open(TESTFN, "rb+")
+ mf = mmap.mmap(f.fileno(), 0)
+ self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
+ self.assertEqual(mf.read(2**16), 2**16 * "m")
+ mf.close()
+ f.close()
+ @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()")
def test_length_0_offset(self):
# Issue #10916: test mapping of remainder of file by passing 0 for
# map length with an offset doesn't cause a segfault.
- if not hasattr(os, "stat"):
- self.skipTest("needs os.stat")
# NOTE: allocation granularity is currently 65536 under Win64,
# and therefore the minimum offset alignment.
with open(TESTFN, "wb") as f:
@@ -352,12 +351,10 @@
finally:
mf.close()
+ @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()")
def test_length_0_large_offset(self):
# Issue #10959: test mapping of a file by passing 0 for
# map length with a large offset doesn't cause a segfault.
- if not hasattr(os, "stat"):
- self.skipTest("needs os.stat")
-
with open(TESTFN, "wb") as f:
f.write(115699 * b'm') # Arbitrary character
@@ -538,9 +535,8 @@
return mmap.mmap.__new__(klass, -1, *args, **kwargs)
anon_mmap(PAGESIZE)
+ @unittest.skipUnless(hasattr(mmap, 'PROT_READ'), "needs mmap.PROT_READ")
def test_prot_readonly(self):
- if not hasattr(mmap, 'PROT_READ'):
- return
mapsize = 10
open(TESTFN, "wb").write("a"*mapsize)
f = open(TESTFN, "rb")
@@ -584,66 +580,68 @@
m.seek(8)
self.assertRaises(ValueError, m.write, "bar")
- if os.name == 'nt':
- def test_tagname(self):
- data1 = "0123456789"
- data2 = "abcdefghij"
- assert len(data1) == len(data2)
+ @unittest.skipUnless(os.name == 'nt', 'requires Windows')
+ def test_tagname(self):
+ data1 = "0123456789"
+ data2 = "abcdefghij"
+ assert len(data1) == len(data2)
- # Test same tag
- m1 = mmap.mmap(-1, len(data1), tagname="foo")
- m1[:] = data1
- m2 = mmap.mmap(-1, len(data2), tagname="foo")
- m2[:] = data2
- self.assertEqual(m1[:], data2)
- self.assertEqual(m2[:], data2)
- m2.close()
- m1.close()
+ # Test same tag
+ m1 = mmap.mmap(-1, len(data1), tagname="foo")
+ m1[:] = data1
+ m2 = mmap.mmap(-1, len(data2), tagname="foo")
+ m2[:] = data2
+ self.assertEqual(m1[:], data2)
+ self.assertEqual(m2[:], data2)
+ m2.close()
+ m1.close()
- # Test different tag
- m1 = mmap.mmap(-1, len(data1), tagname="foo")
- m1[:] = data1
- m2 = mmap.mmap(-1, len(data2), tagname="boo")
- m2[:] = data2
- self.assertEqual(m1[:], data1)
- self.assertEqual(m2[:], data2)
- m2.close()
- m1.close()
+ # Test different tag
+ m1 = mmap.mmap(-1, len(data1), tagname="foo")
+ m1[:] = data1
+ m2 = mmap.mmap(-1, len(data2), tagname="boo")
+ m2[:] = data2
+ self.assertEqual(m1[:], data1)
+ self.assertEqual(m2[:], data2)
+ m2.close()
+ m1.close()
- def test_crasher_on_windows(self):
- # Should not crash (Issue 1733986)
- m = mmap.mmap(-1, 1000, tagname="foo")
- try:
- mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
- except:
- pass
- m.close()
+ @unittest.skipUnless(os.name == 'nt', 'requires Windows')
+ def test_crasher_on_windows(self):
+ # Should not crash (Issue 1733986)
+ m = mmap.mmap(-1, 1000, tagname="foo")
+ try:
+ mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
+ except:
+ pass
+ m.close()
- # Should not crash (Issue 5385)
- open(TESTFN, "wb").write("x"*10)
- f = open(TESTFN, "r+b")
- m = mmap.mmap(f.fileno(), 0)
- f.close()
- try:
- m.resize(0) # will raise WindowsError
- except:
- pass
- try:
- m[:]
- except:
- pass
- m.close()
+ # Should not crash (Issue 5385)
+ open(TESTFN, "wb").write("x"*10)
+ f = open(TESTFN, "r+b")
+ m = mmap.mmap(f.fileno(), 0)
+ f.close()
+ try:
+ m.resize(0) # will raise WindowsError
+ except:
+ pass
+ try:
+ m[:]
+ except:
+ pass
+ m.close()
- def test_invalid_descriptor(self):
- # socket file descriptors are valid, but out of range
- # for _get_osfhandle, causing a crash when validating the
- # parameters to _get_osfhandle.
- s = socket.socket()
- try:
- with self.assertRaises(mmap.error):
- m = mmap.mmap(s.fileno(), 10)
- finally:
- s.close()
+ @unittest.skipUnless(os.name == 'nt', 'requires Windows')
+ def test_invalid_descriptor(self):
+ # socket file descriptors are valid, but out of range
+ # for _get_osfhandle, causing a crash when validating the
+ # parameters to _get_osfhandle.
+ s = socket.socket()
+ try:
+ with self.assertRaises(mmap.error):
+ m = mmap.mmap(s.fileno(), 10)
+ finally:
+ s.close()
class LargeMmapTests(unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/test_multibytecodec.py
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# test_multibytecodec.py
# Unit test for multibytecodec itself
#
@@ -157,57 +155,55 @@
os.unlink(TESTFN)
class Test_StreamWriter(unittest.TestCase):
- if len(u'\U00012345') == 2: # UCS2
- def test_gb18030(self):
- s = StringIO.StringIO()
- c = codecs.getwriter('gb18030')(s)
- c.write(u'123')
- self.assertEqual(s.getvalue(), '123')
- c.write(u'\U00012345')
- self.assertEqual(s.getvalue(), '123\x907\x959')
+ @unittest.skipUnless(len(u'\U00012345') == 2, 'need a narrow build')
+ def test_gb18030(self):
+ s = StringIO.StringIO()
+ c = codecs.getwriter('gb18030')(s)
+ c.write(u'123')
+ self.assertEqual(s.getvalue(), '123')
+ c.write(u'\U00012345')
+ self.assertEqual(s.getvalue(), '123\x907\x959')
+ c.write(u'\U00012345'[0])
+ self.assertEqual(s.getvalue(), '123\x907\x959')
+ c.write(u'\U00012345'[1] + u'\U00012345' + u'\uac00\u00ac')
+ self.assertEqual(s.getvalue(),
+ '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+ c.write(u'\U00012345'[0])
+ self.assertEqual(s.getvalue(),
+ '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+ self.assertRaises(UnicodeError, c.reset)
+ self.assertEqual(s.getvalue(),
+ '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+
+ @unittest.skipUnless(len(u'\U00012345') == 2, 'need a narrow build')
+ def test_utf_8(self):
+ s= StringIO.StringIO()
+ c = codecs.getwriter('utf-8')(s)
+ c.write(u'123')
+ self.assertEqual(s.getvalue(), '123')
+ c.write(u'\U00012345')
+ self.assertEqual(s.getvalue(), '123\xf0\x92\x8d\x85')
+
+ # Python utf-8 codec can't buffer surrogate pairs yet.
+ if 0:
c.write(u'\U00012345'[0])
- self.assertEqual(s.getvalue(), '123\x907\x959')
+ self.assertEqual(s.getvalue(), '123\xf0\x92\x8d\x85')
c.write(u'\U00012345'[1] + u'\U00012345' + u'\uac00\u00ac')
self.assertEqual(s.getvalue(),
- '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
+ '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+ '\xea\xb0\x80\xc2\xac')
c.write(u'\U00012345'[0])
self.assertEqual(s.getvalue(),
- '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
- self.assertRaises(UnicodeError, c.reset)
+ '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+ '\xea\xb0\x80\xc2\xac')
+ c.reset()
self.assertEqual(s.getvalue(),
- '123\x907\x959\x907\x959\x907\x959\x827\xcf5\x810\x851')
-
- def test_utf_8(self):
- s= StringIO.StringIO()
- c = codecs.getwriter('utf-8')(s)
- c.write(u'123')
- self.assertEqual(s.getvalue(), '123')
- c.write(u'\U00012345')
- self.assertEqual(s.getvalue(), '123\xf0\x92\x8d\x85')
-
- # Python utf-8 codec can't buffer surrogate pairs yet.
- if 0:
- c.write(u'\U00012345'[0])
- self.assertEqual(s.getvalue(), '123\xf0\x92\x8d\x85')
- c.write(u'\U00012345'[1] + u'\U00012345' + u'\uac00\u00ac')
- self.assertEqual(s.getvalue(),
- '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
- '\xea\xb0\x80\xc2\xac')
- c.write(u'\U00012345'[0])
- self.assertEqual(s.getvalue(),
- '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
- '\xea\xb0\x80\xc2\xac')
- c.reset()
- self.assertEqual(s.getvalue(),
- '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
- '\xea\xb0\x80\xc2\xac\xed\xa0\x88')
- c.write(u'\U00012345'[1])
- self.assertEqual(s.getvalue(),
- '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
- '\xea\xb0\x80\xc2\xac\xed\xa0\x88\xed\xbd\x85')
-
- else: # UCS4
- pass
+ '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+ '\xea\xb0\x80\xc2\xac\xed\xa0\x88')
+ c.write(u'\U00012345'[1])
+ self.assertEqual(s.getvalue(),
+ '123\xf0\x92\x8d\x85\xf0\x92\x8d\x85\xf0\x92\x8d\x85'
+ '\xea\xb0\x80\xc2\xac\xed\xa0\x88\xed\xbd\x85')
def test_streamwriter_strwrite(self):
s = StringIO.StringIO()
diff -r 3a1db0d2747e Lib/test/test_multibytecodec_support.py
--- a/Lib/test/test_multibytecodec_support.py
+++ b/Lib/test/test_multibytecodec_support.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# test_multibytecodec_support.py
# Common Unittest Routines for CJK codecs
#
@@ -67,7 +65,7 @@
def test_xmlcharrefreplace(self):
if self.has_iso10646:
- return
+ self.skipTest('encoding contains full ISO 10646 map')
s = u"\u0b13\u0b23\u0b60 nd eggs"
self.assertEqual(
@@ -77,7 +75,7 @@
def test_customreplace_encode(self):
if self.has_iso10646:
- return
+ self.skipTest('encoding contains full ISO 10646 map')
from htmlentitydefs import codepoint2name
diff -r 3a1db0d2747e Lib/test/test_multiprocessing.py
--- a/Lib/test/test_multiprocessing.py
+++ b/Lib/test/test_multiprocessing.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
#
# Unit tests for the multiprocessing package
#
@@ -182,7 +180,7 @@
def test_current(self):
if self.TYPE == 'threads':
- return
+ self.skipTest('test not appropriate for {}'.format(self.TYPE))
current = self.current_process()
authkey = current.authkey
@@ -249,7 +247,7 @@
def test_terminate(self):
if self.TYPE == 'threads':
- return
+ self.skipTest('test not appropriate for {}'.format(self.TYPE))
p = self.Process(target=self._test_terminate)
p.daemon = True
@@ -334,12 +332,12 @@
def test_sys_exit(self):
# See Issue 13854
if self.TYPE == 'threads':
- return
+ self.skipTest('test not appropriate for {}'.format(self.TYPE))
testfn = test_support.TESTFN
self.addCleanup(test_support.unlink, testfn)
- for reason, code in (([1, 2, 3], 1), ('ignore this', 0)):
+ for reason, code in (([1, 2, 3], 1), ('ignore this', 1)):
p = self.Process(target=self._test_sys_exit, args=(reason, testfn))
p.daemon = True
p.start()
@@ -582,7 +580,7 @@
try:
self.assertEqual(q.qsize(), 0)
except NotImplementedError:
- return
+ self.skipTest('qsize method not implemented')
q.put(1)
self.assertEqual(q.qsize(), 1)
q.put(5)
@@ -683,7 +681,7 @@
def test_timeout(self):
if self.TYPE != 'processes':
- return
+ self.skipTest('test not appropriate for {}'.format(self.TYPE))
sem = self.Semaphore(0)
acquire = TimingWrapper(sem.acquire)
@@ -1117,6 +1115,16 @@
self.assertEqual(pmap(sqr, range(100), chunksize=20),
map(sqr, range(100)))
+ def test_map_unplicklable(self):
+ # Issue #19425 -- failure to pickle should not cause a hang
+ if self.TYPE == 'threads':
+ self.skipTest('test not appropriate for {}'.format(self.TYPE))
+ class A(object):
+ def __reduce__(self):
+ raise RuntimeError('cannot pickle')
+ with self.assertRaises(RuntimeError):
+ self.pool.map(sqr, [A()]*10)
+
def test_map_chunksize(self):
try:
self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1)
@@ -1130,7 +1138,7 @@
self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1)
def test_async_timeout(self):
- res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 0.2))
+ res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 1.0))
get = TimingWrapper(res.get)
self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2)
self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2)
@@ -1166,20 +1174,12 @@
p.join()
def test_terminate(self):
- if self.TYPE == 'manager':
- # On Unix a forked process increfs each shared object to
- # which its parent process held a reference. If the
- # forked process gets terminated then there is likely to
- # be a reference leak. So to prevent
- # _TestZZZNumberOfObjects from failing we skip this test
- # when using a manager.
- return
-
- result = self.pool.map_async(
+ p = self.Pool(4)
+ result = p.map_async(
time.sleep, [0.1 for i in range(10000)], chunksize=1
)
- self.pool.terminate()
- join = TimingWrapper(self.pool.join)
+ p.terminate()
+ join = TimingWrapper(p.join)
join()
self.assertTrue(join.elapsed < 0.2)
@@ -1571,7 +1571,7 @@
def test_sendbytes(self):
if self.TYPE != 'processes':
- return
+ self.skipTest('test not appropriate for {}'.format(self.TYPE))
msg = latin('abcdefghijklmnopqrstuvwxyz')
a, b = self.Pipe()
diff -r 3a1db0d2747e Lib/test/test_nis.py
--- a/Lib/test/test_nis.py
+++ b/Lib/test/test_nis.py
@@ -9,11 +9,7 @@
maps = nis.maps()
except nis.error, msg:
# NIS is probably not active, so this test isn't useful
- if test_support.verbose:
- print "Test Skipped:", msg
- # Can't raise SkipTest as regrtest only recognizes the exception
- # import time.
- return
+ self.skipTest(str(msg))
try:
# On some systems, this map is only accessible to the
# super user
diff -r 3a1db0d2747e Lib/test/test_nntplib.py
--- a/Lib/test/test_nntplib.py
+++ b/Lib/test/test_nntplib.py
@@ -1,7 +1,13 @@
import socket
-import threading
import nntplib
import time
+import unittest
+
+try:
+ import threading
+except ImportError:
+ threading = None
+
from unittest import TestCase
from test import test_support
@@ -41,6 +47,7 @@
self.evt.wait()
+@unittest.skipUnless(threading, 'threading required')
class ServerTests(BaseServerTest):
evil = False
@@ -49,6 +56,7 @@
nntp.sock.close()
+@unittest.skipUnless(threading, 'threading required')
class EvilServerTests(BaseServerTest):
evil = True
diff -r 3a1db0d2747e Lib/test/test_ntpath.py
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -1,16 +1,19 @@
import ntpath
import os
+import sys
from test.test_support import TestFailed
from test import test_support, test_genericpath
import unittest
+def tester0(fn, wantResult):
+ gotResult = eval(fn)
+ if wantResult != gotResult:
+ raise TestFailed, "%s should return: %r but returned: %r" \
+ %(fn, wantResult, gotResult)
def tester(fn, wantResult):
fn = fn.replace("\\", "\\\\")
- gotResult = eval(fn)
- if wantResult != gotResult:
- raise TestFailed, "%s should return: %s but returned: %s" \
- %(str(fn), str(wantResult), str(gotResult))
+ tester0(fn, wantResult)
class TestNtpath(unittest.TestCase):
@@ -33,10 +36,24 @@
('c:', '/foo/bar'))
def test_splitunc(self):
+ tester('ntpath.splitunc("c:\\foo\\bar")',
+ ('', 'c:\\foo\\bar'))
+ tester('ntpath.splitunc("c:/foo/bar")',
+ ('', 'c:/foo/bar'))
tester('ntpath.splitunc("\\\\conky\\mountpoint\\foo\\bar")',
('\\\\conky\\mountpoint', '\\foo\\bar'))
tester('ntpath.splitunc("//conky/mountpoint/foo/bar")',
('//conky/mountpoint', '/foo/bar'))
+ tester('ntpath.splitunc("\\\\\\conky\\mountpoint\\foo\\bar")',
+ ('', '\\\\\\conky\\mountpoint\\foo\\bar'))
+ tester('ntpath.splitunc("///conky/mountpoint/foo/bar")',
+ ('', '///conky/mountpoint/foo/bar'))
+ tester('ntpath.splitunc("\\\\conky\\\\mountpoint\\foo\\bar")',
+ ('', '\\\\conky\\\\mountpoint\\foo\\bar'))
+ tester('ntpath.splitunc("//conky//mountpoint/foo/bar")',
+ ('', '//conky//mountpoint/foo/bar'))
+ self.assertEqual(ntpath.splitunc(u'//conky/MOUNTPO\u0130NT/foo/bar'),
+ (u'//conky/MOUNTPO\u0130NT', u'/foo/bar'))
def test_split(self):
tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
@@ -71,10 +88,7 @@
tester('ntpath.join("/a")', '/a')
tester('ntpath.join("\\a")', '\\a')
tester('ntpath.join("a:")', 'a:')
- tester('ntpath.join("a:", "b")', 'a:b')
- tester('ntpath.join("a:", "/b")', 'a:/b')
tester('ntpath.join("a:", "\\b")', 'a:\\b')
- tester('ntpath.join("a", "/b")', '/b')
tester('ntpath.join("a", "\\b")', '\\b')
tester('ntpath.join("a", "b", "c")', 'a\\b\\c')
tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c')
@@ -82,22 +96,46 @@
tester('ntpath.join("a", "b", "\\c")', '\\c')
tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep')
tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b')
- tester("ntpath.join('c:', '/a')", 'c:/a')
- tester("ntpath.join('c:/', '/a')", 'c:/a')
- tester("ntpath.join('c:/a', '/b')", '/b')
- tester("ntpath.join('c:', 'd:/')", 'd:/')
- tester("ntpath.join('c:/', 'd:/')", 'd:/')
- tester("ntpath.join('c:/', 'd:/a/b')", 'd:/a/b')
- tester("ntpath.join('')", '')
- tester("ntpath.join('', '', '', '', '')", '')
- tester("ntpath.join('a')", 'a')
tester("ntpath.join('', 'a')", 'a')
tester("ntpath.join('', '', '', '', 'a')", 'a')
tester("ntpath.join('a', '')", 'a\\')
tester("ntpath.join('a', '', '', '', '')", 'a\\')
tester("ntpath.join('a\\', '')", 'a\\')
tester("ntpath.join('a\\', '', '', '', '')", 'a\\')
+ tester("ntpath.join('a/', '')", 'a/')
+
+ tester("ntpath.join('a/b', 'x/y')", 'a/b\\x/y')
+ tester("ntpath.join('/a/b', 'x/y')", '/a/b\\x/y')
+ tester("ntpath.join('/a/b/', 'x/y')", '/a/b/x/y')
+ tester("ntpath.join('c:', 'x/y')", 'c:x/y')
+ tester("ntpath.join('c:a/b', 'x/y')", 'c:a/b\\x/y')
+ tester("ntpath.join('c:a/b/', 'x/y')", 'c:a/b/x/y')
+ tester("ntpath.join('c:/', 'x/y')", 'c:/x/y')
+ tester("ntpath.join('c:/a/b', 'x/y')", 'c:/a/b\\x/y')
+ tester("ntpath.join('c:/a/b/', 'x/y')", 'c:/a/b/x/y')
+ #tester("ntpath.join('//computer/share', 'x/y')", '//computer/share\\x/y')
+ #tester("ntpath.join('//computer/share/', 'x/y')", '//computer/share/x/y')
+ #tester("ntpath.join('//computer/share/a/b', 'x/y')", '//computer/share/a/b\\x/y')
+
+ tester("ntpath.join('a/b', '/x/y')", '/x/y')
+ tester("ntpath.join('/a/b', '/x/y')", '/x/y')
+ tester("ntpath.join('c:', '/x/y')", 'c:/x/y')
+ tester("ntpath.join('c:a/b', '/x/y')", 'c:/x/y')
+ tester("ntpath.join('c:/', '/x/y')", 'c:/x/y')
+ tester("ntpath.join('c:/a/b', '/x/y')", 'c:/x/y')
+ #tester("ntpath.join('//computer/share', '/x/y')", '//computer/share/x/y')
+ #tester("ntpath.join('//computer/share/', '/x/y')", '//computer/share/x/y')
+ #tester("ntpath.join('//computer/share/a', '/x/y')", '//computer/share/x/y')
+
+ tester("ntpath.join('c:', 'C:x/y')", 'C:x/y')
+ tester("ntpath.join('c:a/b', 'C:x/y')", 'C:a/b\\x/y')
+ tester("ntpath.join('c:/', 'C:x/y')", 'C:/x/y')
+ tester("ntpath.join('c:/a/b', 'C:x/y')", 'C:/a/b\\x/y')
+
+ for x in ('', 'a/b', '/a/b', 'c:', 'c:a/b', 'c:/', 'c:/a/b'):
+ for y in ('d:', 'd:x/y', 'd:/', 'd:/x/y'):
+ tester("ntpath.join(%r, %r)" % (x, y), y)
def test_normpath(self):
tester("ntpath.normpath('A//////././//.//B')", r'A\B')
@@ -138,7 +176,6 @@
tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar")
tester('ntpath.expandvars("$bar bar")', "$bar bar")
tester('ntpath.expandvars("$?bar")', "$?bar")
- tester('ntpath.expandvars("${foo}bar")', "barbar")
tester('ntpath.expandvars("$foo}bar")', "bar}bar")
tester('ntpath.expandvars("${foo")', "${foo")
tester('ntpath.expandvars("${{foo}}")', "baz1}")
@@ -152,6 +189,30 @@
tester('ntpath.expandvars("%foo%%bar")', "bar%bar")
tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar")
+ @unittest.skipUnless(test_support.FS_NONASCII, 'need test_support.FS_NONASCII')
+ def test_expandvars_nonascii(self):
+ encoding = sys.getfilesystemencoding()
+ def check(value, expected):
+ tester0("ntpath.expandvars(%r)" % value, expected)
+ tester0("ntpath.expandvars(%r)" % value.decode(encoding),
+ expected.decode(encoding))
+ with test_support.EnvironmentVarGuard() as env:
+ env.clear()
+ unonascii = test_support.FS_NONASCII
+ snonascii = unonascii.encode(encoding)
+ env['spam'] = snonascii
+ env[snonascii] = 'ham' + snonascii
+ check('$spam bar', '%s bar' % snonascii)
+ check('$%s bar' % snonascii, '$%s bar' % snonascii)
+ check('${spam}bar', '%sbar' % snonascii)
+ check('${%s}bar' % snonascii, 'ham%sbar' % snonascii)
+ check('$spam}bar', '%s}bar' % snonascii)
+ check('$%s}bar' % snonascii, '$%s}bar' % snonascii)
+ check('%spam% bar', '%s bar' % snonascii)
+ check('%{}% bar'.format(snonascii), 'ham%s bar' % snonascii)
+ check('%spam%bar', '%sbar' % snonascii)
+ check('%{}%bar'.format(snonascii), 'ham%sbar' % snonascii)
+
def test_abspath(self):
# ntpath.abspath() can only be used on a system with the "nt" module
# (reasonably), so we protect this test with "import nt". This allows
diff -r 3a1db0d2747e Lib/test/test_optparse.py
--- a/Lib/test/test_optparse.py
+++ b/Lib/test/test_optparse.py
@@ -1444,6 +1444,39 @@
-h, --help show this help message and exit
"""
+_expected_very_help_short_lines = """\
+Usage: bar.py [options]
+
+Options:
+ -a APPLE
+ throw
+ APPLEs at
+ basket
+ -b NUM, --boo=NUM
+ shout
+ "boo!" NUM
+ times (in
+ order to
+ frighten
+ away all
+ the evil
+ spirits
+ that cause
+ trouble and
+ mayhem)
+ --foo=FOO
+ store FOO
+ in the foo
+ list for
+ later
+ fooing
+ -h, --help
+ show this
+ help
+ message and
+ exit
+"""
+
class TestHelp(BaseTest):
def setUp(self):
self.parser = self.make_parser(80)
@@ -1505,6 +1538,8 @@
# we look at $COLUMNS.
self.parser = self.make_parser(60)
self.assertHelpEquals(_expected_help_short_lines)
+ self.parser = self.make_parser(0)
+ self.assertHelpEquals(_expected_very_help_short_lines)
def test_help_unicode(self):
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
diff -r 3a1db0d2747e Lib/test/test_os.py
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -83,9 +83,8 @@
open(name, "w")
self.files.append(name)
+ @unittest.skipUnless(hasattr(os, 'tempnam'), 'test needs os.tempnam()')
def test_tempnam(self):
- if not hasattr(os, "tempnam"):
- return
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "tempnam", RuntimeWarning,
r"test_os$")
@@ -99,9 +98,8 @@
self.assertTrue(os.path.basename(name)[:3] == "pfx")
self.check_tempfile(name)
+ @unittest.skipUnless(hasattr(os, 'tmpfile'), 'test needs os.tmpfile()')
def test_tmpfile(self):
- if not hasattr(os, "tmpfile"):
- return
# As with test_tmpnam() below, the Windows implementation of tmpfile()
# attempts to create a file in the root directory of the current drive.
# On Vista and Server 2008, this test will always fail for normal users
@@ -150,9 +148,8 @@
fp.close()
self.assertTrue(s == "foobar")
+ @unittest.skipUnless(hasattr(os, 'tmpnam'), 'test needs os.tmpnam()')
def test_tmpnam(self):
- if not hasattr(os, "tmpnam"):
- return
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning,
r"test_os$")
@@ -193,10 +190,8 @@
os.unlink(self.fname)
os.rmdir(test_support.TESTFN)
+ @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
def test_stat_attributes(self):
- if not hasattr(os, "stat"):
- return
-
import stat
result = os.stat(self.fname)
@@ -256,16 +251,14 @@
pass
+ @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()')
def test_statvfs_attributes(self):
- if not hasattr(os, "statvfs"):
- return
-
try:
result = os.statvfs(self.fname)
except OSError, e:
# On AtheOS, glibc always returns ENOSYS
if e.errno == errno.ENOSYS:
- return
+ self.skipTest('glibc always returns ENOSYS on AtheOS')
# Make sure direct access works
self.assertEqual(result.f_bfree, result[3])
@@ -311,10 +304,10 @@
st2 = os.stat(test_support.TESTFN)
self.assertEqual(st2.st_mtime, int(st.st_mtime-delta))
- # Restrict test to Win32, since there is no guarantee other
+ # Restrict tests to Win32, since there is no guarantee other
# systems support centiseconds
- if sys.platform == 'win32':
- def get_file_system(path):
+ def get_file_system(path):
+ if sys.platform == 'win32':
root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
import ctypes
kernel32 = ctypes.windll.kernel32
@@ -322,25 +315,31 @@
if kernel32.GetVolumeInformationA(root, None, 0, None, None, None, buf, len(buf)):
return buf.value
- if get_file_system(test_support.TESTFN) == "NTFS":
- def test_1565150(self):
- t1 = 1159195039.25
- os.utime(self.fname, (t1, t1))
- self.assertEqual(os.stat(self.fname).st_mtime, t1)
+ @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+ @unittest.skipUnless(get_file_system(test_support.TESTFN) == "NTFS",
+ "requires NTFS")
+ def test_1565150(self):
+ t1 = 1159195039.25
+ os.utime(self.fname, (t1, t1))
+ self.assertEqual(os.stat(self.fname).st_mtime, t1)
- def test_large_time(self):
- t1 = 5000000000 # some day in 2128
- os.utime(self.fname, (t1, t1))
- self.assertEqual(os.stat(self.fname).st_mtime, t1)
+ @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+ @unittest.skipUnless(get_file_system(test_support.TESTFN) == "NTFS",
+ "requires NTFS")
+ def test_large_time(self):
+ t1 = 5000000000 # some day in 2128
+ os.utime(self.fname, (t1, t1))
+ self.assertEqual(os.stat(self.fname).st_mtime, t1)
- def test_1686475(self):
- # Verify that an open file can be stat'ed
- try:
- os.stat(r"c:\pagefile.sys")
- except WindowsError, e:
- if e.errno == 2: # file does not exist; cannot run test
- return
- self.fail("Could not stat pagefile.sys")
+ @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+ def test_1686475(self):
+ # Verify that an open file can be stat'ed
+ try:
+ os.stat(r"c:\pagefile.sys")
+ except WindowsError, e:
+ if e.errno == 2: # file does not exist; cannot run test
+ self.skipTest(r'c:\pagefile.sys does not exist')
+ self.fail("Could not stat pagefile.sys")
from test import mapping_tests
@@ -598,6 +597,7 @@
self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
+@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32ErrorTests(unittest.TestCase):
def test_rename(self):
self.assertRaises(WindowsError, os.rename, test_support.TESTFN, test_support.TESTFN+".bak")
@@ -644,121 +644,118 @@
self.fail("%r didn't raise a OSError with a bad file descriptor"
% f)
+ @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()')
def test_isatty(self):
- if hasattr(os, "isatty"):
- self.assertEqual(os.isatty(test_support.make_bad_fd()), False)
+ self.assertEqual(os.isatty(test_support.make_bad_fd()), False)
+ @unittest.skipUnless(hasattr(os, 'closerange'), 'test needs os.closerange()')
def test_closerange(self):
- if hasattr(os, "closerange"):
- fd = test_support.make_bad_fd()
- # Make sure none of the descriptors we are about to close are
- # currently valid (issue 6542).
- for i in range(10):
- try: os.fstat(fd+i)
- except OSError:
- pass
- else:
- break
- if i < 2:
- raise unittest.SkipTest(
- "Unable to acquire a range of invalid file descriptors")
- self.assertEqual(os.closerange(fd, fd + i-1), None)
+ fd = test_support.make_bad_fd()
+ # Make sure none of the descriptors we are about to close are
+ # currently valid (issue 6542).
+ for i in range(10):
+ try: os.fstat(fd+i)
+ except OSError:
+ pass
+ else:
+ break
+ if i < 2:
+ raise unittest.SkipTest(
+ "Unable to acquire a range of invalid file descriptors")
+ self.assertEqual(os.closerange(fd, fd + i-1), None)
+ @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()')
def test_dup2(self):
- if hasattr(os, "dup2"):
- self.check(os.dup2, 20)
+ self.check(os.dup2, 20)
+ @unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()')
def test_fchmod(self):
- if hasattr(os, "fchmod"):
- self.check(os.fchmod, 0)
+ self.check(os.fchmod, 0)
+ @unittest.skipUnless(hasattr(os, 'fchown'), 'test needs os.fchown()')
def test_fchown(self):
- if hasattr(os, "fchown"):
- self.check(os.fchown, -1, -1)
+ self.check(os.fchown, -1, -1)
+ @unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()')
def test_fpathconf(self):
- if hasattr(os, "fpathconf"):
- self.check(os.fpathconf, "PC_NAME_MAX")
+ self.check(os.fpathconf, "PC_NAME_MAX")
+ @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
def test_ftruncate(self):
- if hasattr(os, "ftruncate"):
- self.check(os.ftruncate, 0)
+ self.check(os.ftruncate, 0)
+ @unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
def test_lseek(self):
- if hasattr(os, "lseek"):
- self.check(os.lseek, 0, 0)
+ self.check(os.lseek, 0, 0)
+ @unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()')
def test_read(self):
- if hasattr(os, "read"):
- self.check(os.read, 1)
+ self.check(os.read, 1)
+ @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
def test_tcsetpgrpt(self):
- if hasattr(os, "tcsetpgrp"):
- self.check(os.tcsetpgrp, 0)
+ self.check(os.tcsetpgrp, 0)
+ @unittest.skipUnless(hasattr(os, 'write'), 'test needs os.write()')
def test_write(self):
- if hasattr(os, "write"):
- self.check(os.write, " ")
+ self.check(os.write, " ")
-if sys.platform != 'win32':
- class Win32ErrorTests(unittest.TestCase):
- pass
+@unittest.skipIf(sys.platform == "win32", "Posix specific tests")
+class PosixUidGidTests(unittest.TestCase):
+ @unittest.skipUnless(hasattr(os, 'setuid'), 'test needs os.setuid()')
+ def test_setuid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setuid, 0)
+ self.assertRaises(OverflowError, os.setuid, 1<<32)
- class PosixUidGidTests(unittest.TestCase):
- if hasattr(os, 'setuid'):
- def test_setuid(self):
- if os.getuid() != 0:
- self.assertRaises(os.error, os.setuid, 0)
- self.assertRaises(OverflowError, os.setuid, 1<<32)
+ @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()')
+ def test_setgid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setgid, 0)
+ self.assertRaises(OverflowError, os.setgid, 1<<32)
- if hasattr(os, 'setgid'):
- def test_setgid(self):
- if os.getuid() != 0:
- self.assertRaises(os.error, os.setgid, 0)
- self.assertRaises(OverflowError, os.setgid, 1<<32)
+ @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()')
+ def test_seteuid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.seteuid, 0)
+ self.assertRaises(OverflowError, os.seteuid, 1<<32)
- if hasattr(os, 'seteuid'):
- def test_seteuid(self):
- if os.getuid() != 0:
- self.assertRaises(os.error, os.seteuid, 0)
- self.assertRaises(OverflowError, os.seteuid, 1<<32)
+ @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()')
+ def test_setegid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setegid, 0)
+ self.assertRaises(OverflowError, os.setegid, 1<<32)
- if hasattr(os, 'setegid'):
- def test_setegid(self):
- if os.getuid() != 0:
- self.assertRaises(os.error, os.setegid, 0)
- self.assertRaises(OverflowError, os.setegid, 1<<32)
+ @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
+ def test_setreuid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setreuid, 0, 0)
+ self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
+ self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
- if hasattr(os, 'setreuid'):
- def test_setreuid(self):
- if os.getuid() != 0:
- self.assertRaises(os.error, os.setreuid, 0, 0)
- self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
- self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
+ @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
+ def test_setreuid_neg1(self):
+ # Needs to accept -1. We run this in a subprocess to avoid
+ # altering the test runner's process state (issue8045).
+ subprocess.check_call([
+ sys.executable, '-c',
+ 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
- def test_setreuid_neg1(self):
- # Needs to accept -1. We run this in a subprocess to avoid
- # altering the test runner's process state (issue8045).
- subprocess.check_call([
- sys.executable, '-c',
- 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
+ @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
+ def test_setregid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setregid, 0, 0)
+ self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
+ self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
- if hasattr(os, 'setregid'):
- def test_setregid(self):
- if os.getuid() != 0:
- self.assertRaises(os.error, os.setregid, 0, 0)
- self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
- self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
+ @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
+ def test_setregid_neg1(self):
+ # Needs to accept -1. We run this in a subprocess to avoid
+ # altering the test runner's process state (issue8045).
+ subprocess.check_call([
+ sys.executable, '-c',
+ 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
- def test_setregid_neg1(self):
- # Needs to accept -1. We run this in a subprocess to avoid
- # altering the test runner's process state (issue8045).
- subprocess.check_call([
- sys.executable, '-c',
- 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
-else:
- class PosixUidGidTests(unittest.TestCase):
- pass
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32KillTests(unittest.TestCase):
diff -r 3a1db0d2747e Lib/test/test_pep263.py
--- a/Lib/test/test_pep263.py
+++ b/Lib/test/test_pep263.py
@@ -58,6 +58,11 @@
with self.assertRaisesRegexp(SyntaxError, 'BOM'):
compile('\xef\xbb\xbf# -*- coding: fake -*-\n', 'dummy', 'exec')
+ def test_non_unicode_codec(self):
+ with self.assertRaisesRegexp(SyntaxError,
+ 'codec did not return a unicode'):
+ from test import bad_coding3
+
def test_main():
test_support.run_unittest(PEP263Test)
diff -r 3a1db0d2747e Lib/test/test_poll.py
--- a/Lib/test/test_poll.py
+++ b/Lib/test/test_poll.py
@@ -3,14 +3,13 @@
import os
import random
import select
-import _testcapi
try:
import threading
except ImportError:
threading = None
import time
import unittest
-from test.test_support import TESTFN, run_unittest, reap_threads
+from test.test_support import TESTFN, run_unittest, reap_threads, cpython_only
try:
select.poll
@@ -159,14 +158,23 @@
if x != 5:
self.fail('Overflow must have occurred')
+ # Issues #15989, #17919
+ self.assertRaises(OverflowError, pollster.register, 0, -1)
+ self.assertRaises(OverflowError, pollster.register, 0, 1 << 64)
+ self.assertRaises(OverflowError, pollster.modify, 1, -1)
+ self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64)
+
+ @cpython_only
+ def test_poll_c_limits(self):
+ from _testcapi import USHRT_MAX, INT_MAX, UINT_MAX
pollster = select.poll()
- # Issue 15989
- self.assertRaises(OverflowError, pollster.register, 0,
- _testcapi.SHRT_MAX + 1)
- self.assertRaises(OverflowError, pollster.register, 0,
- _testcapi.USHRT_MAX + 1)
- self.assertRaises(OverflowError, pollster.poll, _testcapi.INT_MAX + 1)
- self.assertRaises(OverflowError, pollster.poll, _testcapi.UINT_MAX + 1)
+ pollster.register(1)
+
+ # Issues #15989, #17919
+ self.assertRaises(OverflowError, pollster.register, 0, USHRT_MAX + 1)
+ self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1)
+ self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
+ self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)
@unittest.skipUnless(threading, 'Threading required for this test.')
@reap_threads
diff -r 3a1db0d2747e Lib/test/test_popen.py
--- a/Lib/test/test_popen.py
+++ b/Lib/test/test_popen.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Basic tests for os.popen()
Particularly useful for platforms that fake popen.
diff -r 3a1db0d2747e Lib/test/test_popen2.py
--- a/Lib/test/test_popen2.py
+++ b/Lib/test/test_popen2.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for popen2.py"""
import warnings
diff -r 3a1db0d2747e Lib/test/test_poplib.py
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -11,7 +11,7 @@
import time
import errno
-from unittest import TestCase
+from unittest import TestCase, skipUnless
from test import test_support
from test.test_support import HOST
threading = test_support.import_module('threading')
@@ -263,17 +263,20 @@
else:
DummyPOP3Handler.handle_read(self)
- class TestPOP3_SSLClass(TestPOP3Class):
- # repeat previous tests by using poplib.POP3_SSL
+requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported')
- def setUp(self):
- self.server = DummyPOP3Server((HOST, 0))
- self.server.handler = DummyPOP3_SSLHandler
- self.server.start()
- self.client = poplib.POP3_SSL(self.server.host, self.server.port)
+@requires_ssl
+class TestPOP3_SSLClass(TestPOP3Class):
+ # repeat previous tests by using poplib.POP3_SSL
- def test__all__(self):
- self.assertIn('POP3_SSL', poplib.__all__)
+ def setUp(self):
+ self.server = DummyPOP3Server((HOST, 0))
+ self.server.handler = DummyPOP3_SSLHandler
+ self.server.start()
+ self.client = poplib.POP3_SSL(self.server.host, self.server.port)
+
+ def test__all__(self):
+ self.assertIn('POP3_SSL', poplib.__all__)
class TestTimeouts(TestCase):
@@ -305,7 +308,7 @@
serv.close()
def testTimeoutDefault(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
pop = poplib.POP3(HOST, self.port)
@@ -315,13 +318,13 @@
pop.sock.close()
def testTimeoutNone(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
pop = poplib.POP3(HOST, self.port, timeout=None)
finally:
socket.setdefaulttimeout(None)
- self.assertTrue(pop.sock.gettimeout() is None)
+ self.assertIsNone(pop.sock.gettimeout())
pop.sock.close()
def testTimeoutValue(self):
@@ -331,9 +334,8 @@
def test_main():
- tests = [TestPOP3Class, TestTimeouts]
- if SUPPORTS_SSL:
- tests.append(TestPOP3_SSLClass)
+ tests = [TestPOP3Class, TestTimeouts,
+ TestPOP3_SSLClass]
thread_info = test_support.threading_setup()
try:
test_support.run_unittest(*tests)
diff -r 3a1db0d2747e Lib/test/test_posix.py
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -53,47 +53,55 @@
posix_func()
self.assertRaises(TypeError, posix_func, 1)
- if hasattr(posix, 'getresuid'):
- def test_getresuid(self):
- user_ids = posix.getresuid()
- self.assertEqual(len(user_ids), 3)
- for val in user_ids:
- self.assertGreaterEqual(val, 0)
+ @unittest.skipUnless(hasattr(posix, 'getresuid'),
+ 'test needs posix.getresuid()')
+ def test_getresuid(self):
+ user_ids = posix.getresuid()
+ self.assertEqual(len(user_ids), 3)
+ for val in user_ids:
+ self.assertGreaterEqual(val, 0)
- if hasattr(posix, 'getresgid'):
- def test_getresgid(self):
- group_ids = posix.getresgid()
- self.assertEqual(len(group_ids), 3)
- for val in group_ids:
- self.assertGreaterEqual(val, 0)
+ @unittest.skipUnless(hasattr(posix, 'getresgid'),
+ 'test needs posix.getresgid()')
+ def test_getresgid(self):
+ group_ids = posix.getresgid()
+ self.assertEqual(len(group_ids), 3)
+ for val in group_ids:
+ self.assertGreaterEqual(val, 0)
- if hasattr(posix, 'setresuid'):
- def test_setresuid(self):
- current_user_ids = posix.getresuid()
- self.assertIsNone(posix.setresuid(*current_user_ids))
- # -1 means don't change that value.
- self.assertIsNone(posix.setresuid(-1, -1, -1))
+ @unittest.skipUnless(hasattr(posix, 'setresuid'),
+ 'test needs posix.setresuid()')
+ def test_setresuid(self):
+ current_user_ids = posix.getresuid()
+ self.assertIsNone(posix.setresuid(*current_user_ids))
+ # -1 means don't change that value.
+ self.assertIsNone(posix.setresuid(-1, -1, -1))
- def test_setresuid_exception(self):
- # Don't do this test if someone is silly enough to run us as root.
- current_user_ids = posix.getresuid()
- if 0 not in current_user_ids:
- new_user_ids = (current_user_ids[0]+1, -1, -1)
- self.assertRaises(OSError, posix.setresuid, *new_user_ids)
+ @unittest.skipUnless(hasattr(posix, 'setresuid'),
+ 'test needs posix.setresuid()')
+ def test_setresuid_exception(self):
+ # Don't do this test if someone is silly enough to run us as root.
+ current_user_ids = posix.getresuid()
+ if 0 not in current_user_ids:
+ new_user_ids = (current_user_ids[0]+1, -1, -1)
+ self.assertRaises(OSError, posix.setresuid, *new_user_ids)
- if hasattr(posix, 'setresgid'):
- def test_setresgid(self):
- current_group_ids = posix.getresgid()
- self.assertIsNone(posix.setresgid(*current_group_ids))
- # -1 means don't change that value.
- self.assertIsNone(posix.setresgid(-1, -1, -1))
+ @unittest.skipUnless(hasattr(posix, 'setresgid'),
+ 'test needs posix.setresgid()')
+ def test_setresgid(self):
+ current_group_ids = posix.getresgid()
+ self.assertIsNone(posix.setresgid(*current_group_ids))
+ # -1 means don't change that value.
+ self.assertIsNone(posix.setresgid(-1, -1, -1))
- def test_setresgid_exception(self):
- # Don't do this test if someone is silly enough to run us as root.
- current_group_ids = posix.getresgid()
- if 0 not in current_group_ids:
- new_group_ids = (current_group_ids[0]+1, -1, -1)
- self.assertRaises(OSError, posix.setresgid, *new_group_ids)
+ @unittest.skipUnless(hasattr(posix, 'setresgid'),
+ 'test needs posix.setresgid()')
+ def test_setresgid_exception(self):
+ # Don't do this test if someone is silly enough to run us as root.
+ current_group_ids = posix.getresgid()
+ if 0 not in current_group_ids:
+ new_group_ids = (current_group_ids[0]+1, -1, -1)
+ self.assertRaises(OSError, posix.setresgid, *new_group_ids)
@unittest.skipUnless(hasattr(posix, 'initgroups'),
"test needs os.initgroups()")
@@ -120,107 +128,118 @@
else:
self.fail("Expected OSError to be raised by initgroups")
+ @unittest.skipUnless(hasattr(posix, 'statvfs'),
+ 'test needs posix.statvfs()')
def test_statvfs(self):
- if hasattr(posix, 'statvfs'):
- self.assertTrue(posix.statvfs(os.curdir))
+ self.assertTrue(posix.statvfs(os.curdir))
+ @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
+ 'test needs posix.fstatvfs()')
def test_fstatvfs(self):
- if hasattr(posix, 'fstatvfs'):
- fp = open(test_support.TESTFN)
- try:
- self.assertTrue(posix.fstatvfs(fp.fileno()))
- finally:
- fp.close()
+ fp = open(test_support.TESTFN)
+ try:
+ self.assertTrue(posix.fstatvfs(fp.fileno()))
+ finally:
+ fp.close()
+ @unittest.skipUnless(hasattr(posix, 'ftruncate'),
+ 'test needs posix.ftruncate()')
def test_ftruncate(self):
- if hasattr(posix, 'ftruncate'):
- fp = open(test_support.TESTFN, 'w+')
- try:
- # we need to have some data to truncate
- fp.write('test')
- fp.flush()
- posix.ftruncate(fp.fileno(), 0)
- finally:
- fp.close()
+ fp = open(test_support.TESTFN, 'w+')
+ try:
+ # we need to have some data to truncate
+ fp.write('test')
+ fp.flush()
+ posix.ftruncate(fp.fileno(), 0)
+ finally:
+ fp.close()
+ @unittest.skipUnless(hasattr(posix, 'dup'),
+ 'test needs posix.dup()')
def test_dup(self):
- if hasattr(posix, 'dup'):
- fp = open(test_support.TESTFN)
- try:
- fd = posix.dup(fp.fileno())
- self.assertIsInstance(fd, int)
- os.close(fd)
- finally:
- fp.close()
+ fp = open(test_support.TESTFN)
+ try:
+ fd = posix.dup(fp.fileno())
+ self.assertIsInstance(fd, int)
+ os.close(fd)
+ finally:
+ fp.close()
+ @unittest.skipUnless(hasattr(posix, 'confstr'),
+ 'test needs posix.confstr()')
def test_confstr(self):
- if hasattr(posix, 'confstr'):
- self.assertRaises(ValueError, posix.confstr, "CS_garbage")
- self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
+ self.assertRaises(ValueError, posix.confstr, "CS_garbage")
+ self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
+ @unittest.skipUnless(hasattr(posix, 'dup2'),
+ 'test needs posix.dup2()')
def test_dup2(self):
- if hasattr(posix, 'dup2'):
- fp1 = open(test_support.TESTFN)
- fp2 = open(test_support.TESTFN)
- try:
- posix.dup2(fp1.fileno(), fp2.fileno())
- finally:
- fp1.close()
- fp2.close()
+ fp1 = open(test_support.TESTFN)
+ fp2 = open(test_support.TESTFN)
+ try:
+ posix.dup2(fp1.fileno(), fp2.fileno())
+ finally:
+ fp1.close()
+ fp2.close()
def fdopen_helper(self, *args):
fd = os.open(test_support.TESTFN, os.O_RDONLY)
fp2 = posix.fdopen(fd, *args)
fp2.close()
+ @unittest.skipUnless(hasattr(posix, 'fdopen'),
+ 'test needs posix.fdopen()')
def test_fdopen(self):
- if hasattr(posix, 'fdopen'):
- self.fdopen_helper()
- self.fdopen_helper('r')
- self.fdopen_helper('r', 100)
+ self.fdopen_helper()
+ self.fdopen_helper('r')
+ self.fdopen_helper('r', 100)
+ @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
+ 'test needs posix.O_EXLOCK')
def test_osexlock(self):
- if hasattr(posix, "O_EXLOCK"):
+ fd = os.open(test_support.TESTFN,
+ os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
+ self.assertRaises(OSError, os.open, test_support.TESTFN,
+ os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
+ os.close(fd)
+
+ if hasattr(posix, "O_SHLOCK"):
fd = os.open(test_support.TESTFN,
- os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
+ os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
self.assertRaises(OSError, os.open, test_support.TESTFN,
os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
os.close(fd)
- if hasattr(posix, "O_SHLOCK"):
- fd = os.open(test_support.TESTFN,
- os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
- self.assertRaises(OSError, os.open, test_support.TESTFN,
- os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
- os.close(fd)
+ @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
+ 'test needs posix.O_SHLOCK')
+ def test_osshlock(self):
+ fd1 = os.open(test_support.TESTFN,
+ os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+ fd2 = os.open(test_support.TESTFN,
+ os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+ os.close(fd2)
+ os.close(fd1)
- def test_osshlock(self):
- if hasattr(posix, "O_SHLOCK"):
- fd1 = os.open(test_support.TESTFN,
+ if hasattr(posix, "O_EXLOCK"):
+ fd = os.open(test_support.TESTFN,
os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
- fd2 = os.open(test_support.TESTFN,
- os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
- os.close(fd2)
- os.close(fd1)
+ self.assertRaises(OSError, os.open, test_support.TESTFN,
+ os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
+ os.close(fd)
- if hasattr(posix, "O_EXLOCK"):
- fd = os.open(test_support.TESTFN,
- os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
- self.assertRaises(OSError, os.open, test_support.TESTFN,
- os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
- os.close(fd)
+ @unittest.skipUnless(hasattr(posix, 'fstat'),
+ 'test needs posix.fstat()')
+ def test_fstat(self):
+ fp = open(test_support.TESTFN)
+ try:
+ self.assertTrue(posix.fstat(fp.fileno()))
+ finally:
+ fp.close()
- def test_fstat(self):
- if hasattr(posix, 'fstat'):
- fp = open(test_support.TESTFN)
- try:
- self.assertTrue(posix.fstat(fp.fileno()))
- finally:
- fp.close()
-
+ @unittest.skipUnless(hasattr(posix, 'stat'),
+ 'test needs posix.stat()')
def test_stat(self):
- if hasattr(posix, 'stat'):
- self.assertTrue(posix.stat(test_support.TESTFN))
+ self.assertTrue(posix.stat(test_support.TESTFN))
def _test_all_chown_common(self, chown_func, first_param, stat_func):
"""Common code for chown, fchown and lchown tests."""
@@ -313,59 +332,62 @@
self._test_all_chown_common(posix.lchown, test_support.TESTFN,
getattr(posix, 'lstat', None))
+ @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
def test_chdir(self):
- if hasattr(posix, 'chdir'):
- posix.chdir(os.curdir)
- self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
+ posix.chdir(os.curdir)
+ self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
+ @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
def test_lsdir(self):
- if hasattr(posix, 'lsdir'):
- self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
+ self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
+ @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
def test_access(self):
- if hasattr(posix, 'access'):
- self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
+ self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
+ @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
def test_umask(self):
- if hasattr(posix, 'umask'):
- old_mask = posix.umask(0)
- self.assertIsInstance(old_mask, int)
- posix.umask(old_mask)
+ old_mask = posix.umask(0)
+ self.assertIsInstance(old_mask, int)
+ posix.umask(old_mask)
+ @unittest.skipUnless(hasattr(posix, 'strerror'),
+ 'test needs posix.strerror()')
def test_strerror(self):
- if hasattr(posix, 'strerror'):
- self.assertTrue(posix.strerror(0))
+ self.assertTrue(posix.strerror(0))
+ @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
def test_pipe(self):
- if hasattr(posix, 'pipe'):
- reader, writer = posix.pipe()
- os.close(reader)
- os.close(writer)
+ reader, writer = posix.pipe()
+ os.close(reader)
+ os.close(writer)
+ @unittest.skipUnless(hasattr(posix, 'tempnam'),
+ 'test needs posix.tempnam()')
def test_tempnam(self):
- if hasattr(posix, 'tempnam'):
- with warnings.catch_warnings():
- warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
- self.assertTrue(posix.tempnam())
- self.assertTrue(posix.tempnam(os.curdir))
- self.assertTrue(posix.tempnam(os.curdir, 'blah'))
+ with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
+ self.assertTrue(posix.tempnam())
+ self.assertTrue(posix.tempnam(os.curdir))
+ self.assertTrue(posix.tempnam(os.curdir, 'blah'))
+ @unittest.skipUnless(hasattr(posix, 'tmpfile'),
+ 'test needs posix.tmpfile()')
def test_tmpfile(self):
- if hasattr(posix, 'tmpfile'):
- with warnings.catch_warnings():
- warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
- fp = posix.tmpfile()
- fp.close()
+ with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
+ fp = posix.tmpfile()
+ fp.close()
+ @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
def test_utime(self):
- if hasattr(posix, 'utime'):
- now = time.time()
- posix.utime(test_support.TESTFN, None)
- self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
- self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
- self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
- posix.utime(test_support.TESTFN, (int(now), int(now)))
- posix.utime(test_support.TESTFN, (now, now))
+ now = time.time()
+ posix.utime(test_support.TESTFN, None)
+ self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
+ self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
+ self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
+ posix.utime(test_support.TESTFN, (int(now), int(now)))
+ posix.utime(test_support.TESTFN, (now, now))
def _test_chflags_regular_file(self, chflags_func, target_file):
st = os.stat(target_file)
@@ -428,56 +450,54 @@
finally:
posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
+ @unittest.skipUnless(hasattr(posix, 'getcwd'),
+ 'test needs posix.getcwd()')
def test_getcwd_long_pathnames(self):
- if hasattr(posix, 'getcwd'):
- dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
- curdir = os.getcwd()
- base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
+ dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
+ curdir = os.getcwd()
+ base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
- try:
- os.mkdir(base_path)
- os.chdir(base_path)
- except:
-# Just returning nothing instead of the SkipTest exception,
-# because the test results in Error in that case.
-# Is that ok?
-# raise unittest.SkipTest, "cannot create directory for testing"
- return
+ try:
+ os.mkdir(base_path)
+ os.chdir(base_path)
+ except:
+ self.skipTest("cannot create directory for testing")
- try:
- def _create_and_do_getcwd(dirname, current_path_length = 0):
- try:
- os.mkdir(dirname)
- except:
- raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
+ try:
+ def _create_and_do_getcwd(dirname, current_path_length = 0):
+ try:
+ os.mkdir(dirname)
+ except:
+ self.skipTest("mkdir cannot create directory sufficiently "
+ "deep for getcwd test")
- os.chdir(dirname)
- try:
- os.getcwd()
- if current_path_length < 4099:
- _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
- except OSError as e:
- expected_errno = errno.ENAMETOOLONG
- # The following platforms have quirky getcwd()
- # behaviour -- see issue 9185 and 15765 for
- # more information.
- quirky_platform = (
- 'sunos' in sys.platform or
- 'netbsd' in sys.platform or
- 'openbsd' in sys.platform
- )
- if quirky_platform:
- expected_errno = errno.ERANGE
- self.assertEqual(e.errno, expected_errno)
- finally:
- os.chdir('..')
- os.rmdir(dirname)
+ os.chdir(dirname)
+ try:
+ os.getcwd()
+ if current_path_length < 4099:
+ _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
+ except OSError as e:
+ expected_errno = errno.ENAMETOOLONG
+ # The following platforms have quirky getcwd()
+ # behaviour -- see issue 9185 and 15765 for
+ # more information.
+ quirky_platform = (
+ 'sunos' in sys.platform or
+ 'netbsd' in sys.platform or
+ 'openbsd' in sys.platform
+ )
+ if quirky_platform:
+ expected_errno = errno.ERANGE
+ self.assertEqual(e.errno, expected_errno)
+ finally:
+ os.chdir('..')
+ os.rmdir(dirname)
- _create_and_do_getcwd(dirname)
+ _create_and_do_getcwd(dirname)
- finally:
- os.chdir(curdir)
- shutil.rmtree(base_path)
+ finally:
+ os.chdir(curdir)
+ shutil.rmtree(base_path)
@unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
def test_getgroups(self):
@@ -522,17 +542,17 @@
posix.initgroups(name, self.saved_groups[0])
@unittest.skipUnless(hasattr(posix, 'initgroups'),
- "test needs posix.initgroups()")
+ 'test needs posix.initgroups()')
def test_initgroups(self):
# find missing group
- g = max(self.saved_groups) + 1
+ g = max(self.saved_groups or [0]) + 1
name = pwd.getpwuid(posix.getuid()).pw_name
posix.initgroups(name, g)
self.assertIn(g, posix.getgroups())
@unittest.skipUnless(hasattr(posix, 'setgroups'),
- "test needs posix.setgroups()")
+ 'test needs posix.setgroups()')
def test_setgroups(self):
for groups in [[0], range(16)]:
posix.setgroups(groups)
diff -r 3a1db0d2747e Lib/test/test_pwd.py
--- a/Lib/test/test_pwd.py
+++ b/Lib/test/test_pwd.py
@@ -8,8 +8,6 @@
def test_values(self):
entries = pwd.getpwall()
- entriesbyname = {}
- entriesbyuid = {}
for e in entries:
self.assertEqual(len(e), 7)
@@ -32,13 +30,20 @@
# for one uid
# self.assertEqual(pwd.getpwuid(e.pw_uid), e)
# instead of this collect all entries for one uid
- # and check afterwards
+ # and check afterwards (done in test_values_extended)
+
+ def test_values_extended(self):
+ entries = pwd.getpwall()
+ entriesbyname = {}
+ entriesbyuid = {}
+
+ if len(entries) > 1000: # Huge passwd file (NIS?) -- skip this test
+ self.skipTest('passwd file is huge; extended test skipped')
+
+ for e in entries:
entriesbyname.setdefault(e.pw_name, []).append(e)
entriesbyuid.setdefault(e.pw_uid, []).append(e)
- if len(entries) > 1000: # Huge passwd file (NIS?) -- skip the rest
- return
-
# check whether the entry returned by getpwuid()
# for each uid is among those from getpwall() for this uid
for e in entries:
diff -r 3a1db0d2747e Lib/test/test_pydoc.py
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -10,6 +10,7 @@
import pkgutil
import unittest
import xml.etree
+import types
import test.test_support
from collections import namedtuple
from test.script_helper import assert_python_ok
@@ -421,13 +422,103 @@
def test_namedtuple_public_underscore(self):
NT = namedtuple('NT', ['abc', 'def'], rename=True)
with captured_stdout() as help_io:
- help(NT)
+ pydoc.help(NT)
helptext = help_io.getvalue()
self.assertIn('_1', helptext)
self.assertIn('_replace', helptext)
self.assertIn('_asdict', helptext)
+@unittest.skipUnless(test.test_support.have_unicode,
+ "test requires unicode support")
+class TestUnicode(unittest.TestCase):
+
+ def setUp(self):
+ # Better not to use unicode escapes in literals, lest the
+ # parser choke on it if Python has been built without
+ # unicode support.
+ self.Q = types.ModuleType(
+ 'Q', 'Rational numbers: \xe2\x84\x9a'.decode('utf8'))
+ self.Q.__version__ = '\xe2\x84\x9a'.decode('utf8')
+ self.Q.__date__ = '\xe2\x84\x9a'.decode('utf8')
+ self.Q.__author__ = '\xe2\x84\x9a'.decode('utf8')
+ self.Q.__credits__ = '\xe2\x84\x9a'.decode('utf8')
+
+ self.assertIsInstance(self.Q.__doc__, unicode)
+
+ def test_render_doc(self):
+ # render_doc is robust against unicode in docstrings
+ doc = pydoc.render_doc(self.Q)
+ self.assertIsInstance(doc, str)
+
+ def test_encode(self):
+ # _encode is robust against characters out the specified encoding
+ self.assertEqual(pydoc._encode(self.Q.__doc__, 'ascii'), 'Rational numbers: ℚ')
+
+ def test_pipepager(self):
+ # pipepager does not choke on unicode
+ doc = pydoc.render_doc(self.Q)
+
+ saved, os.popen = os.popen, open
+ try:
+ with test.test_support.temp_cwd():
+ pydoc.pipepager(doc, 'pipe')
+ self.assertEqual(open('pipe').read(), pydoc._encode(doc))
+ finally:
+ os.popen = saved
+
+ def test_tempfilepager(self):
+ # tempfilepager does not choke on unicode
+ doc = pydoc.render_doc(self.Q)
+
+ output = {}
+ def mock_system(cmd):
+ filename = cmd.strip()[1:-1]
+ self.assertEqual('"' + filename + '"', cmd.strip())
+ output['content'] = open(filename).read()
+ saved, os.system = os.system, mock_system
+ try:
+ pydoc.tempfilepager(doc, '')
+ self.assertEqual(output['content'], pydoc._encode(doc))
+ finally:
+ os.system = saved
+
+ def test_plainpager(self):
+ # plainpager does not choke on unicode
+ doc = pydoc.render_doc(self.Q)
+
+ # Note: captured_stdout is too permissive when it comes to
+ # unicode, and using it here would make the test always
+ # pass.
+ with test.test_support.temp_cwd():
+ with open('output', 'w') as f:
+ saved, sys.stdout = sys.stdout, f
+ try:
+ pydoc.plainpager(doc)
+ finally:
+ sys.stdout = saved
+ self.assertIn('Rational numbers:', open('output').read())
+
+ def test_ttypager(self):
+ # ttypager does not choke on unicode
+ doc = pydoc.render_doc(self.Q)
+ # Test ttypager
+ with test.test_support.temp_cwd(), test.test_support.captured_stdin():
+ with open('output', 'w') as f:
+ saved, sys.stdout = sys.stdout, f
+ try:
+ pydoc.ttypager(doc)
+ finally:
+ sys.stdout = saved
+ self.assertIn('Rational numbers:', open('output').read())
+
+ def test_htmlpage(self):
+ # html.page does not choke on unicode
+ with test.test_support.temp_cwd():
+ with captured_stdout() as output:
+ pydoc.writedoc(self.Q)
+ self.assertEqual(output.getvalue(), 'wrote Q.html\n')
+
class TestHelper(unittest.TestCase):
def test_keywords(self):
self.assertEqual(sorted(pydoc.Helper.keywords),
@@ -456,6 +547,7 @@
test.test_support.run_unittest(PydocDocTest,
PydocImportTest,
TestDescriptions,
+ TestUnicode,
TestHelper)
finally:
reap_children()
diff -r 3a1db0d2747e Lib/test/test_random.py
--- a/Lib/test/test_random.py
+++ b/Lib/test/test_random.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
import unittest
import random
import time
@@ -251,10 +249,10 @@
def test_bigrand_ranges(self):
for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
- start = self.gen.randrange(2 ** i)
- stop = self.gen.randrange(2 ** (i-2))
+ start = self.gen.randrange(2 ** (i-2))
+ stop = self.gen.randrange(2 ** i)
if stop <= start:
- return
+ continue
self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
def test_rangelimits(self):
@@ -403,10 +401,10 @@
def test_bigrand_ranges(self):
for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
- start = self.gen.randrange(2 ** i)
- stop = self.gen.randrange(2 ** (i-2))
+ start = self.gen.randrange(2 ** (i-2))
+ stop = self.gen.randrange(2 ** i)
if stop <= start:
- return
+ continue
self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
def test_rangelimits(self):
diff -r 3a1db0d2747e Lib/test/test_re.py
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -1,5 +1,6 @@
from test.test_support import verbose, run_unittest, import_module
from test.test_support import precisionbigmemtest, _2G, cpython_only
+from test.test_support import captured_stdout
import re
from re import Scanner
import sre_constants
@@ -700,7 +701,7 @@
try:
unicode
except NameError:
- return # no problem if we have no unicode
+ self.skipTest('no problem if we have no unicode')
class my_unicode(unicode): pass
pat = re.compile(my_unicode("abc"))
self.assertEqual(pat.match("xyz"), None)
@@ -714,7 +715,7 @@
try:
unicode
except NameError:
- return # no problem if we have no unicode
+ self.skipTest('no problem if we have no unicode')
self.assertTrue(re.compile('bug_926075') is not
re.compile(eval("u'bug_926075'")))
@@ -722,7 +723,7 @@
try:
unicode
except NameError:
- pass
+ self.skipTest('no problem if we have no unicode')
pattern = eval('u"[\u002E\u3002\uFF0E\uFF61]"')
self.assertEqual(re.compile(pattern).split("a.b.c"),
['a','b','c'])
@@ -920,6 +921,32 @@
self.assertEqual(m.group(1), "")
self.assertEqual(m.group(2), "y")
+ def test_debug_flag(self):
+ with captured_stdout() as out:
+ re.compile('foo', re.DEBUG)
+ self.assertEqual(out.getvalue().splitlines(),
+ ['literal 102', 'literal 111', 'literal 111'])
+ # Debug output is output again even a second time (bypassing
+ # the cache -- issue #20426).
+ with captured_stdout() as out:
+ re.compile('foo', re.DEBUG)
+ self.assertEqual(out.getvalue().splitlines(),
+ ['literal 102', 'literal 111', 'literal 111'])
+
+ def test_keyword_parameters(self):
+ # Issue #20283: Accepting the string keyword parameter.
+ pat = re.compile(r'(ab)')
+ self.assertEqual(
+ pat.match(string='abracadabra', pos=7, endpos=10).span(), (7, 9))
+ self.assertEqual(
+ pat.search(string='abracadabra', pos=3, endpos=10).span(), (7, 9))
+ self.assertEqual(
+ pat.findall(string='abracadabra', pos=3, endpos=10), ['ab'])
+ self.assertEqual(
+ pat.split(string='abracadabra', maxsplit=1),
+ ['', 'ab', 'racadabra'])
+
+
def run_re_tests():
from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
if verbose:
diff -r 3a1db0d2747e Lib/test/test_repr.py
--- a/Lib/test/test_repr.py
+++ b/Lib/test/test_repr.py
@@ -179,8 +179,15 @@
self.assertTrue(repr(x).startswith('<read-only buffer for 0x'))
def test_cell(self):
- # XXX Hmm? How to get at a cell object?
- pass
+ def get_cell():
+ x = 42
+ def inner():
+ return x
+ return inner
+ x = get_cell().__closure__[0]
+ self.assertRegexpMatches(repr(x), r'<cell at 0x[0-9A-Fa-f]+: '
+ r'int object at 0x[0-9A-Fa-f]+>')
+ self.assertRegexpMatches(r(x), r'<cell at.*\.\.\..*>')
def test_descriptors(self):
eq = self.assertEqual
@@ -261,6 +268,7 @@
eq(repr(foo.foo),
"<class '%s.foo'>" % foo.__name__)
+ @unittest.skip('need a suitable object')
def test_object(self):
# XXX Test the repr of a type with a really long tp_name but with no
# tp_repr. WIBNI we had ::Inline? :)
@@ -302,6 +310,7 @@
'<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \
% (qux.__name__,) ))
+ @unittest.skip('needs a built-in function with a really long name')
def test_builtin_function(self):
# XXX test built-in functions and methods with really long names
pass
diff -r 3a1db0d2747e Lib/test/test_resource.py
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -18,62 +18,60 @@
try:
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
except AttributeError:
- pass
- else:
- # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
- # number on a platform with large file support. On these platforms,
- # we need to test that the get/setrlimit functions properly convert
- # the number to a C long long and that the conversion doesn't raise
- # an error.
- self.assertEqual(resource.RLIM_INFINITY, max)
- resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
+ self.skipTest('RLIMIT_FSIZE not available')
+ # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
+ # number on a platform with large file support. On these platforms,
+ # we need to test that the get/setrlimit functions properly convert
+ # the number to a C long long and that the conversion doesn't raise
+ # an error.
+ self.assertEqual(resource.RLIM_INFINITY, max)
+ resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
def test_fsize_enforced(self):
try:
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
except AttributeError:
- pass
- else:
- # Check to see what happens when the RLIMIT_FSIZE is small. Some
- # versions of Python were terminated by an uncaught SIGXFSZ, but
- # pythonrun.c has been fixed to ignore that exception. If so, the
- # write() should return EFBIG when the limit is exceeded.
+ self.skipTest('RLIMIT_FSIZE not available')
+ # Check to see what happens when the RLIMIT_FSIZE is small. Some
+ # versions of Python were terminated by an uncaught SIGXFSZ, but
+ # pythonrun.c has been fixed to ignore that exception. If so, the
+ # write() should return EFBIG when the limit is exceeded.
- # At least one platform has an unlimited RLIMIT_FSIZE and attempts
- # to change it raise ValueError instead.
+ # At least one platform has an unlimited RLIMIT_FSIZE and attempts
+ # to change it raise ValueError instead.
+ try:
try:
+ resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
+ limit_set = True
+ except ValueError:
+ limit_set = False
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("X" * 1024)
try:
- resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
- limit_set = True
- except ValueError:
- limit_set = False
- f = open(test_support.TESTFN, "wb")
- try:
- f.write("X" * 1024)
- try:
- f.write("Y")
+ f.write("Y")
+ f.flush()
+ # On some systems (e.g., Ubuntu on hppa) the flush()
+ # doesn't always cause the exception, but the close()
+ # does eventually. Try flushing several times in
+ # an attempt to ensure the file is really synced and
+ # the exception raised.
+ for i in range(5):
+ time.sleep(.1)
f.flush()
- # On some systems (e.g., Ubuntu on hppa) the flush()
- # doesn't always cause the exception, but the close()
- # does eventually. Try flushing several times in
- # an attempt to ensure the file is really synced and
- # the exception raised.
- for i in range(5):
- time.sleep(.1)
- f.flush()
- except IOError:
- if not limit_set:
- raise
- if limit_set:
- # Close will attempt to flush the byte we wrote
- # Restore limit first to avoid getting a spurious error
- resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
- finally:
- f.close()
+ except IOError:
+ if not limit_set:
+ raise
+ if limit_set:
+ # Close will attempt to flush the byte we wrote
+ # Restore limit first to avoid getting a spurious error
+ resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
finally:
- if limit_set:
- resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
- test_support.unlink(test_support.TESTFN)
+ f.close()
+ finally:
+ if limit_set:
+ resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
+ test_support.unlink(test_support.TESTFN)
def test_fsize_toobig(self):
# Be sure that setrlimit is checking for really large values
@@ -81,16 +79,15 @@
try:
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
except AttributeError:
+ self.skipTest('RLIMIT_FSIZE not available')
+ try:
+ resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
+ except (OverflowError, ValueError):
pass
- else:
- try:
- resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
- except (OverflowError, ValueError):
- pass
- try:
- resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
- except (OverflowError, ValueError):
- pass
+ try:
+ resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
+ except (OverflowError, ValueError):
+ pass
def test_getrusage(self):
self.assertRaises(TypeError, resource.getrusage)
@@ -108,17 +105,16 @@
try:
limits = resource.getrlimit(resource.RLIMIT_CPU)
except AttributeError:
- pass
- else:
- class BadSequence:
- def __len__(self):
- return 2
- def __getitem__(self, key):
- if key in (0, 1):
- return len(tuple(range(1000000)))
- raise IndexError
+ self.skipTest('RLIMIT_CPU not available')
+ class BadSequence:
+ def __len__(self):
+ return 2
+ def __getitem__(self, key):
+ if key in (0, 1):
+ return len(tuple(range(1000000)))
+ raise IndexError
- resource.setrlimit(resource.RLIMIT_CPU, BadSequence())
+ resource.setrlimit(resource.RLIMIT_CPU, BadSequence())
def test_main(verbose=None):
test_support.run_unittest(ResourceTest)
diff -r 3a1db0d2747e Lib/test/test_set.py
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -561,10 +561,10 @@
s = None
self.assertRaises(ReferenceError, str, p)
- # C API test only available in a debug build
- if hasattr(set, "test_c_api"):
- def test_c_api(self):
- self.assertEqual(set().test_c_api(), True)
+ @unittest.skipUnless(hasattr(set, "test_c_api"),
+ 'C API test only available in a debug build')
+ def test_c_api(self):
+ self.assertEqual(set().test_c_api(), True)
class SetSubclass(set):
pass
diff -r 3a1db0d2747e Lib/test/test_sets.py
--- a/Lib/test/test_sets.py
+++ b/Lib/test/test_sets.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
import unittest, operator, copy, pickle, random
from test import test_support
diff -r 3a1db0d2747e Lib/test/test_shutil.py
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -78,33 +78,34 @@
filename = tempfile.mktemp()
self.assertRaises(OSError, shutil.rmtree, filename)
- # See bug #1071513 for why we don't run this on cygwin
- # and bug #1076467 for why we don't run this as root.
- if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin'
- and not (hasattr(os, 'geteuid') and os.geteuid() == 0)):
- def test_on_error(self):
- self.errorState = 0
- os.mkdir(TESTFN)
- self.childpath = os.path.join(TESTFN, 'a')
- f = open(self.childpath, 'w')
- f.close()
- old_dir_mode = os.stat(TESTFN).st_mode
- old_child_mode = os.stat(self.childpath).st_mode
- # Make unwritable.
- os.chmod(self.childpath, stat.S_IREAD)
- os.chmod(TESTFN, stat.S_IREAD)
+ @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod()')
+ @unittest.skipIf(sys.platform[:6] == 'cygwin',
+ "This test can't be run on Cygwin (issue #1071513).")
+ @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
+ "This test can't be run reliably as root (issue #1076467).")
+ def test_on_error(self):
+ self.errorState = 0
+ os.mkdir(TESTFN)
+ self.childpath = os.path.join(TESTFN, 'a')
+ f = open(self.childpath, 'w')
+ f.close()
+ old_dir_mode = os.stat(TESTFN).st_mode
+ old_child_mode = os.stat(self.childpath).st_mode
+ # Make unwritable.
+ os.chmod(self.childpath, stat.S_IREAD)
+ os.chmod(TESTFN, stat.S_IREAD)
- shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
- # Test whether onerror has actually been called.
- self.assertEqual(self.errorState, 2,
- "Expected call to onerror function did not happen.")
+ shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
+ # Test whether onerror has actually been called.
+ self.assertEqual(self.errorState, 2,
+ "Expected call to onerror function did not happen.")
- # Make writable again.
- os.chmod(TESTFN, old_dir_mode)
- os.chmod(self.childpath, old_child_mode)
+ # Make writable again.
+ os.chmod(TESTFN, old_dir_mode)
+ os.chmod(self.childpath, old_child_mode)
- # Clean up.
- shutil.rmtree(TESTFN)
+ # Clean up.
+ shutil.rmtree(TESTFN)
def check_args_to_onerror(self, func, arg, exc):
# test_rmtree_errors deliberately runs rmtree
@@ -308,37 +309,38 @@
finally:
shutil.rmtree(TESTFN, ignore_errors=True)
- if hasattr(os, "mkfifo"):
- # Issue #3002: copyfile and copytree block indefinitely on named pipes
- def test_copyfile_named_pipe(self):
- os.mkfifo(TESTFN)
+ # Issue #3002: copyfile and copytree block indefinitely on named pipes
+ @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
+ def test_copyfile_named_pipe(self):
+ os.mkfifo(TESTFN)
+ try:
+ self.assertRaises(shutil.SpecialFileError,
+ shutil.copyfile, TESTFN, TESTFN2)
+ self.assertRaises(shutil.SpecialFileError,
+ shutil.copyfile, __file__, TESTFN)
+ finally:
+ os.remove(TESTFN)
+
+ @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
+ def test_copytree_named_pipe(self):
+ os.mkdir(TESTFN)
+ try:
+ subdir = os.path.join(TESTFN, "subdir")
+ os.mkdir(subdir)
+ pipe = os.path.join(subdir, "mypipe")
+ os.mkfifo(pipe)
try:
- self.assertRaises(shutil.SpecialFileError,
- shutil.copyfile, TESTFN, TESTFN2)
- self.assertRaises(shutil.SpecialFileError,
- shutil.copyfile, __file__, TESTFN)
- finally:
- os.remove(TESTFN)
-
- def test_copytree_named_pipe(self):
- os.mkdir(TESTFN)
- try:
- subdir = os.path.join(TESTFN, "subdir")
- os.mkdir(subdir)
- pipe = os.path.join(subdir, "mypipe")
- os.mkfifo(pipe)
- try:
- shutil.copytree(TESTFN, TESTFN2)
- except shutil.Error as e:
- errors = e.args[0]
- self.assertEqual(len(errors), 1)
- src, dst, error_msg = errors[0]
- self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
- else:
- self.fail("shutil.Error should have been raised")
- finally:
- shutil.rmtree(TESTFN, ignore_errors=True)
- shutil.rmtree(TESTFN2, ignore_errors=True)
+ shutil.copytree(TESTFN, TESTFN2)
+ except shutil.Error as e:
+ errors = e.args[0]
+ self.assertEqual(len(errors), 1)
+ src, dst, error_msg = errors[0]
+ self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
+ else:
+ self.fail("shutil.Error should have been raised")
+ finally:
+ shutil.rmtree(TESTFN, ignore_errors=True)
+ shutil.rmtree(TESTFN2, ignore_errors=True)
@unittest.skipUnless(hasattr(os, 'chflags') and
hasattr(errno, 'EOPNOTSUPP') and
@@ -649,16 +651,14 @@
def test_move_file_other_fs(self):
# Move a file to an existing dir on another filesystem.
if not self.dir_other_fs:
- # skip
- return
+ self.skipTest('dir on other filesystem not available')
self._check_move_file(self.src_file, self.file_other_fs,
self.file_other_fs)
def test_move_file_to_dir_other_fs(self):
# Move a file to another location on another filesystem.
if not self.dir_other_fs:
- # skip
- return
+ self.skipTest('dir on other filesystem not available')
self._check_move_file(self.src_file, self.dir_other_fs,
self.file_other_fs)
@@ -676,8 +676,7 @@
def test_move_dir_other_fs(self):
# Move a dir to another location on another filesystem.
if not self.dir_other_fs:
- # skip
- return
+ self.skipTest('dir on other filesystem not available')
dst_dir = tempfile.mktemp(dir=self.dir_other_fs)
try:
self._check_move_dir(self.src_dir, dst_dir, dst_dir)
@@ -695,11 +694,19 @@
def test_move_dir_to_dir_other_fs(self):
# Move a dir inside an existing dir on another filesystem.
if not self.dir_other_fs:
- # skip
- return
+ self.skipTest('dir on other filesystem not available')
self._check_move_dir(self.src_dir, self.dir_other_fs,
os.path.join(self.dir_other_fs, os.path.basename(self.src_dir)))
+ def test_move_dir_sep_to_dir(self):
+ self._check_move_dir(self.src_dir + os.path.sep, self.dst_dir,
+ os.path.join(self.dst_dir, os.path.basename(self.src_dir)))
+
+ @unittest.skipUnless(os.path.altsep, 'requires os.path.altsep')
+ def test_move_dir_altsep_to_dir(self):
+ self._check_move_dir(self.src_dir + os.path.altsep, self.dst_dir,
+ os.path.join(self.dst_dir, os.path.basename(self.src_dir)))
+
def test_existing_file_inside_dest_dir(self):
# A file with the same name inside the destination dir already exists.
with open(self.dst_file, "wb"):
diff -r 3a1db0d2747e Lib/test/test_site.py
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -343,6 +343,7 @@
self.assertNotIn(path, seen_paths)
seen_paths.add(path)
+ @unittest.skip('test not implemented')
def test_add_build_dir(self):
# Test that the build directory's Modules directory is used when it
# should be.
diff -r 3a1db0d2747e Lib/test/test_smtplib.py
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -77,7 +77,7 @@
smtp.close()
def testTimeoutDefault(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
smtp = smtplib.SMTP(HOST, self.port)
@@ -87,13 +87,13 @@
smtp.close()
def testTimeoutNone(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
socket.setdefaulttimeout(30)
try:
smtp = smtplib.SMTP(HOST, self.port, timeout=None)
finally:
socket.setdefaulttimeout(None)
- self.assertTrue(smtp.sock.gettimeout() is None)
+ self.assertIsNone(smtp.sock.gettimeout())
smtp.close()
def testTimeoutValue(self):
diff -r 3a1db0d2747e Lib/test/test_smtpnet.py
--- a/Lib/test/test_smtpnet.py
+++ b/Lib/test/test_smtpnet.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
import unittest
from test import test_support
import smtplib
diff -r 3a1db0d2747e Lib/test/test_socket.py
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1,12 +1,9 @@
-#!/usr/bin/env python
-
import unittest
from test import test_support
import errno
import socket
import select
-import _testcapi
import time
import traceback
import Queue
@@ -331,28 +328,29 @@
ip = socket.gethostbyname(hostname)
except socket.error:
# Probably name lookup wasn't set up right; skip this test
- return
+ self.skipTest('name lookup failure')
self.assertTrue(ip.find('.') >= 0, "Error resolving host to ip.")
try:
hname, aliases, ipaddrs = socket.gethostbyaddr(ip)
except socket.error:
# Probably a similar problem as above; skip this test
- return
+ self.skipTest('address lookup failure')
all_host_names = [hostname, hname] + aliases
fqhn = socket.getfqdn(ip)
if not fqhn in all_host_names:
self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names)))
+ @unittest.skipUnless(hasattr(sys, 'getrefcount'),
+ 'test needs sys.getrefcount()')
def testRefCountGetNameInfo(self):
# Testing reference count for getnameinfo
- if hasattr(sys, "getrefcount"):
- try:
- # On some versions, this loses a reference
- orig = sys.getrefcount(__name__)
- socket.getnameinfo(__name__,0)
- except TypeError:
- self.assertEqual(sys.getrefcount(__name__), orig,
- "socket.getnameinfo loses a reference")
+ try:
+ # On some versions, this loses a reference
+ orig = sys.getrefcount(__name__)
+ socket.getnameinfo(__name__,0)
+ except TypeError:
+ self.assertEqual(sys.getrefcount(__name__), orig,
+ "socket.getnameinfo loses a reference")
def testInterpreterCrash(self):
# Making sure getnameinfo doesn't crash the interpreter
@@ -459,17 +457,17 @@
# Check that setting it to an invalid type raises TypeError
self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
+ @unittest.skipUnless(hasattr(socket, 'inet_aton'),
+ 'test needs socket.inet_aton()')
def testIPv4_inet_aton_fourbytes(self):
- if not hasattr(socket, 'inet_aton'):
- return # No inet_aton, nothing to check
# Test that issue1008086 and issue767150 are fixed.
# It must return 4 bytes.
self.assertEqual('\x00'*4, socket.inet_aton('0.0.0.0'))
self.assertEqual('\xff'*4, socket.inet_aton('255.255.255.255'))
+ @unittest.skipUnless(hasattr(socket, 'inet_pton'),
+ 'test needs socket.inet_pton()')
def testIPv4toString(self):
- if not hasattr(socket, 'inet_pton'):
- return # No inet_pton() on this platform
from socket import inet_aton as f, inet_pton, AF_INET
g = lambda a: inet_pton(AF_INET, a)
@@ -484,15 +482,15 @@
self.assertEqual('\xaa\xaa\xaa\xaa', g('170.170.170.170'))
self.assertEqual('\xff\xff\xff\xff', g('255.255.255.255'))
+ @unittest.skipUnless(hasattr(socket, 'inet_pton'),
+ 'test needs socket.inet_pton()')
def testIPv6toString(self):
- if not hasattr(socket, 'inet_pton'):
- return # No inet_pton() on this platform
try:
from socket import inet_pton, AF_INET6, has_ipv6
if not has_ipv6:
- return
+ self.skipTest('IPv6 not available')
except ImportError:
- return
+ self.skipTest('could not import needed symbols from socket')
f = lambda a: inet_pton(AF_INET6, a)
self.assertEqual('\x00' * 16, f('::'))
@@ -503,9 +501,9 @@
f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae')
)
+ @unittest.skipUnless(hasattr(socket, 'inet_ntop'),
+ 'test needs socket.inet_ntop()')
def testStringToIPv4(self):
- if not hasattr(socket, 'inet_ntop'):
- return # No inet_ntop() on this platform
from socket import inet_ntoa as f, inet_ntop, AF_INET
g = lambda a: inet_ntop(AF_INET, a)
@@ -518,15 +516,15 @@
self.assertEqual('170.85.170.85', g('\xaa\x55\xaa\x55'))
self.assertEqual('255.255.255.255', g('\xff\xff\xff\xff'))
+ @unittest.skipUnless(hasattr(socket, 'inet_ntop'),
+ 'test needs socket.inet_ntop()')
def testStringToIPv6(self):
- if not hasattr(socket, 'inet_ntop'):
- return # No inet_ntop() on this platform
try:
from socket import inet_ntop, AF_INET6, has_ipv6
if not has_ipv6:
- return
+ self.skipTest('IPv6 not available')
except ImportError:
- return
+ self.skipTest('could not import needed symbols from socket')
f = lambda a: inet_ntop(AF_INET6, a)
self.assertEqual('::', f('\x00' * 16))
@@ -566,7 +564,7 @@
my_ip_addr = socket.gethostbyname(socket.gethostname())
except socket.error:
# Probably name lookup wasn't set up right; skip this test
- return
+ self.skipTest('name lookup failure')
self.assertIn(name[0], ("0.0.0.0", my_ip_addr), '%s invalid' % name[0])
self.assertEqual(name[1], port)
@@ -665,9 +663,15 @@
socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0,
socket.AI_PASSIVE)
- # Issue 17269
+ # Issue 17269: test workaround for OS X platform bug segfault
if hasattr(socket, 'AI_NUMERICSERV'):
- socket.getaddrinfo("localhost", None, 0, 0, 0, socket.AI_NUMERICSERV)
+ try:
+ # The arguments here are undefined and the call may succeed
+ # or fail. All we care here is that it doesn't segfault.
+ socket.getaddrinfo("localhost", None, 0, 0, 0,
+ socket.AI_NUMERICSERV)
+ except socket.gaierror:
+ pass
def check_sendall_interrupted(self, with_timeout):
# socketpair() is not stricly required, but it makes things easier.
@@ -712,7 +716,10 @@
srv.listen(backlog)
srv.close()
+ @test_support.cpython_only
+ def test_listen_backlog_overflow(self):
# Issue 15989
+ import _testcapi
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind((HOST, 0))
self.assertRaises(OverflowError, srv.listen, _testcapi.INT_MAX + 1)
@@ -785,10 +792,10 @@
big_chunk = 'f' * 2048
self.serv_conn.sendall(big_chunk)
+ @unittest.skipUnless(hasattr(socket, 'fromfd'),
+ 'socket.fromfd not availble')
def testFromFd(self):
# Testing fromfd()
- if not hasattr(socket, "fromfd"):
- return # On Windows, this doesn't exist
fd = self.cli_conn.fileno()
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
self.addCleanup(sock.close)
@@ -819,6 +826,14 @@
def _testShutdown(self):
self.serv_conn.send(MSG)
+ self.serv_conn.shutdown(2)
+
+ testShutdown_overflow = test_support.cpython_only(testShutdown)
+
+ @test_support.cpython_only
+ def _testShutdown_overflow(self):
+ import _testcapi
+ self.serv_conn.send(MSG)
# Issue 15989
self.assertRaises(OverflowError, self.serv_conn.shutdown,
_testcapi.INT_MAX + 1)
@@ -871,6 +886,8 @@
self.cli.connect((HOST, self.port))
time.sleep(1.0)
+@unittest.skipUnless(hasattr(socket, 'socketpair'),
+ 'test needs socket.socketpair()')
@unittest.skipUnless(thread, 'Threading required for this test.')
class BasicSocketPairTest(SocketPairTest):
@@ -910,14 +927,23 @@
pass
end = time.time()
self.assertTrue((end - start) < 1.0, "Error setting non-blocking mode.")
- # Issue 15989
- if _testcapi.UINT_MAX < _testcapi.ULONG_MAX:
- self.serv.setblocking(_testcapi.UINT_MAX + 1)
- self.assertIsNone(self.serv.gettimeout())
def _testSetBlocking(self):
pass
+ @test_support.cpython_only
+ def testSetBlocking_overflow(self):
+ # Issue 15989
+ import _testcapi
+ if _testcapi.UINT_MAX >= _testcapi.ULONG_MAX:
+ self.skipTest('needs UINT_MAX < ULONG_MAX')
+ self.serv.setblocking(False)
+ self.assertEqual(self.serv.gettimeout(), 0.0)
+ self.serv.setblocking(_testcapi.UINT_MAX + 1)
+ self.assertIsNone(self.serv.gettimeout())
+
+ _testSetBlocking_overflow = test_support.cpython_only(_testSetBlocking)
+
def testAccept(self):
# Testing non-blocking accept
self.serv.setblocking(0)
@@ -1456,12 +1482,12 @@
if not ok:
self.fail("accept() returned success when we did not expect it")
+ @unittest.skipUnless(hasattr(signal, 'alarm'),
+ 'test needs signal.alarm()')
def testInterruptedTimeout(self):
# XXX I don't know how to do this test on MSWindows or any other
# plaform that doesn't support signal.alarm() or os.kill(), though
# the bug should have existed on all platforms.
- if not hasattr(signal, "alarm"):
- return # can only test on *nix
self.serv.settimeout(5.0) # must be longer than alarm
class Alarm(Exception):
pass
@@ -1521,6 +1547,7 @@
self.assertTrue(issubclass(socket.gaierror, socket.error))
self.assertTrue(issubclass(socket.timeout, socket.error))
+@unittest.skipUnless(sys.platform == 'linux', 'Linux specific test')
class TestLinuxAbstractNamespace(unittest.TestCase):
UNIX_PATH_MAX = 108
@@ -1616,6 +1643,23 @@
_testRecvFromIntoMemoryview = _testRecvFromIntoArray
+ def testRecvFromIntoSmallBuffer(self):
+ # See issue #20246.
+ buf = bytearray(8)
+ self.assertRaises(ValueError, self.cli_conn.recvfrom_into, buf, 1024)
+
+ def _testRecvFromIntoSmallBuffer(self):
+ with test_support.check_py3k_warnings():
+ buf = buffer(MSG)
+ self.serv_conn.send(buf)
+
+ def testRecvFromIntoEmptyBuffer(self):
+ buf = bytearray()
+ self.cli_conn.recvfrom_into(buf)
+ self.cli_conn.recvfrom_into(buf, 0)
+
+ _testRecvFromIntoEmptyBuffer = _testRecvFromIntoArray
+
TIPC_STYPE = 2000
TIPC_LOWER = 200
@@ -1635,11 +1679,11 @@
for line in f:
if line.startswith("tipc "):
return True
- if test_support.verbose:
- print "TIPC module is not loaded, please 'sudo modprobe tipc'"
return False
-class TIPCTest (unittest.TestCase):
+@unittest.skipUnless(isTipcAvailable(),
+ "TIPC module is not loaded, please 'sudo modprobe tipc'")
+class TIPCTest(unittest.TestCase):
def testRDM(self):
srv = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
cli = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
@@ -1659,7 +1703,9 @@
self.assertEqual(msg, MSG)
-class TIPCThreadableTest (unittest.TestCase, ThreadableTest):
+@unittest.skipUnless(isTipcAvailable(),
+ "TIPC module is not loaded, please 'sudo modprobe tipc'")
+class TIPCThreadableTest(unittest.TestCase, ThreadableTest):
def __init__(self, methodName = 'runTest'):
unittest.TestCase.__init__(self, methodName = methodName)
ThreadableTest.__init__(self)
@@ -1712,13 +1758,9 @@
NetworkConnectionAttributesTest,
NetworkConnectionBehaviourTest,
])
- if hasattr(socket, "socketpair"):
- tests.append(BasicSocketPairTest)
- if sys.platform == 'linux2':
- tests.append(TestLinuxAbstractNamespace)
- if isTipcAvailable():
- tests.append(TIPCTest)
- tests.append(TIPCThreadableTest)
+ tests.append(BasicSocketPairTest)
+ tests.append(TestLinuxAbstractNamespace)
+ tests.extend([TIPCTest, TIPCThreadableTest])
thread_info = test_support.threading_setup()
test_support.run_unittest(*tests)
diff -r 3a1db0d2747e Lib/test/test_socketserver.py
--- a/Lib/test/test_socketserver.py
+++ b/Lib/test/test_socketserver.py
@@ -27,7 +27,10 @@
HOST = test.test_support.HOST
HAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX")
+requires_unix_sockets = unittest.skipUnless(HAVE_UNIX_SOCKETS,
+ 'requires Unix sockets')
HAVE_FORKING = hasattr(os, "fork") and os.name != "os2"
+requires_forking = unittest.skipUnless(HAVE_FORKING, 'requires forking')
def signal_alarm(n):
"""Call signal.alarm when it exists (i.e. not on Windows)."""
@@ -188,31 +191,33 @@
SocketServer.StreamRequestHandler,
self.stream_examine)
- if HAVE_FORKING:
- def test_ForkingTCPServer(self):
- with simple_subprocess(self):
- self.run_server(SocketServer.ForkingTCPServer,
- SocketServer.StreamRequestHandler,
- self.stream_examine)
-
- if HAVE_UNIX_SOCKETS:
- def test_UnixStreamServer(self):
- self.run_server(SocketServer.UnixStreamServer,
+ @requires_forking
+ def test_ForkingTCPServer(self):
+ with simple_subprocess(self):
+ self.run_server(SocketServer.ForkingTCPServer,
SocketServer.StreamRequestHandler,
self.stream_examine)
- def test_ThreadingUnixStreamServer(self):
- self.run_server(SocketServer.ThreadingUnixStreamServer,
+ @requires_unix_sockets
+ def test_UnixStreamServer(self):
+ self.run_server(SocketServer.UnixStreamServer,
+ SocketServer.StreamRequestHandler,
+ self.stream_examine)
+
+ @requires_unix_sockets
+ def test_ThreadingUnixStreamServer(self):
+ self.run_server(SocketServer.ThreadingUnixStreamServer,
+ SocketServer.StreamRequestHandler,
+ self.stream_examine)
+
+ @requires_unix_sockets
+ @requires_forking
+ def test_ForkingUnixStreamServer(self):
+ with simple_subprocess(self):
+ self.run_server(ForkingUnixStreamServer,
SocketServer.StreamRequestHandler,
self.stream_examine)
- if HAVE_FORKING:
- def test_ForkingUnixStreamServer(self):
- with simple_subprocess(self):
- self.run_server(ForkingUnixStreamServer,
- SocketServer.StreamRequestHandler,
- self.stream_examine)
-
def test_UDPServer(self):
self.run_server(SocketServer.UDPServer,
SocketServer.DatagramRequestHandler,
@@ -223,12 +228,12 @@
SocketServer.DatagramRequestHandler,
self.dgram_examine)
- if HAVE_FORKING:
- def test_ForkingUDPServer(self):
- with simple_subprocess(self):
- self.run_server(SocketServer.ForkingUDPServer,
- SocketServer.DatagramRequestHandler,
- self.dgram_examine)
+ @requires_forking
+ def test_ForkingUDPServer(self):
+ with simple_subprocess(self):
+ self.run_server(SocketServer.ForkingUDPServer,
+ SocketServer.DatagramRequestHandler,
+ self.dgram_examine)
@contextlib.contextmanager
def mocked_select_module(self):
@@ -265,22 +270,24 @@
# Alas, on Linux (at least) recvfrom() doesn't return a meaningful
# client address so this cannot work:
- # if HAVE_UNIX_SOCKETS:
- # def test_UnixDatagramServer(self):
- # self.run_server(SocketServer.UnixDatagramServer,
- # SocketServer.DatagramRequestHandler,
- # self.dgram_examine)
+ # @requires_unix_sockets
+ # def test_UnixDatagramServer(self):
+ # self.run_server(SocketServer.UnixDatagramServer,
+ # SocketServer.DatagramRequestHandler,
+ # self.dgram_examine)
#
- # def test_ThreadingUnixDatagramServer(self):
- # self.run_server(SocketServer.ThreadingUnixDatagramServer,
- # SocketServer.DatagramRequestHandler,
- # self.dgram_examine)
+ # @requires_unix_sockets
+ # def test_ThreadingUnixDatagramServer(self):
+ # self.run_server(SocketServer.ThreadingUnixDatagramServer,
+ # SocketServer.DatagramRequestHandler,
+ # self.dgram_examine)
#
- # if HAVE_FORKING:
- # def test_ForkingUnixDatagramServer(self):
- # self.run_server(SocketServer.ForkingUnixDatagramServer,
- # SocketServer.DatagramRequestHandler,
- # self.dgram_examine)
+ # @requires_unix_sockets
+ # @requires_forking
+ # def test_ForkingUnixDatagramServer(self):
+ # self.run_server(SocketServer.ForkingUnixDatagramServer,
+ # SocketServer.DatagramRequestHandler,
+ # self.dgram_examine)
@reap_threads
def test_shutdown(self):
diff -r 3a1db0d2747e Lib/test/test_ssl.py
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -192,9 +192,8 @@
self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
(s, t))
+ @test_support.requires_resource('network')
def test_ciphers(self):
- if not test_support.is_resource_enabled('network'):
- return
remote = ("svn.python.org", 443)
with test_support.transient_internet(remote[0]):
s = ssl.wrap_socket(socket.socket(socket.AF_INET),
@@ -233,6 +232,13 @@
self.assertRaises(socket.error, ss.send, b'x')
self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
+ def test_unsupported_dtls(self):
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ self.addCleanup(s.close)
+ with self.assertRaises(NotImplementedError) as cx:
+ ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
+ self.assertEqual(str(cx.exception), "only stream sockets are supported")
+
class NetworkedTests(unittest.TestCase):
@@ -384,19 +390,24 @@
def test_get_server_certificate(self):
with test_support.transient_internet("svn.python.org"):
- pem = ssl.get_server_certificate(("svn.python.org", 443))
+ pem = ssl.get_server_certificate(("svn.python.org", 443),
+ ssl.PROTOCOL_SSLv23)
if not pem:
self.fail("No server certificate on svn.python.org:443!")
try:
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
+ pem = ssl.get_server_certificate(("svn.python.org", 443),
+ ssl.PROTOCOL_SSLv23,
+ ca_certs=CERTFILE)
except ssl.SSLError:
#should fail
pass
else:
self.fail("Got server certificate %s for svn.python.org!" % pem)
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ pem = ssl.get_server_certificate(("svn.python.org", 443),
+ ssl.PROTOCOL_SSLv23,
+ ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
if not pem:
self.fail("No server certificate on svn.python.org:443!")
if test_support.verbose:
@@ -1046,7 +1057,7 @@
try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
diff -r 3a1db0d2747e Lib/test/test_str.py
--- a/Lib/test/test_str.py
+++ b/Lib/test/test_str.py
@@ -1,4 +1,4 @@
-
+import unittest
import struct
import sys
from test import test_support, string_tests
@@ -110,12 +110,12 @@
self.assertEqual(str(Foo9("foo")), "string")
self.assertEqual(unicode(Foo9("foo")), u"not unicode")
+ # This test only affects 32-bit platforms because expandtabs can only take
+ # an int as the max value, not a 64-bit C long. If expandtabs is changed
+ # to take a 64-bit long, this test should apply to all platforms.
+ @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4,
+ 'only applies to 32-bit platforms')
def test_expandtabs_overflows_gracefully(self):
- # This test only affects 32-bit platforms because expandtabs can only take
- # an int as the max value, not a 64-bit C long. If expandtabs is changed
- # to take a 64-bit long, this test should apply to all platforms.
- if sys.maxint > (1 << 32) or struct.calcsize('P') != 4:
- return
self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint)
def test__format__(self):
diff -r 3a1db0d2747e Lib/test/test_strptime.py
--- a/Lib/test/test_strptime.py
+++ b/Lib/test/test_strptime.py
@@ -313,7 +313,7 @@
# when time.tzname[0] == time.tzname[1] and time.daylight
tz_name = time.tzname[0]
if tz_name.upper() in ("UTC", "GMT"):
- return
+ self.skipTest('need non-UTC/GMT timezone')
try:
original_tzname = time.tzname
original_daylight = time.daylight
@@ -526,7 +526,7 @@
try:
locale.setlocale(locale.LC_TIME, ('en_US', 'UTF8'))
except locale.Error:
- return
+ self.skipTest('test needs en_US.UTF8 locale')
try:
_strptime._strptime_time('10', '%d')
# Get id of current cache object.
@@ -543,7 +543,7 @@
# If this is the case just suppress the exception and fall-through
# to the resetting to the original locale.
except locale.Error:
- pass
+ self.skipTest('test needs de_DE.UTF8 locale')
# Make sure we don't trample on the locale setting once we leave the
# test.
finally:
diff -r 3a1db0d2747e Lib/test/test_strtod.py
--- a/Lib/test/test_strtod.py
+++ b/Lib/test/test_strtod.py
@@ -249,6 +249,38 @@
else:
assert False, "expected ValueError"
+ @test_support.precisionbigmemtest(size=test_support._2G, memuse=3,
+ dry_run=False)
+ def test_oversized_digit_strings(self, maxsize):
+ # Input string whose length doesn't fit in an INT.
+ s = "1." + "1" * int(2.2e9)
+ with self.assertRaises(ValueError):
+ float(s)
+ del s
+
+ s = "0." + "0" * int(2.2e9) + "1"
+ with self.assertRaises(ValueError):
+ float(s)
+ del s
+
+ def test_large_exponents(self):
+ # Verify that the clipping of the exponent in strtod doesn't affect the
+ # output values.
+ def positive_exp(n):
+ """ Long string with value 1.0 and exponent n"""
+ return '0.{}1e+{}'.format('0'*(n-1), n)
+
+ def negative_exp(n):
+ """ Long string with value 1.0 and exponent -n"""
+ return '1{}e-{}'.format('0'*n, n)
+
+ self.assertEqual(float(positive_exp(10000)), 1.0)
+ self.assertEqual(float(positive_exp(20000)), 1.0)
+ self.assertEqual(float(positive_exp(30000)), 1.0)
+ self.assertEqual(float(negative_exp(10000)), 1.0)
+ self.assertEqual(float(negative_exp(20000)), 1.0)
+ self.assertEqual(float(negative_exp(30000)), 1.0)
+
def test_particular(self):
# inputs that produced crashes or incorrectly rounded results with
# previous versions of dtoa.c, for various reasons
diff -r 3a1db0d2747e Lib/test/test_struct.py
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -574,6 +574,18 @@
self.check_sizeof('0s', 1)
self.check_sizeof('0c', 0)
+ def test_unicode_format(self):
+ try:
+ unicode
+ except NameError:
+ self.skipTest('no unicode support')
+ # Issue #19099
+ s = struct.Struct(unichr(ord('I')))
+ self.assertEqual(s.format, 'I')
+ self.assertIs(type(s.format), str)
+ self.assertRaises(ValueError, struct.Struct, unichr(0x80))
+
+
def test_main():
support.run_unittest(StructTest)
diff -r 3a1db0d2747e Lib/test/test_structmembers.py
--- a/Lib/test/test_structmembers.py
+++ b/Lib/test/test_structmembers.py
@@ -1,3 +1,8 @@
+import unittest
+from test import test_support
+
+# Skip this test if the _testcapi module isn't available.
+test_support.import_module('_testcapi')
from _testcapi import _test_structmembersType, \
CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
SHRT_MAX, SHRT_MIN, USHRT_MAX, \
@@ -5,9 +10,6 @@
LONG_MAX, LONG_MIN, ULONG_MAX, \
LLONG_MAX, LLONG_MIN, ULLONG_MAX
-import unittest
-from test import test_support
-
ts=_test_structmembersType(False, 1, 2, 3, 4, 5, 6, 7, 8,
9.99999, 10.1010101010, "hi")
diff -r 3a1db0d2747e Lib/test/test_sunau.py
--- a/Lib/test/test_sunau.py
+++ b/Lib/test/test_sunau.py
@@ -5,10 +5,12 @@
import sunau
-class SunauPCM8Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
+class SunauTest(audiotests.AudioWriteTests,
+ audiotests.AudioTestsWithSourceFile):
module = sunau
+
+
+class SunauPCM8Test(SunauTest, unittest.TestCase):
sndfilename = 'pluck-pcm8.au'
sndfilenframes = 3307
nchannels = 2
@@ -25,10 +27,7 @@
""")
-class SunauPCM16Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = sunau
+class SunauPCM16Test(SunauTest, unittest.TestCase):
sndfilename = 'pluck-pcm16.au'
sndfilenframes = 3307
nchannels = 2
@@ -47,10 +46,7 @@
""")
-class SunauPCM32Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = sunau
+class SunauPCM32Test(SunauTest, unittest.TestCase):
sndfilename = 'pluck-pcm32.au'
sndfilenframes = 3307
nchannels = 2
@@ -75,10 +71,7 @@
""")
-class SunauULAWTest(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = sunau
+class SunauULAWTest(SunauTest, unittest.TestCase):
sndfilename = 'pluck-ulaw.au'
sndfilenframes = 3307
nchannels = 2
diff -r 3a1db0d2747e Lib/test/test_sundry.py
--- a/Lib/test/test_sundry.py
+++ b/Lib/test/test_sundry.py
@@ -49,7 +49,6 @@
import getpass
import htmlentitydefs
import ihooks
- import imghdr
import imputil
import keyword
import linecache
diff -r 3a1db0d2747e Lib/test/test_support.py
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -19,7 +19,6 @@
import re
import time
import struct
-import _testcapi
import sysconfig
try:
import thread
@@ -271,6 +270,36 @@
# is exited) but there is a .pyo file.
unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
+# On some platforms, should not run gui test even if it is allowed
+# in `use_resources'.
+if sys.platform.startswith('win'):
+ import ctypes
+ import ctypes.wintypes
+ def _is_gui_available():
+ UOI_FLAGS = 1
+ WSF_VISIBLE = 0x0001
+ class USEROBJECTFLAGS(ctypes.Structure):
+ _fields_ = [("fInherit", ctypes.wintypes.BOOL),
+ ("fReserved", ctypes.wintypes.BOOL),
+ ("dwFlags", ctypes.wintypes.DWORD)]
+ dll = ctypes.windll.user32
+ h = dll.GetProcessWindowStation()
+ if not h:
+ raise ctypes.WinError()
+ uof = USEROBJECTFLAGS()
+ needed = ctypes.wintypes.DWORD()
+ res = dll.GetUserObjectInformationW(h,
+ UOI_FLAGS,
+ ctypes.byref(uof),
+ ctypes.sizeof(uof),
+ ctypes.byref(needed))
+ if not res:
+ raise ctypes.WinError()
+ return bool(uof.dwFlags & WSF_VISIBLE)
+else:
+ def _is_gui_available():
+ return True
+
def is_resource_enabled(resource):
"""Test whether a resource is enabled. Known resources are set by
regrtest.py."""
@@ -281,6 +310,8 @@
If the caller's module is __main__ then automatically return True. The
possibility of False being returned occurs when regrtest.py is executing."""
+ if resource == 'gui' and not _is_gui_available():
+ raise unittest.SkipTest("Cannot use the 'gui' resource")
# see if the caller's module is __main__ - if so, treat as if
# the resource was set
if sys._getframe(1).f_globals.get("__name__") == "__main__":
@@ -377,9 +408,15 @@
raise TestFailed("tests should never set the SO_REUSEADDR " \
"socket option on TCP/IP sockets!")
if hasattr(socket, 'SO_REUSEPORT'):
- if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1:
- raise TestFailed("tests should never set the SO_REUSEPORT " \
- "socket option on TCP/IP sockets!")
+ try:
+ if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1:
+ raise TestFailed("tests should never set the SO_REUSEPORT " \
+ "socket option on TCP/IP sockets!")
+ except EnvironmentError:
+ # Python's socket module was compiled using modern headers
+ # thus defining SO_REUSEPORT but this process is running
+ # under an older kernel that does not support SO_REUSEPORT.
+ pass
if hasattr(socket, 'SO_EXCLUSIVEADDRUSE'):
sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1)
@@ -428,6 +465,52 @@
is_jython = sys.platform.startswith('java')
+# FS_NONASCII: non-ASCII Unicode character encodable by
+# sys.getfilesystemencoding(), or None if there is no such character.
+FS_NONASCII = None
+if have_unicode:
+ for character in (
+ # First try printable and common characters to have a readable filename.
+ # For each character, the encoding list are just example of encodings able
+ # to encode the character (the list is not exhaustive).
+
+ # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1
+ unichr(0x00E6),
+ # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3
+ unichr(0x0130),
+ # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257
+ unichr(0x0141),
+ # U+03C6 (Greek Small Letter Phi): cp1253
+ unichr(0x03C6),
+ # U+041A (Cyrillic Capital Letter Ka): cp1251
+ unichr(0x041A),
+ # U+05D0 (Hebrew Letter Alef): Encodable to cp424
+ unichr(0x05D0),
+ # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic
+ unichr(0x060C),
+ # U+062A (Arabic Letter Teh): cp720
+ unichr(0x062A),
+ # U+0E01 (Thai Character Ko Kai): cp874
+ unichr(0x0E01),
+
+ # Then try more "special" characters. "special" because they may be
+ # interpreted or displayed differently depending on the exact locale
+ # encoding and the font.
+
+ # U+00A0 (No-Break Space)
+ unichr(0x00A0),
+ # U+20AC (Euro Sign)
+ unichr(0x20AC),
+ ):
+ try:
+ character.encode(sys.getfilesystemencoding())\
+ .decode(sys.getfilesystemencoding())
+ except UnicodeError:
+ pass
+ else:
+ FS_NONASCII = character
+ break
+
# Filename used for testing
if os.name == 'java':
# Jython disallows @ in module names
@@ -964,6 +1047,7 @@
_TPFLAGS_HEAPTYPE = 1<<9
def check_sizeof(test, o, size):
+ import _testcapi
result = sys.getsizeof(o)
# add GC header size
if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\
@@ -1128,6 +1212,8 @@
return obj
def requires_resource(resource):
+ if resource == 'gui' and not _is_gui_available():
+ return unittest.skip("resource 'gui' is not available")
if is_resource_enabled(resource):
return _id
else:
diff -r 3a1db0d2747e Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1,5 +1,6 @@
# -*- coding: iso-8859-1 -*-
import unittest, test.test_support
+from test.script_helper import assert_python_ok, assert_python_failure
import sys, os, cStringIO
import struct
import operator
@@ -114,90 +115,69 @@
clear_check(exc)
def test_exit(self):
+ # call with two arguments
self.assertRaises(TypeError, sys.exit, 42, 42)
# call without argument
- try:
- sys.exit(0)
- except SystemExit, exc:
- self.assertEqual(exc.code, 0)
- except:
- self.fail("wrong exception")
- else:
- self.fail("no exception")
+ with self.assertRaises(SystemExit) as cm:
+ sys.exit()
+ self.assertIsNone(cm.exception.code)
+
+ rc, out, err = assert_python_ok('-c', 'import sys; sys.exit()')
+ self.assertEqual(rc, 0)
+ self.assertEqual(out, b'')
+ self.assertEqual(err, b'')
+
+ # call with integer argument
+ with self.assertRaises(SystemExit) as cm:
+ sys.exit(42)
+ self.assertEqual(cm.exception.code, 42)
# call with tuple argument with one entry
# entry will be unpacked
- try:
- sys.exit(42)
- except SystemExit, exc:
- self.assertEqual(exc.code, 42)
- except:
- self.fail("wrong exception")
- else:
- self.fail("no exception")
-
- # call with integer argument
- try:
+ with self.assertRaises(SystemExit) as cm:
sys.exit((42,))
- except SystemExit, exc:
- self.assertEqual(exc.code, 42)
- except:
- self.fail("wrong exception")
- else:
- self.fail("no exception")
+ self.assertEqual(cm.exception.code, 42)
# call with string argument
- try:
+ with self.assertRaises(SystemExit) as cm:
sys.exit("exit")
- except SystemExit, exc:
- self.assertEqual(exc.code, "exit")
- except:
- self.fail("wrong exception")
- else:
- self.fail("no exception")
+ self.assertEqual(cm.exception.code, "exit")
# call with tuple argument with two entries
- try:
+ with self.assertRaises(SystemExit) as cm:
sys.exit((17, 23))
- except SystemExit, exc:
- self.assertEqual(exc.code, (17, 23))
- except:
- self.fail("wrong exception")
- else:
- self.fail("no exception")
+ self.assertEqual(cm.exception.code, (17, 23))
# test that the exit machinery handles SystemExits properly
- import subprocess
# both unnormalized...
- rc = subprocess.call([sys.executable, "-c",
- "raise SystemExit, 46"])
+ rc, out, err = assert_python_failure('-c', 'raise SystemExit, 46')
self.assertEqual(rc, 46)
+ self.assertEqual(out, b'')
+ self.assertEqual(err, b'')
# ... and normalized
- rc = subprocess.call([sys.executable, "-c",
- "raise SystemExit(47)"])
+ rc, out, err = assert_python_failure('-c', 'raise SystemExit(47)')
self.assertEqual(rc, 47)
+ self.assertEqual(out, b'')
+ self.assertEqual(err, b'')
- def check_exit_message(code, expected, env=None):
- process = subprocess.Popen([sys.executable, "-c", code],
- stderr=subprocess.PIPE, env=env)
- stdout, stderr = process.communicate()
- self.assertEqual(process.returncode, 1)
- self.assertTrue(stderr.startswith(expected),
- "%s doesn't start with %s" % (repr(stderr), repr(expected)))
+ def check_exit_message(code, expected, **env_vars):
+ rc, out, err = assert_python_failure('-c', code, **env_vars)
+ self.assertEqual(rc, 1)
+ self.assertEqual(out, b'')
+ self.assertTrue(err.startswith(expected),
+ "%s doesn't start with %s" % (repr(err), repr(expected)))
- # test that stderr buffer if flushed before the exit message is written
+ # test that stderr buffer is flushed before the exit message is written
# into stderr
check_exit_message(
r'import sys; sys.stderr.write("unflushed,"); sys.exit("message")',
b"unflushed,message")
# test that the unicode message is encoded to the stderr encoding
- env = os.environ.copy()
- env['PYTHONIOENCODING'] = 'latin-1'
check_exit_message(
r'import sys; sys.exit(u"h\xe9")',
- b"h\xe9", env=env)
+ b"h\xe9", PYTHONIOENCODING='latin-1')
def test_getdefaultencoding(self):
if test.test_support.have_unicode:
@@ -266,15 +246,16 @@
# still has 5 elements
maj, min, buildno, plat, csd = sys.getwindowsversion()
+ @unittest.skipUnless(hasattr(sys, "setdlopenflags"),
+ 'test needs sys.setdlopenflags()')
def test_dlopenflags(self):
- if hasattr(sys, "setdlopenflags"):
- self.assertTrue(hasattr(sys, "getdlopenflags"))
- self.assertRaises(TypeError, sys.getdlopenflags, 42)
- oldflags = sys.getdlopenflags()
- self.assertRaises(TypeError, sys.setdlopenflags)
- sys.setdlopenflags(oldflags+1)
- self.assertEqual(sys.getdlopenflags(), oldflags+1)
- sys.setdlopenflags(oldflags)
+ self.assertTrue(hasattr(sys, "getdlopenflags"))
+ self.assertRaises(TypeError, sys.getdlopenflags, 42)
+ oldflags = sys.getdlopenflags()
+ self.assertRaises(TypeError, sys.setdlopenflags)
+ sys.setdlopenflags(oldflags+1)
+ self.assertEqual(sys.getdlopenflags(), oldflags+1)
+ sys.setdlopenflags(oldflags)
def test_refcount(self):
# n here must be a global in order for this test to pass while
@@ -488,6 +469,7 @@
p.wait()
self.assertIn(executable, ["''", repr(sys.executable)])
+@test.test_support.cpython_only
class SizeofTest(unittest.TestCase):
def setUp(self):
diff -r 3a1db0d2747e Lib/test/test_tarfile.py
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -158,6 +158,80 @@
self._test_fileobj_link("symtype2", "ustar/regtype")
+class ListTest(ReadTest, unittest.TestCase):
+
+ # Override setUp to use default encoding (UTF-8)
+ def setUp(self):
+ self.tar = tarfile.open(self.tarname, mode=self.mode)
+
+ def test_list(self):
+ with test_support.captured_stdout() as t:
+ self.tar.list(verbose=False)
+ out = t.getvalue()
+ self.assertIn('ustar/conttype', out)
+ self.assertIn('ustar/regtype', out)
+ self.assertIn('ustar/lnktype', out)
+ self.assertIn('ustar' + ('/12345' * 40) + '67/longname', out)
+ self.assertIn('./ustar/linktest2/symtype', out)
+ self.assertIn('./ustar/linktest2/lnktype', out)
+ # Make sure it puts trailing slash for directory
+ self.assertIn('ustar/dirtype/', out)
+ self.assertIn('ustar/dirtype-with-size/', out)
+ # Make sure it is able to print non-ASCII characters
+ self.assertIn('ustar/umlauts-'
+ '\xc4\xd6\xdc\xe4\xf6\xfc\xdf', out)
+ self.assertIn('misc/regtype-hpux-signed-chksum-'
+ '\xc4\xd6\xdc\xe4\xf6\xfc\xdf', out)
+ self.assertIn('misc/regtype-old-v7-signed-chksum-'
+ '\xc4\xd6\xdc\xe4\xf6\xfc\xdf', out)
+ # Make sure it prints files separated by one newline without any
+ # 'ls -l'-like accessories if verbose flag is not being used
+ # ...
+ # ustar/conttype
+ # ustar/regtype
+ # ...
+ self.assertRegexpMatches(out, r'ustar/conttype ?\r?\n'
+ r'ustar/regtype ?\r?\n')
+ # Make sure it does not print the source of link without verbose flag
+ self.assertNotIn('link to', out)
+ self.assertNotIn('->', out)
+
+ def test_list_verbose(self):
+ with test_support.captured_stdout() as t:
+ self.tar.list(verbose=True)
+ out = t.getvalue()
+ # Make sure it prints files separated by one newline with 'ls -l'-like
+ # accessories if verbose flag is being used
+ # ...
+ # ?rw-r--r-- tarfile/tarfile 7011 2003-01-06 07:19:43 ustar/conttype
+ # ?rw-r--r-- tarfile/tarfile 7011 2003-01-06 07:19:43 ustar/regtype
+ # ...
+ self.assertRegexpMatches(out, (r'-rw-r--r-- tarfile/tarfile\s+7011 '
+ r'\d{4}-\d\d-\d\d\s+\d\d:\d\d:\d\d '
+ r'ustar/\w+type ?\r?\n') * 2)
+ # Make sure it prints the source of link with verbose flag
+ self.assertIn('ustar/symtype -> regtype', out)
+ self.assertIn('./ustar/linktest2/symtype -> ../linktest1/regtype', out)
+ self.assertIn('./ustar/linktest2/lnktype link to '
+ './ustar/linktest1/regtype', out)
+ self.assertIn('gnu' + ('/123' * 125) + '/longlink link to gnu' +
+ ('/123' * 125) + '/longname', out)
+ self.assertIn('pax' + ('/123' * 125) + '/longlink link to pax' +
+ ('/123' * 125) + '/longname', out)
+
+
+class GzipListTest(ListTest):
+ tarname = gzipname
+ mode = "r:gz"
+ taropen = tarfile.TarFile.gzopen
+
+
+class Bz2ListTest(ListTest):
+ tarname = bz2name
+ mode = "r:bz2"
+ taropen = tarfile.TarFile.bz2open
+
+
class CommonReadTest(ReadTest):
def test_empty_tarfile(self):
@@ -181,6 +255,14 @@
self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode)
self.assertRaises(tarfile.ReadError, tarfile.open, tmpname)
+ def test_non_existent_tarfile(self):
+ # Test for issue11513: prevent non-existent gzipped tarfiles raising
+ # multiple exceptions.
+ exctype = OSError if '|' in self.mode else IOError
+ with self.assertRaisesRegexp(exctype, "xxx") as ex:
+ tarfile.open("xxx", self.mode)
+ self.assertEqual(ex.exception.errno, errno.ENOENT)
+
def test_ignore_zeros(self):
# Test TarFile's ignore_zeros option.
if self.mode.endswith(":gz"):
@@ -205,6 +287,7 @@
class MiscReadTest(CommonReadTest):
+ taropen = tarfile.TarFile.taropen
def test_no_name_argument(self):
fobj = open(self.tarname, "rb")
@@ -225,6 +308,17 @@
tar = tarfile.open(fileobj=fobj, mode=self.mode)
self.assertEqual(tar.name, None)
+ def test_illegal_mode_arg(self):
+ with open(tmpname, 'wb'):
+ pass
+ self.addCleanup(os.unlink, tmpname)
+ with self.assertRaisesRegexp(ValueError, 'mode must be '):
+ tar = self.taropen(tmpname, 'q')
+ with self.assertRaisesRegexp(ValueError, 'mode must be '):
+ tar = self.taropen(tmpname, 'rw')
+ with self.assertRaisesRegexp(ValueError, 'mode must be '):
+ tar = self.taropen(tmpname, '')
+
def test_fileobj_with_offset(self):
# Skip the first member and store values from the second member
# of the testtar.
@@ -260,7 +354,7 @@
def test_fail_comp(self):
# For Gzip and Bz2 Tests: fail with a ReadError on an uncompressed file.
if self.mode == "r:":
- return
+ self.skipTest('needs a gz or bz2 mode')
self.assertRaises(tarfile.ReadError, tarfile.open, tarname, self.mode)
fobj = open(tarname, "rb")
self.assertRaises(tarfile.ReadError, tarfile.open, fileobj=fobj, mode=self.mode)
@@ -446,14 +540,12 @@
def test_detect_fileobj(self):
self._test_modes(self._testfunc_fileobj)
+ @unittest.skipUnless(bz2, 'requires bz2')
def test_detect_stream_bz2(self):
# Originally, tarfile's stream detection looked for the string
# "BZh91" at the start of the file. This is incorrect because
# the '9' represents the blocksize (900kB). If the file was
# compressed using another blocksize autodetection fails.
- if not bz2:
- return
-
with open(tarname, "rb") as fobj:
data = fobj.read()
@@ -639,6 +731,12 @@
tar.addfile(tarfile.TarInfo("foo"))
tar.close()
self.assertTrue(fobj.closed is False, "external fileobjs must never closed")
+ # Issue #20238: Incomplete gzip output with mode="w:gz"
+ data = fobj.getvalue()
+ del tar
+ test_support.gc_collect()
+ self.assertFalse(fobj.closed)
+ self.assertEqual(data, fobj.getvalue())
class WriteTest(WriteTestBase):
@@ -955,6 +1053,22 @@
os.unlink(temparchive)
shutil.rmtree(tempdir)
+ def test_open_nonwritable_fileobj(self):
+ for exctype in IOError, EOFError, RuntimeError:
+ class BadFile(StringIO.StringIO):
+ first = True
+ def write(self, data):
+ if self.first:
+ self.first = False
+ raise exctype
+
+ f = BadFile()
+ with self.assertRaises(exctype):
+ tar = tarfile.open(tmpname, self.mode, fileobj=f,
+ format=tarfile.PAX_FORMAT,
+ pax_headers={'non': 'empty'})
+ self.assertFalse(f.closed)
+
class StreamWriteTest(WriteTestBase):
mode = "w|"
@@ -982,12 +1096,11 @@
self.assertTrue(data.count("\0") == tarfile.RECORDSIZE,
"incorrect zero padding")
+ @unittest.skipIf(sys.platform == 'win32', 'not appropriate for Windows')
+ @unittest.skipUnless(hasattr(os, 'umask'), 'requires os.umask')
def test_file_mode(self):
# Test for issue #8464: Create files with correct
# permissions.
- if sys.platform == "win32" or not hasattr(os, "umask"):
- return
-
if os.path.exists(tmpname):
os.remove(tmpname)
@@ -1360,15 +1473,13 @@
self._add_testfile()
self._test(names=["foo", "bar"])
+ @unittest.skipUnless(gzip, 'requires gzip')
def test_append_gz(self):
- if gzip is None:
- return
self._create_testtar("w:gz")
self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, "a")
+ @unittest.skipUnless(bz2, 'requires bz2')
def test_append_bz2(self):
- if bz2 is None:
- return
self._create_testtar("w:bz2")
self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, "a")
@@ -1540,6 +1651,7 @@
class GzipMiscReadTest(MiscReadTest):
tarname = gzipname
mode = "r:gz"
+ taropen = tarfile.TarFile.gzopen
class GzipUstarReadTest(UstarReadTest):
tarname = gzipname
mode = "r:gz"
@@ -1555,6 +1667,7 @@
class Bz2MiscReadTest(MiscReadTest):
tarname = bz2name
mode = "r:bz2"
+ taropen = tarfile.TarFile.bz2open
class Bz2UstarReadTest(UstarReadTest):
tarname = bz2name
mode = "r:bz2"
@@ -1607,6 +1720,7 @@
MemberReadTest,
GNUReadTest,
PaxReadTest,
+ ListTest,
WriteTest,
StreamWriteTest,
GNUWriteTest,
@@ -1638,6 +1752,7 @@
GzipMiscReadTest,
GzipUstarReadTest,
GzipStreamReadTest,
+ GzipListTest,
GzipWriteTest,
GzipStreamWriteTest,
]
@@ -1652,6 +1767,7 @@
Bz2MiscReadTest,
Bz2UstarReadTest,
Bz2StreamReadTest,
+ Bz2ListTest,
Bz2WriteTest,
Bz2StreamWriteTest,
Bz2PartialReadTest,
diff -r 3a1db0d2747e Lib/test/test_tcl.py
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -1,9 +1,6 @@
-#!/usr/bin/env python
-
import unittest
import sys
import os
-import _testcapi
from test import test_support
from subprocess import Popen, PIPE
@@ -13,6 +10,11 @@
from Tkinter import Tcl
from _tkinter import TclError
+try:
+ from _testcapi import INT_MAX, PY_SSIZE_T_MAX
+except ImportError:
+ INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
+
tcl_version = _tkinter.TCL_VERSION.split('.')
try:
for i in range(len(tcl_version)):
@@ -21,6 +23,21 @@
pass
tcl_version = tuple(tcl_version)
+_tk_patchlevel = None
+def get_tk_patchlevel():
+ global _tk_patchlevel
+ if _tk_patchlevel is None:
+ tcl = Tcl()
+ patchlevel = []
+ for x in tcl.call('info', 'patchlevel').split('.'):
+ try:
+ x = int(x, 10)
+ except ValueError:
+ x = -1
+ patchlevel.append(x)
+ _tk_patchlevel = tuple(patchlevel)
+ return _tk_patchlevel
+
class TkinterTest(unittest.TestCase):
@@ -33,6 +50,7 @@
def setUp(self):
self.interp = Tcl()
+ self.wantobjects = self.interp.tk.wantobjects()
def testEval(self):
tcl = self.interp
@@ -125,6 +143,18 @@
self.assertEqual(tcl.eval('set b'),'2')
self.assertEqual(tcl.eval('set c'),'3')
+ def test_evalfile_null_in_result(self):
+ tcl = self.interp
+ with open(test_support.TESTFN, 'wb') as f:
+ self.addCleanup(test_support.unlink, test_support.TESTFN)
+ f.write("""
+ set a "a\0b"
+ set b "a\\0b"
+ """)
+ tcl.evalfile(test_support.TESTFN)
+ self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
+ self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
+
def testEvalFileException(self):
tcl = self.interp
filename = "doesnotexists"
@@ -138,18 +168,15 @@
tcl = self.interp
self.assertRaises(TclError,tcl.eval,'package require DNE')
+ @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
def testLoadWithUNC(self):
- import sys
- if sys.platform != 'win32':
- return
-
# Build a UNC path from the regular path.
# Something like
# \\%COMPUTERNAME%\c$\python27\python.exe
fullname = os.path.abspath(sys.executable)
if fullname[1] != ':':
- return
+ self.skipTest('unusable path: %r' % fullname)
unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
fullname[0],
fullname[3:])
@@ -158,7 +185,14 @@
env.unset("TCL_LIBRARY")
cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
- p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+ try:
+ p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+ except WindowsError as e:
+ if e.winerror == 5:
+ self.skipTest('Not permitted to start the child process')
+ else:
+ raise
+
out_data, err_data = p.communicate()
msg = '\n\n'.join(['"Tkinter.py" not in output',
@@ -171,27 +205,231 @@
self.assertEqual(p.wait(), 0, 'Non-zero exit code')
+ def test_exprstring(self):
+ tcl = self.interp
+ tcl.call('set', 'a', 3)
+ tcl.call('set', 'b', 6)
+ def check(expr, expected):
+ result = tcl.exprstring(expr)
+ self.assertEqual(result, expected)
+ self.assertIsInstance(result, str)
+
+ self.assertRaises(TypeError, tcl.exprstring)
+ self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
+ self.assertRaises(TclError, tcl.exprstring, 'spam')
+ check('', '0')
+ check('8.2 + 6', '14.2')
+ check('3.1 + $a', '6.1')
+ check('2 + "$a.$b"', '5.6')
+ check('4*[llength "6 2"]', '8')
+ check('{word one} < "word $a"', '0')
+ check('4*2 < 7', '0')
+ check('hypot($a, 4)', '5.0')
+ check('5 / 4', '1')
+ check('5 / 4.0', '1.25')
+ check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
+ check('20.0/5.0', '4.0')
+ check('"0x03" > "2"', '1')
+ check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
+ check(r'[string length "a\xbd\u20ac"]', '3')
+ check('"abc"', 'abc')
+ check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
+ check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
+ check(r'"a\0b"', 'a\xc0\x80b')
+ if tcl_version >= (8, 5):
+ check('2**64', str(2**64))
+
+ def test_exprdouble(self):
+ tcl = self.interp
+ tcl.call('set', 'a', 3)
+ tcl.call('set', 'b', 6)
+ def check(expr, expected):
+ result = tcl.exprdouble(expr)
+ self.assertEqual(result, expected)
+ self.assertIsInstance(result, float)
+
+ self.assertRaises(TypeError, tcl.exprdouble)
+ self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
+ self.assertRaises(TclError, tcl.exprdouble, 'spam')
+ check('', 0.0)
+ check('8.2 + 6', 14.2)
+ check('3.1 + $a', 6.1)
+ check('2 + "$a.$b"', 5.6)
+ check('4*[llength "6 2"]', 8.0)
+ check('{word one} < "word $a"', 0.0)
+ check('4*2 < 7', 0.0)
+ check('hypot($a, 4)', 5.0)
+ check('5 / 4', 1.0)
+ check('5 / 4.0', 1.25)
+ check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
+ check('20.0/5.0', 4.0)
+ check('"0x03" > "2"', 1.0)
+ check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
+ check(r'[string length "a\xbd\u20ac"]', 3.0)
+ self.assertRaises(TclError, tcl.exprdouble, '"abc"')
+ if tcl_version >= (8, 5):
+ check('2**64', float(2**64))
+
+ def test_exprlong(self):
+ tcl = self.interp
+ tcl.call('set', 'a', 3)
+ tcl.call('set', 'b', 6)
+ def check(expr, expected):
+ result = tcl.exprlong(expr)
+ self.assertEqual(result, expected)
+ self.assertIsInstance(result, int)
+
+ self.assertRaises(TypeError, tcl.exprlong)
+ self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
+ self.assertRaises(TclError, tcl.exprlong, 'spam')
+ check('', 0)
+ check('8.2 + 6', 14)
+ check('3.1 + $a', 6)
+ check('2 + "$a.$b"', 5)
+ check('4*[llength "6 2"]', 8)
+ check('{word one} < "word $a"', 0)
+ check('4*2 < 7', 0)
+ check('hypot($a, 4)', 5)
+ check('5 / 4', 1)
+ check('5 / 4.0', 1)
+ check('5 / ( [string length "abcd"] + 0.0 )', 1)
+ check('20.0/5.0', 4)
+ check('"0x03" > "2"', 1)
+ check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
+ check(r'[string length "a\xbd\u20ac"]', 3)
+ self.assertRaises(TclError, tcl.exprlong, '"abc"')
+ if tcl_version >= (8, 5):
+ self.assertRaises(TclError, tcl.exprlong, '2**64')
+
+ def test_exprboolean(self):
+ tcl = self.interp
+ tcl.call('set', 'a', 3)
+ tcl.call('set', 'b', 6)
+ def check(expr, expected):
+ result = tcl.exprboolean(expr)
+ self.assertEqual(result, expected)
+ self.assertIsInstance(result, int)
+ self.assertNotIsInstance(result, bool)
+
+ self.assertRaises(TypeError, tcl.exprboolean)
+ self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
+ self.assertRaises(TclError, tcl.exprboolean, 'spam')
+ check('', False)
+ for value in ('0', 'false', 'no', 'off'):
+ check(value, False)
+ check('"%s"' % value, False)
+ check('{%s}' % value, False)
+ for value in ('1', 'true', 'yes', 'on'):
+ check(value, True)
+ check('"%s"' % value, True)
+ check('{%s}' % value, True)
+ check('8.2 + 6', True)
+ check('3.1 + $a', True)
+ check('2 + "$a.$b"', True)
+ check('4*[llength "6 2"]', True)
+ check('{word one} < "word $a"', False)
+ check('4*2 < 7', False)
+ check('hypot($a, 4)', True)
+ check('5 / 4', True)
+ check('5 / 4.0', True)
+ check('5 / ( [string length "abcd"] + 0.0 )', True)
+ check('20.0/5.0', True)
+ check('"0x03" > "2"', True)
+ check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
+ check(r'[string length "a\xbd\u20ac"]', True)
+ self.assertRaises(TclError, tcl.exprboolean, '"abc"')
+ if tcl_version >= (8, 5):
+ check('2**64', True)
+
def test_passing_values(self):
def passValue(value):
return self.interp.call('set', '_', value)
- self.assertEqual(passValue(True), True)
- self.assertEqual(passValue(False), False)
+
+ self.assertEqual(passValue(True), True if self.wantobjects else '1')
+ self.assertEqual(passValue(False), False if self.wantobjects else '0')
self.assertEqual(passValue('string'), 'string')
- self.assertEqual(passValue('string\u20ac'), 'string\u20ac')
+ self.assertEqual(passValue('string\xbd'), 'string\xbd')
+ self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
self.assertEqual(passValue(u'string'), u'string')
+ self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
+ self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
+ self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
+ self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
+ self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
+ self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
for i in (0, 1, -1, int(2**31-1), int(-2**31)):
- self.assertEqual(passValue(i), i)
+ self.assertEqual(passValue(i), i if self.wantobjects else str(i))
for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
sys.float_info.min, sys.float_info.max,
-sys.float_info.min, -sys.float_info.max):
- self.assertEqual(passValue(f), f)
- for f in float('nan'), float('inf'), -float('inf'):
- if f != f: # NaN
- self.assertNotEqual(passValue(f), f)
+ if self.wantobjects:
+ self.assertEqual(passValue(f), f)
else:
- self.assertEqual(passValue(f), f)
- self.assertEqual(passValue((1, '2', (3.4,))), (1, '2', (3.4,)))
+ self.assertEqual(float(passValue(f)), f)
+ if self.wantobjects:
+ f = passValue(float('nan'))
+ self.assertNotEqual(f, f)
+ self.assertEqual(passValue(float('inf')), float('inf'))
+ self.assertEqual(passValue(-float('inf')), -float('inf'))
+ else:
+ f = float(passValue(float('nan')))
+ self.assertNotEqual(f, f)
+ self.assertEqual(float(passValue(float('inf'))), float('inf'))
+ self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
+ self.assertEqual(passValue((1, '2', (3.4,))),
+ (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
+
+ def test_user_command(self):
+ result = []
+ def testfunc(arg):
+ result.append(arg)
+ return arg
+ self.interp.createcommand('testfunc', testfunc)
+ self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
+ def check(value, expected, expected2=None, eq=self.assertEqual):
+ if expected2 is None:
+ expected2 = expected
+ del result[:]
+ r = self.interp.call('testfunc', value)
+ self.assertEqual(len(result), 1)
+ self.assertIsInstance(result[0], (str, unicode))
+ eq(result[0], expected2)
+ self.assertIsInstance(r, (str, unicode))
+ eq(r, expected2)
+ def float_eq(actual, expected):
+ expected = float(expected)
+ self.assertAlmostEqual(float(actual), expected,
+ delta=abs(expected) * 1e-10)
+ def nan_eq(actual, expected):
+ actual = float(actual)
+ self.assertNotEqual(actual, actual)
+
+ check(True, '1')
+ check(False, '0')
+ check('string', 'string')
+ check('string\xbd', 'string\xbd')
+ check('string\xe2\x82\xac', 'string\xe2\x82\xac', u'string\u20ac')
+ check(u'string', u'string')
+ check(u'string\xbd', 'string\xc2\xbd', u'string\xbd')
+ check(u'string\u20ac', 'string\xe2\x82\xac', u'string\u20ac')
+ check('str\xc0\x80ing', 'str\xc0\x80ing', u'str\x00ing')
+ check('str\xc0\x80ing\xe2\x82\xac', 'str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
+ check(u'str\x00ing', 'str\xc0\x80ing', u'str\x00ing')
+ check(u'str\x00ing\xbd', 'str\xc0\x80ing\xc2\xbd', u'str\x00ing\xbd')
+ check(u'str\x00ing\u20ac', 'str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
+ for i in (0, 1, -1, 2**31-1, -2**31):
+ check(i, str(i))
+ for f in (0.0, 1.0, -1.0):
+ check(f, repr(f))
+ for f in (1/3.0, sys.float_info.min, sys.float_info.max,
+ -sys.float_info.min, -sys.float_info.max):
+ check(f, f, eq=float_eq)
+ check(float('inf'), 'Inf', eq=float_eq)
+ check(-float('inf'), '-Inf', eq=float_eq)
+ check(float('nan'), 'NaN', eq=nan_eq)
+ check((), '')
+ check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
def test_splitlist(self):
splitlist = self.interp.tk.splitlist
@@ -208,6 +446,7 @@
(u'a\n b\t\r c\n ', ('a', 'b', 'c')),
('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
(u'a \u20ac', ('a', '\xe2\x82\xac')),
+ ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
('a {b c}', ('a', 'b c')),
(r'a b\ c', ('a', 'b c')),
(('a', 'b c'), ('a', 'b c')),
@@ -216,12 +455,21 @@
('a 3.4', ('a', '3.4')),
(('a', 3.4), ('a', 3.4)),
((), ()),
- (call('list', 1, '2', (3.4,)), (1, '2', (3.4,))),
+ (call('list', 1, '2', (3.4,)),
+ (1, '2', (3.4,)) if self.wantobjects else
+ ('1', '2', '3.4')),
]
if tcl_version >= (8, 5):
+ if not self.wantobjects:
+ expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
+ elif get_tk_patchlevel() < (8, 5, 5):
+ # Before 8.5.5 dicts were converted to lists through string
+ expected = ('12', u'\u20ac', u'\u20ac', '3.4')
+ else:
+ expected = (12, u'\u20ac', u'\u20ac', (3.4,))
testcases += [
- (call('dict', 'create', 1, u'\u20ac', '\xe2\x82\xac', (3.4,)),
- (1, u'\u20ac', u'\u20ac', (3.4,))),
+ (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
+ expected),
]
for arg, res in testcases:
self.assertEqual(splitlist(arg), res)
@@ -243,6 +491,8 @@
(u'a\n b\t\r c\n ', ('a', 'b', 'c')),
('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
(u'a \u20ac', ('a', '\xe2\x82\xac')),
+ ('a\xc0\x80b', 'a\xc0\x80b'),
+ ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
('a {b c}', ('a', ('b', 'c'))),
(r'a b\ c', ('a', ('b', 'c'))),
(('a', 'b c'), ('a', ('b', 'c'))),
@@ -253,12 +503,21 @@
(('a', 3.4), ('a', 3.4)),
(('a', (2, 3.4)), ('a', (2, 3.4))),
((), ()),
- (call('list', 1, '2', (3.4,)), (1, '2', (3.4,))),
+ (call('list', 1, '2', (3.4,)),
+ (1, '2', (3.4,)) if self.wantobjects else
+ ('1', '2', '3.4')),
]
if tcl_version >= (8, 5):
+ if not self.wantobjects:
+ expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
+ elif get_tk_patchlevel() < (8, 5, 5):
+ # Before 8.5.5 dicts were converted to lists through string
+ expected = ('12', u'\u20ac', u'\u20ac', '3.4')
+ else:
+ expected = (12, u'\u20ac', u'\u20ac', (3.4,))
testcases += [
(call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
- (12, u'\u20ac', u'\u20ac', (3.4,))),
+ expected),
]
for arg, res in testcases:
self.assertEqual(split(arg), res)
@@ -269,15 +528,20 @@
def setUp(self):
self.interp = Tcl()
- @unittest.skipUnless(_testcapi.INT_MAX < _testcapi.PY_SSIZE_T_MAX,
- "needs UINT_MAX < SIZE_MAX")
- @test_support.precisionbigmemtest(size=_testcapi.INT_MAX + 1, memuse=5,
- dry_run=False)
+ @test_support.cpython_only
+ @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
+ @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
def test_huge_string(self, size):
value = ' ' * size
self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
+def setUpModule():
+ if test_support.verbose:
+ tcl = Tcl()
+ print 'patchlevel =', tcl.call('info', 'patchlevel')
+
+
def test_main():
test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
diff -r 3a1db0d2747e Lib/test/test_telnetlib.py
--- a/Lib/test/test_telnetlib.py
+++ b/Lib/test/test_telnetlib.py
@@ -177,7 +177,6 @@
self.dataq.join()
data = telnet.read_all()
self.assertEqual(data, ''.join(want[:-1]))
- return
def _test_blocking(self, func):
self.dataq.put([self.block_long, EOF_sigil])
diff -r 3a1db0d2747e Lib/test/test_tempfile.py
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -342,10 +342,9 @@
finally:
os.rmdir(dir)
+ @unittest.skipUnless(has_stat, 'os.stat not available')
def test_file_mode(self):
# _mkstemp_inner creates files with the proper mode
- if not has_stat:
- return # ugh, can't use SkipTest.
file = self.do_create()
mode = stat.S_IMODE(os.stat(file.name).st_mode)
@@ -357,10 +356,9 @@
expected = user * (1 + 8 + 64)
self.assertEqual(mode, expected)
+ @unittest.skipUnless(has_spawnl, 'os.spawnl not available')
def test_noinherit(self):
# _mkstemp_inner file handles are not inherited by child processes
- if not has_spawnl:
- return # ugh, can't use SkipTest.
if support.verbose:
v="v"
@@ -395,10 +393,9 @@
"child process caught fatal signal %d" % -retval)
self.assertFalse(retval > 0, "child process reports failure %d"%retval)
+ @unittest.skipUnless(has_textmode, "text mode not available")
def test_textmode(self):
# _mkstemp_inner can create files in text mode
- if not has_textmode:
- return # ugh, can't use SkipTest.
self.do_create(bin=0).write("blat\n")
# XXX should test that the file really is a text file
@@ -590,10 +587,9 @@
finally:
os.rmdir(dir)
+ @unittest.skipUnless(has_stat, 'os.stat not available')
def test_mode(self):
# mkdtemp creates directories with the proper mode
- if not has_stat:
- return # ugh, can't use SkipTest.
dir = self.do_create()
try:
diff -r 3a1db0d2747e Lib/test/test_thread.py
--- a/Lib/test/test_thread.py
+++ b/Lib/test/test_thread.py
@@ -70,39 +70,35 @@
thread.stack_size(0)
self.assertEqual(thread.stack_size(), 0, "stack_size not reset to default")
- if os.name not in ("nt", "os2", "posix"):
- return
-
- tss_supported = True
+ @unittest.skipIf(os.name not in ("nt", "os2", "posix"), 'test meant for nt, os2, and posix')
+ def test_nt_and_posix_stack_size(self):
try:
thread.stack_size(4096)
except ValueError:
verbose_print("caught expected ValueError setting "
"stack_size(4096)")
except thread.error:
- tss_supported = False
- verbose_print("platform does not support changing thread stack "
- "size")
+ self.skipTest("platform does not support changing thread stack "
+ "size")
- if tss_supported:
- fail_msg = "stack_size(%d) failed - should succeed"
- for tss in (262144, 0x100000, 0):
- thread.stack_size(tss)
- self.assertEqual(thread.stack_size(), tss, fail_msg % tss)
- verbose_print("successfully set stack_size(%d)" % tss)
+ fail_msg = "stack_size(%d) failed - should succeed"
+ for tss in (262144, 0x100000, 0):
+ thread.stack_size(tss)
+ self.assertEqual(thread.stack_size(), tss, fail_msg % tss)
+ verbose_print("successfully set stack_size(%d)" % tss)
- for tss in (262144, 0x100000):
- verbose_print("trying stack_size = (%d)" % tss)
- self.next_ident = 0
- self.created = 0
- for i in range(NUMTASKS):
- self.newtask()
+ for tss in (262144, 0x100000):
+ verbose_print("trying stack_size = (%d)" % tss)
+ self.next_ident = 0
+ self.created = 0
+ for i in range(NUMTASKS):
+ self.newtask()
- verbose_print("waiting for all tasks to complete")
- self.done_mutex.acquire()
- verbose_print("all tasks done")
+ verbose_print("waiting for all tasks to complete")
+ self.done_mutex.acquire()
+ verbose_print("all tasks done")
- thread.stack_size(0)
+ thread.stack_size(0)
def test__count(self):
# Test the _count() function.
diff -r 3a1db0d2747e Lib/test/test_threading.py
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -1,7 +1,7 @@
# Very rudimentary test of threading module
import test.test_support
-from test.test_support import verbose
+from test.test_support import verbose, cpython_only
from test.script_helper import assert_python_ok
import random
@@ -14,6 +14,10 @@
import weakref
import os
import subprocess
+try:
+ import _testcapi
+except ImportError:
+ _testcapi = None
from test import lock_tests
@@ -125,9 +129,7 @@
try:
threading.stack_size(262144)
except thread.error:
- if verbose:
- print 'platform does not support changing thread stack size'
- return
+ self.skipTest('platform does not support changing thread stack size')
self.test_various_ops()
threading.stack_size(0)
@@ -138,9 +140,7 @@
try:
threading.stack_size(0x100000)
except thread.error:
- if verbose:
- print 'platform does not support changing thread stack size'
- return
+ self.skipTest('platform does not support changing thread stack size')
self.test_various_ops()
threading.stack_size(0)
@@ -167,9 +167,7 @@
try:
import ctypes
except ImportError:
- if verbose:
- print "test_PyThreadState_SetAsyncExc can't import ctypes"
- return # can't do anything
+ self.skipTest('requires ctypes')
set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc
@@ -275,9 +273,7 @@
try:
import ctypes
except ImportError:
- if verbose:
- print("test_finalize_with_runnning_thread can't import ctypes")
- return # can't do anything
+ self.skipTest('requires ctypes')
rc = subprocess.call([sys.executable, "-c", """if 1:
import ctypes, sys, time, thread
@@ -728,6 +724,46 @@
for t in threads:
t.join()
+ @cpython_only
+ @unittest.skipIf(_testcapi is None, "need _testcapi module")
+ def test_frame_tstate_tracing(self):
+ # Issue #14432: Crash when a generator is created in a C thread that is
+ # destroyed while the generator is still used. The issue was that a
+ # generator contains a frame, and the frame kept a reference to the
+ # Python state of the destroyed C thread. The crash occurs when a trace
+ # function is setup.
+
+ def noop_trace(frame, event, arg):
+ # no operation
+ return noop_trace
+
+ def generator():
+ while 1:
+ yield "genereator"
+
+ def callback():
+ if callback.gen is None:
+ callback.gen = generator()
+ return next(callback.gen)
+ callback.gen = None
+
+ old_trace = sys.gettrace()
+ sys.settrace(noop_trace)
+ try:
+ # Install a trace function
+ threading.settrace(noop_trace)
+
+ # Create a generator in a C thread which exits after the call
+ _testcapi.call_in_temporary_c_thread(callback)
+
+ # Call the generator in a different Python thread, check that the
+ # generator didn't keep a reference to the destroyed thread state
+ for test in range(3):
+ # The trace function is still called here
+ callback()
+ finally:
+ sys.settrace(old_trace)
+
class ThreadingExceptionTests(BaseTestCase):
# A RuntimeError should be raised if Thread.start() is called
diff -r 3a1db0d2747e Lib/test/test_timeout.py
--- a/Lib/test/test_timeout.py
+++ b/Lib/test/test_timeout.py
@@ -178,16 +178,19 @@
"timeout (%g) is %g seconds more than expected (%g)"
%(_delta, self.fuzz, _timeout))
+ @unittest.skip('test not implemented')
def testSend(self):
# Test send() timeout
# couldn't figure out how to test it
pass
+ @unittest.skip('test not implemented')
def testSendto(self):
# Test sendto() timeout
# couldn't figure out how to test it
pass
+ @unittest.skip('test not implemented')
def testSendall(self):
# Test sendall() timeout
# couldn't figure out how to test it
diff -r 3a1db0d2747e Lib/test/test_tokenize.py
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -4,7 +4,7 @@
>>> import glob, random, sys
The tests can be really simple. Given a small fragment of source
-code, print out a table with tokens. The ENDMARK is omitted for
+code, print out a table with tokens. The ENDMARKER is omitted for
brevity.
>>> dump_tokens("1 + 1")
@@ -559,9 +559,10 @@
from test import test_support
from tokenize import (untokenize, generate_tokens, NUMBER, NAME, OP,
- STRING, ENDMARKER, tok_name)
+ STRING, ENDMARKER, tok_name, Untokenizer)
from StringIO import StringIO
import os
+from unittest import TestCase
def dump_tokens(s):
"""Print out the tokens in s in a table format.
@@ -614,12 +615,47 @@
return untokenize(result)
+class UntokenizeTest(TestCase):
+
+ def test_bad_input_order(self):
+ # raise if previous row
+ u = Untokenizer()
+ u.prev_row = 2
+ u.prev_col = 2
+ with self.assertRaises(ValueError) as cm:
+ u.add_whitespace((1,3))
+ self.assertEqual(cm.exception.args[0],
+ 'start (1,3) precedes previous end (2,2)')
+ # raise if previous column in row
+ self.assertRaises(ValueError, u.add_whitespace, (2,1))
+
+ def test_backslash_continuation(self):
+ # The problem is that <whitespace>\<newline> leaves no token
+ u = Untokenizer()
+ u.prev_row = 1
+ u.prev_col = 1
+ u.tokens = []
+ u.add_whitespace((2, 0))
+ self.assertEqual(u.tokens, ['\\\n'])
+ u.prev_row = 2
+ u.add_whitespace((4, 4))
+ self.assertEqual(u.tokens, ['\\\n', '\\\n\\\n', ' '])
+
+ def test_iter_compat(self):
+ u = Untokenizer()
+ token = (NAME, 'Hello')
+ u.compat(token, iter([]))
+ self.assertEqual(u.tokens, ["Hello "])
+ u = Untokenizer()
+ self.assertEqual(u.untokenize(iter([token])), 'Hello ')
+
+
__test__ = {"doctests" : doctests, 'decistmt': decistmt}
-
def test_main():
from test import test_tokenize
test_support.run_doctest(test_tokenize, True)
+ test_support.run_unittest(UntokenizeTest)
if __name__ == "__main__":
test_main()
diff -r 3a1db0d2747e Lib/test/test_traceback.py
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -1,11 +1,10 @@
"""Test cases for traceback module"""
-from _testcapi import traceback_print
from StringIO import StringIO
import sys
import unittest
from imp import reload
-from test.test_support import run_unittest, is_jython, Error
+from test.test_support import run_unittest, is_jython, Error, cpython_only
import traceback
@@ -35,6 +34,9 @@
def syntax_error_bad_indentation(self):
compile("def spam():\n print 1\n print 2", "?", "exec")
+ def syntax_error_bad_indentation2(self):
+ compile(" print(2)", "?", "exec")
+
def test_caret(self):
err = self.get_exception_format(self.syntax_error_with_caret,
SyntaxError)
@@ -111,6 +113,13 @@
os.unlink(os.path.join(testdir, f))
os.rmdir(testdir)
+ err = self.get_exception_format(self.syntax_error_bad_indentation2,
+ IndentationError)
+ self.assertEqual(len(err), 4)
+ self.assertEqual(err[1].strip(), "print(2)")
+ self.assertIn("^", err[2])
+ self.assertEqual(err[1].find("p"), err[2].find("^"))
+
def test_base_exception(self):
# Test that exceptions derived from BaseException are formatted right
e = KeyboardInterrupt()
@@ -171,7 +180,9 @@
class TracebackFormatTests(unittest.TestCase):
+ @cpython_only
def test_traceback_format(self):
+ from _testcapi import traceback_print
try:
raise KeyError('blah')
except KeyError:
diff -r 3a1db0d2747e Lib/test/test_ucn.py
--- a/Lib/test/test_ucn.py
+++ b/Lib/test/test_ucn.py
@@ -9,10 +9,14 @@
import unittest
import sys
-import _testcapi
from test import test_support
+try:
+ from _testcapi import INT_MAX, PY_SSIZE_T_MAX, UINT_MAX
+except ImportError:
+ INT_MAX = PY_SSIZE_T_MAX = UINT_MAX = 2**64 - 1
+
class UnicodeNamesTest(unittest.TestCase):
def checkletter(self, name, code):
@@ -139,11 +143,10 @@
unicode, "\\NSPACE", 'unicode-escape', 'strict'
)
- @unittest.skipUnless(_testcapi.INT_MAX < _testcapi.PY_SSIZE_T_MAX,
- "needs UINT_MAX < SIZE_MAX")
- @unittest.skipUnless(_testcapi.UINT_MAX < sys.maxint,
- "needs UINT_MAX < sys.maxint")
- @test_support.bigmemtest(minsize=_testcapi.UINT_MAX + 1,
+ @test_support.cpython_only
+ @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
+ @unittest.skipUnless(UINT_MAX < sys.maxint, "needs UINT_MAX < sys.maxint")
+ @test_support.bigmemtest(minsize=UINT_MAX + 1,
memuse=2 + 4 // len(u'\U00010000'))
def test_issue16335(self, size):
func = self.test_issue16335
@@ -151,9 +154,8 @@
raise unittest.SkipTest("not enough memory: %.1fG minimum needed" %
(func.minsize * func.memuse / float(1024**3),))
# very very long bogus character name
- x = b'\\N{SPACE' + b'x' * int(_testcapi.UINT_MAX + 1) + b'}'
- self.assertEqual(len(x), len(b'\\N{SPACE}') +
- (_testcapi.UINT_MAX + 1))
+ x = b'\\N{SPACE' + b'x' * int(UINT_MAX + 1) + b'}'
+ self.assertEqual(len(x), len(b'\\N{SPACE}') + (UINT_MAX + 1))
self.assertRaisesRegexp(UnicodeError,
'unknown Unicode character name',
x.decode, 'unicode-escape'
diff -r 3a1db0d2747e Lib/test/test_unicode.py
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -644,8 +644,13 @@
return u'\u1234'
self.assertEqual('%s' % Wrapper(), u'\u1234')
+ def test_formatting_huge_precision(self):
+ format_string = u"%.{}f".format(sys.maxsize + 1)
+ with self.assertRaises(ValueError):
+ result = format_string % 2.34
+
@test_support.cpython_only
- def test_formatting_huge_precision(self):
+ def test_formatting_huge_precision_c_limits(self):
from _testcapi import INT_MAX
format_string = u"%.{}f".format(INT_MAX + 1)
with self.assertRaises(ValueError):
@@ -1278,12 +1283,12 @@
self.assertEqual(repr(s1()), '\\n')
self.assertEqual(repr(s2()), '\\n')
+ # This test only affects 32-bit platforms because expandtabs can only take
+ # an int as the max value, not a 64-bit C long. If expandtabs is changed
+ # to take a 64-bit long, this test should apply to all platforms.
+ @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4,
+ 'only applies to 32-bit platforms')
def test_expandtabs_overflows_gracefully(self):
- # This test only affects 32-bit platforms because expandtabs can only take
- # an int as the max value, not a 64-bit C long. If expandtabs is changed
- # to take a 64-bit long, this test should apply to all platforms.
- if sys.maxint > (1 << 32) or struct.calcsize('P') != 4:
- return
self.assertRaises(OverflowError, u't\tt\t'.expandtabs, sys.maxint)
def test__format__(self):
@@ -1633,6 +1638,7 @@
self.assertEqual("%s" % u, u'__unicode__ overridden')
self.assertEqual("{}".format(u), '__unicode__ overridden')
+ @test_support.cpython_only
def test_encode_decimal(self):
from _testcapi import unicode_encodedecimal
self.assertEqual(unicode_encodedecimal(u'123'),
@@ -1658,6 +1664,7 @@
self.assertEqual(unicode_encodedecimal(u"123\u20ac\u0660", "replace"),
b'123?0')
+ @test_support.cpython_only
def test_encode_decimal_with_surrogates(self):
from _testcapi import unicode_encodedecimal
tests = [(u'\U0001f49d', '💝'),
diff -r 3a1db0d2747e Lib/test/test_urllib.py
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -789,6 +789,26 @@
self.assertEqual(('user 2', 'ab'),urllib.splitpasswd('user 2:ab'))
self.assertEqual(('user+1', 'a+b'),urllib.splitpasswd('user+1:a+b'))
+ def test_splitport(self):
+ splitport = urllib.splitport
+ self.assertEqual(splitport('parrot:88'), ('parrot', '88'))
+ self.assertEqual(splitport('parrot'), ('parrot', None))
+ self.assertEqual(splitport('parrot:'), ('parrot', None))
+ self.assertEqual(splitport('127.0.0.1'), ('127.0.0.1', None))
+ self.assertEqual(splitport('parrot:cheese'), ('parrot:cheese', None))
+
+ def test_splitnport(self):
+ splitnport = urllib.splitnport
+ self.assertEqual(splitnport('parrot:88'), ('parrot', 88))
+ self.assertEqual(splitnport('parrot'), ('parrot', -1))
+ self.assertEqual(splitnport('parrot', 55), ('parrot', 55))
+ self.assertEqual(splitnport('parrot:'), ('parrot', -1))
+ self.assertEqual(splitnport('parrot:', 55), ('parrot', 55))
+ self.assertEqual(splitnport('127.0.0.1'), ('127.0.0.1', -1))
+ self.assertEqual(splitnport('127.0.0.1', 55), ('127.0.0.1', 55))
+ self.assertEqual(splitnport('parrot:cheese'), ('parrot', None))
+ self.assertEqual(splitnport('parrot:cheese', 55), ('parrot', None))
+
class URLopener_Tests(unittest.TestCase):
"""Testcase to test the open method of URLopener class."""
@@ -858,7 +878,7 @@
# def testTimeoutNone(self):
# # global default timeout is ignored
# import socket
-# self.assertTrue(socket.getdefaulttimeout() is None)
+# self.assertIsNone(socket.getdefaulttimeout())
# socket.setdefaulttimeout(30)
# try:
# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
@@ -870,7 +890,7 @@
# def testTimeoutDefault(self):
# # global default timeout is used
# import socket
-# self.assertTrue(socket.getdefaulttimeout() is None)
+# self.assertIsNone(socket.getdefaulttimeout())
# socket.setdefaulttimeout(30)
# try:
# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
diff -r 3a1db0d2747e Lib/test/test_urllib2.py
--- a/Lib/test/test_urllib2.py
+++ b/Lib/test/test_urllib2.py
@@ -591,8 +591,8 @@
self.assertIsInstance(args[0], Request)
# response from opener.open is None, because there's no
# handler that defines http_open to handle it
- self.assertTrue(args[1] is None or
- isinstance(args[1], MockResponse))
+ if args[1] is not None:
+ self.assertIsInstance(args[1], MockResponse)
def sanepathname2url(path):
@@ -924,7 +924,8 @@
MockHeaders({"location": to_url}))
except urllib2.HTTPError:
# 307 in response to POST requires user OK
- self.assertTrue(code == 307 and data is not None)
+ self.assertEqual(code, 307)
+ self.assertIsNotNone(data)
self.assertEqual(o.req.get_full_url(), to_url)
try:
self.assertEqual(o.req.get_method(), "GET")
diff -r 3a1db0d2747e Lib/test/test_urllib2_localnet.py
--- a/Lib/test/test_urllib2_localnet.py
+++ b/Lib/test/test_urllib2_localnet.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
import urlparse
import urllib2
import BaseHTTPServer
diff -r 3a1db0d2747e Lib/test/test_urllib2net.py
--- a/Lib/test/test_urllib2net.py
+++ b/Lib/test/test_urllib2net.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
import unittest
from test import test_support
from test.test_urllib2 import sanepathname2url
@@ -82,11 +80,11 @@
# delve deep into response to fetch socket._socketobject
response = _urlopen_with_retry("http://www.python.org/")
abused_fileobject = response.fp
- self.assertTrue(abused_fileobject.__class__ is socket._fileobject)
+ self.assertIs(abused_fileobject.__class__, socket._fileobject)
httpresponse = abused_fileobject._sock
- self.assertTrue(httpresponse.__class__ is httplib.HTTPResponse)
+ self.assertIs(httpresponse.__class__, httplib.HTTPResponse)
fileobject = httpresponse.fp
- self.assertTrue(fileobject.__class__ is socket._fileobject)
+ self.assertIs(fileobject.__class__, socket._fileobject)
self.assertTrue(not fileobject.closed)
response.close()
@@ -252,14 +250,14 @@
class TimeoutTest(unittest.TestCase):
def test_http_basic(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
url = "http://www.python.org"
with test_support.transient_internet(url, timeout=None):
u = _urlopen_with_retry(url)
- self.assertTrue(u.fp._sock.fp._sock.gettimeout() is None)
+ self.assertIsNone(u.fp._sock.fp._sock.gettimeout())
def test_http_default_timeout(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
url = "http://www.python.org"
with test_support.transient_internet(url):
socket.setdefaulttimeout(60)
@@ -270,7 +268,7 @@
self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 60)
def test_http_no_timeout(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
url = "http://www.python.org"
with test_support.transient_internet(url):
socket.setdefaulttimeout(60)
@@ -278,7 +276,7 @@
u = _urlopen_with_retry(url, timeout=None)
finally:
socket.setdefaulttimeout(None)
- self.assertTrue(u.fp._sock.fp._sock.gettimeout() is None)
+ self.assertIsNone(u.fp._sock.fp._sock.gettimeout())
def test_http_timeout(self):
url = "http://www.python.org"
@@ -289,13 +287,13 @@
FTP_HOST = "ftp://ftp.mirror.nl/pub/gnu/"
def test_ftp_basic(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
with test_support.transient_internet(self.FTP_HOST, timeout=None):
u = _urlopen_with_retry(self.FTP_HOST)
- self.assertTrue(u.fp.fp._sock.gettimeout() is None)
+ self.assertIsNone(u.fp.fp._sock.gettimeout())
def test_ftp_default_timeout(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout())
with test_support.transient_internet(self.FTP_HOST):
socket.setdefaulttimeout(60)
try:
@@ -305,14 +303,14 @@
self.assertEqual(u.fp.fp._sock.gettimeout(), 60)
def test_ftp_no_timeout(self):
- self.assertTrue(socket.getdefaulttimeout() is None)
+ self.assertIsNone(socket.getdefaulttimeout(),)
with test_support.transient_internet(self.FTP_HOST):
socket.setdefaulttimeout(60)
try:
u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
finally:
socket.setdefaulttimeout(None)
- self.assertTrue(u.fp.fp._sock.gettimeout() is None)
+ self.assertIsNone(u.fp.fp._sock.gettimeout())
def test_ftp_timeout(self):
with test_support.transient_internet(self.FTP_HOST):
diff -r 3a1db0d2747e Lib/test/test_urllibnet.py
--- a/Lib/test/test_urllibnet.py
+++ b/Lib/test/test_urllibnet.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
import unittest
from test import test_support
@@ -94,7 +92,7 @@
def test_geturl(self):
# Make sure same URL as opened is returned by geturl.
- URL = "http://www.python.org/"
+ URL = "https://www.python.org/"
open_url = self.urlopen(URL)
try:
gotten_url = open_url.geturl()
@@ -112,12 +110,9 @@
open_url.close()
self.assertEqual(code, 404)
+ @unittest.skipIf(sys.platform in ('win32',), 'not appropriate for Windows')
+ @unittest.skipUnless(hasattr(os, 'fdopen'), 'os.fdopen not available')
def test_fileno(self):
- if (sys.platform in ('win32',) or
- not hasattr(os, 'fdopen')):
- # On Windows, socket handles are not file descriptors; this
- # test can't pass on Windows.
- return
# Make sure fd returned by fileno is valid.
open_url = self.urlopen("http://www.python.org/")
fd = open_url.fileno()
@@ -189,7 +184,7 @@
"header is not an instance of mimetools.Message")
def test_data_header(self):
- logo = "http://www.python.org/community/logos/python-logo-master-v3-TM.png"
+ logo = "http://python.org/static/community_logos/python-logo-master-v3-TM.png"
file_location, fileheaders = self.urlretrieve(logo)
os.unlink(file_location)
datevalue = fileheaders.getheader('Date')
diff -r 3a1db0d2747e Lib/test/test_urlparse.py
--- a/Lib/test/test_urlparse.py
+++ b/Lib/test/test_urlparse.py
@@ -1,5 +1,3 @@
-#! /usr/bin/env python
-
from test import test_support
import unittest
import urlparse
@@ -364,6 +362,16 @@
('http://[::12.34.56.78]/foo/', '::12.34.56.78', None),
('http://[::ffff:12.34.56.78]/foo/',
'::ffff:12.34.56.78', None),
+ ('http://Test.python.org:/foo/', 'test.python.org', None),
+ ('http://12.34.56.78:/foo/', '12.34.56.78', None),
+ ('http://[::1]:/foo/', '::1', None),
+ ('http://[dead:beef::1]:/foo/', 'dead:beef::1', None),
+ ('http://[dead:beef::]:/foo/', 'dead:beef::', None),
+ ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]:/foo/',
+ 'dead:beef:cafe:5417:affe:8fa3:deaf:feed', None),
+ ('http://[::12.34.56.78]:/foo/', '::12.34.56.78', None),
+ ('http://[::ffff:12.34.56.78]:/foo/',
+ '::ffff:12.34.56.78', None),
]:
urlparsed = urlparse.urlparse(url)
self.assertEqual((urlparsed.hostname, urlparsed.port) , (hostname, port))
diff -r 3a1db0d2747e Lib/test/test_userstring.py
--- a/Lib/test/test_userstring.py
+++ b/Lib/test/test_userstring.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# UserString is a wrapper around the native builtin string type.
# UserString instances should behave similar to builtin string objects.
diff -r 3a1db0d2747e Lib/test/test_uuid.py
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -1,5 +1,6 @@
import unittest
from test import test_support
+import io
import os
import uuid
@@ -346,6 +347,37 @@
self.assertEqual(node1, node2)
+ @unittest.skipUnless(os.name == 'posix', 'requires Posix')
+ def test_find_mac(self):
+ data = '''\
+
+fake hwaddr
+cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
+'''
+ def mock_popen(cmd):
+ return io.BytesIO(data)
+
+ path = os.environ.get("PATH", os.defpath).split(os.pathsep)
+ path.extend(('/sbin', '/usr/sbin'))
+ for dir in path:
+ executable = os.path.join(dir, 'ifconfig')
+ if (os.path.exists(executable) and
+ os.access(executable, os.F_OK | os.X_OK) and
+ not os.path.isdir(executable)):
+ break
+ else:
+ self.skipTest('requires ifconfig')
+
+ with test_support.swap_attr(os, 'popen', mock_popen):
+ mac = uuid._find_mac(
+ command='ifconfig',
+ args='',
+ hw_identifiers=['hwaddr'],
+ get_index=lambda x: x + 1,
+ )
+ self.assertEqual(mac, 0x1234567890ab)
+
@unittest.skipUnless(importable('ctypes'), 'requires ctypes')
def test_uuid1(self):
equal = self.assertEqual
diff -r 3a1db0d2747e Lib/test/test_warnings.py
--- a/Lib/test/test_warnings.py
+++ b/Lib/test/test_warnings.py
@@ -259,11 +259,10 @@
finally:
warning_tests.__file__ = filename
+ @unittest.skipUnless(hasattr(sys, 'argv'), 'test needs sys.argv')
def test_missing_filename_main_with_argv(self):
# If __file__ is not specified and the caller is __main__ and sys.argv
# exists, then use sys.argv[0] as the file.
- if not hasattr(sys, 'argv'):
- return
filename = warning_tests.__file__
module_name = warning_tests.__name__
try:
@@ -669,7 +668,7 @@
# Explicit tests for the test_support convenience wrapper
wmod = self.module
if wmod is not sys.modules['warnings']:
- return
+ self.skipTest('module to test is not loaded warnings module')
with test_support.check_warnings(quiet=False) as w:
self.assertEqual(w.warnings, [])
wmod.simplefilter("always")
diff -r 3a1db0d2747e Lib/test/test_wave.py
--- a/Lib/test/test_wave.py
+++ b/Lib/test/test_wave.py
@@ -5,10 +5,15 @@
import wave
-class WavePCM8Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
+class WaveTest(audiotests.AudioWriteTests,
+ audiotests.AudioTestsWithSourceFile):
module = wave
+ test_unseekable_write = None
+ test_unseekable_overflowed_write = None
+ test_unseekable_incompleted_write = None
+
+
+class WavePCM8Test(WaveTest, unittest.TestCase):
sndfilename = 'pluck-pcm8.wav'
sndfilenframes = 3307
nchannels = 2
@@ -25,10 +30,7 @@
""")
-class WavePCM16Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = wave
+class WavePCM16Test(WaveTest, unittest.TestCase):
sndfilename = 'pluck-pcm16.wav'
sndfilenframes = 3307
nchannels = 2
@@ -48,14 +50,14 @@
if sys.byteorder != 'big':
frames = audiotests.byteswap2(frames)
+ if sys.byteorder == 'big':
+ @unittest.expectedFailure
+ def test_unseekable_incompleted_write(self):
+ super().test_unseekable_incompleted_write()
-@unittest.skipIf(sys.byteorder == 'big',
- '24-bit wave files are supported only on little-endian '
- 'platforms')
-class WavePCM24Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = wave
+
+
+class WavePCM24Test(WaveTest, unittest.TestCase):
sndfilename = 'pluck-pcm24.wav'
sndfilenframes = 3307
nchannels = 2
@@ -82,10 +84,7 @@
frames = audiotests.byteswap3(frames)
-class WavePCM32Test(audiotests.AudioWriteTests,
- audiotests.AudioTestsWithSourceFile,
- unittest.TestCase):
- module = wave
+class WavePCM32Test(WaveTest, unittest.TestCase):
sndfilename = 'pluck-pcm32.wav'
sndfilenframes = 3307
nchannels = 2
@@ -111,6 +110,11 @@
if sys.byteorder != 'big':
frames = audiotests.byteswap4(frames)
+ if sys.byteorder == 'big':
+ @unittest.expectedFailure
+ def test_unseekable_incompleted_write(self):
+ super().test_unseekable_incompleted_write()
+
def test_main():
run_unittest(WavePCM8Test, WavePCM16Test, WavePCM24Test, WavePCM32Test)
diff -r 3a1db0d2747e Lib/test/test_weakref.py
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -4,6 +4,8 @@
import UserList
import weakref
import operator
+import contextlib
+import copy
from test import test_support
@@ -91,11 +93,9 @@
ref1 = weakref.ref(o, self.callback)
ref2 = weakref.ref(o, self.callback)
del o
- self.assertTrue(ref1() is None,
- "expected reference to be invalidated")
- self.assertTrue(ref2() is None,
- "expected reference to be invalidated")
- self.assertTrue(self.cbcalled == 2,
+ self.assertIsNone(ref1(), "expected reference to be invalidated")
+ self.assertIsNone(ref2(), "expected reference to be invalidated")
+ self.assertEqual(self.cbcalled, 2,
"callback not called the right number of times")
def test_multiple_selfref_callbacks(self):
@@ -129,15 +129,15 @@
self.assertRaises(weakref.ReferenceError, check, ref1)
self.assertRaises(weakref.ReferenceError, check, ref2)
self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C()))
- self.assertTrue(self.cbcalled == 2)
+ self.assertEqual(self.cbcalled, 2)
def check_basic_ref(self, factory):
o = factory()
ref = weakref.ref(o)
- self.assertTrue(ref() is not None,
+ self.assertIsNotNone(ref(),
"weak reference to live object should be live")
o2 = ref()
- self.assertTrue(o is o2,
+ self.assertIs(o, o2,
"<ref>() should return original object if live")
def check_basic_callback(self, factory):
@@ -145,9 +145,9 @@
o = factory()
ref = weakref.ref(o, self.callback)
del o
- self.assertTrue(self.cbcalled == 1,
+ self.assertEqual(self.cbcalled, 1,
"callback did not properly set 'cbcalled'")
- self.assertTrue(ref() is None,
+ self.assertIsNone(ref(),
"ref2 should be dead after deleting object reference")
def test_ref_reuse(self):
@@ -157,19 +157,19 @@
# between these two; it should make no difference
proxy = weakref.proxy(o)
ref2 = weakref.ref(o)
- self.assertTrue(ref1 is ref2,
+ self.assertIs(ref1, ref2,
"reference object w/out callback should be re-used")
o = C()
proxy = weakref.proxy(o)
ref1 = weakref.ref(o)
ref2 = weakref.ref(o)
- self.assertTrue(ref1 is ref2,
+ self.assertIs(ref1, ref2,
"reference object w/out callback should be re-used")
- self.assertTrue(weakref.getweakrefcount(o) == 2,
+ self.assertEqual(weakref.getweakrefcount(o), 2,
"wrong weak ref count for object")
del proxy
- self.assertTrue(weakref.getweakrefcount(o) == 1,
+ self.assertEqual(weakref.getweakrefcount(o), 1,
"wrong weak ref count for object after deleting proxy")
def test_proxy_reuse(self):
@@ -177,7 +177,7 @@
proxy1 = weakref.proxy(o)
ref = weakref.ref(o)
proxy2 = weakref.proxy(o)
- self.assertTrue(proxy1 is proxy2,
+ self.assertIs(proxy1, proxy2,
"proxy object w/out callback should have been re-used")
def test_basic_proxy(self):
@@ -259,19 +259,19 @@
o = Object(1)
p1 = makeref(o, None)
p2 = makeref(o, None)
- self.assertTrue(p1 is p2, "both callbacks were None in the C API")
+ self.assertIs(p1, p2, "both callbacks were None in the C API")
del p1, p2
p1 = makeref(o)
p2 = makeref(o, None)
- self.assertTrue(p1 is p2, "callbacks were NULL, None in the C API")
+ self.assertIs(p1, p2, "callbacks were NULL, None in the C API")
del p1, p2
p1 = makeref(o)
p2 = makeref(o)
- self.assertTrue(p1 is p2, "both callbacks were NULL in the C API")
+ self.assertIs(p1, p2, "both callbacks were NULL in the C API")
del p1, p2
p1 = makeref(o, None)
p2 = makeref(o)
- self.assertTrue(p1 is p2, "callbacks were None, NULL in the C API")
+ self.assertIs(p1, p2, "callbacks were None, NULL in the C API")
def test_callable_proxy(self):
o = Callable()
@@ -279,13 +279,13 @@
self.check_proxy(o, ref1)
- self.assertTrue(type(ref1) is weakref.CallableProxyType,
+ self.assertIs(type(ref1), weakref.CallableProxyType,
"proxy is not of callable type")
ref1('twinkies!')
- self.assertTrue(o.bar == 'twinkies!',
+ self.assertEqual(o.bar, 'twinkies!',
"call through proxy not passed through to original")
ref1(x='Splat.')
- self.assertTrue(o.bar == 'Splat.',
+ self.assertEqual(o.bar, 'Splat.',
"call through proxy not passed through to original")
# expect due to too few args
@@ -296,24 +296,23 @@
def check_proxy(self, o, proxy):
o.foo = 1
- self.assertTrue(proxy.foo == 1,
+ self.assertEqual(proxy.foo, 1,
"proxy does not reflect attribute addition")
o.foo = 2
- self.assertTrue(proxy.foo == 2,
+ self.assertEqual(proxy.foo, 2,
"proxy does not reflect attribute modification")
del o.foo
- self.assertTrue(not hasattr(proxy, 'foo'),
+ self.assertFalse(hasattr(proxy, 'foo'),
"proxy does not reflect attribute removal")
proxy.foo = 1
- self.assertTrue(o.foo == 1,
+ self.assertEqual(o.foo, 1,
"object does not reflect attribute addition via proxy")
proxy.foo = 2
- self.assertTrue(
- o.foo == 2,
+ self.assertEqual(o.foo, 2,
"object does not reflect attribute modification via proxy")
del proxy.foo
- self.assertTrue(not hasattr(o, 'foo'),
+ self.assertFalse(hasattr(o, 'foo'),
"object does not reflect attribute removal via proxy")
def test_proxy_deletion(self):
@@ -337,21 +336,21 @@
o = C()
ref1 = weakref.ref(o)
ref2 = weakref.ref(o, self.callback)
- self.assertTrue(weakref.getweakrefcount(o) == 2,
+ self.assertEqual(weakref.getweakrefcount(o), 2,
"got wrong number of weak reference objects")
proxy1 = weakref.proxy(o)
proxy2 = weakref.proxy(o, self.callback)
- self.assertTrue(weakref.getweakrefcount(o) == 4,
+ self.assertEqual(weakref.getweakrefcount(o), 4,
"got wrong number of weak reference objects")
del ref1, ref2, proxy1, proxy2
- self.assertTrue(weakref.getweakrefcount(o) == 0,
+ self.assertEqual(weakref.getweakrefcount(o), 0,
"weak reference objects not unlinked from"
" referent when discarded.")
# assumes ints do not support weakrefs
- self.assertTrue(weakref.getweakrefcount(1) == 0,
+ self.assertEqual(weakref.getweakrefcount(1), 0,
"got wrong number of weak reference objects for int")
def test_getweakrefs(self):
@@ -359,22 +358,22 @@
ref1 = weakref.ref(o, self.callback)
ref2 = weakref.ref(o, self.callback)
del ref1
- self.assertTrue(weakref.getweakrefs(o) == [ref2],
+ self.assertEqual(weakref.getweakrefs(o), [ref2],
"list of refs does not match")
o = C()
ref1 = weakref.ref(o, self.callback)
ref2 = weakref.ref(o, self.callback)
del ref2
- self.assertTrue(weakref.getweakrefs(o) == [ref1],
+ self.assertEqual(weakref.getweakrefs(o), [ref1],
"list of refs does not match")
del ref1
- self.assertTrue(weakref.getweakrefs(o) == [],
+ self.assertEqual(weakref.getweakrefs(o), [],
"list of refs not cleared")
# assumes ints do not support weakrefs
- self.assertTrue(weakref.getweakrefs(1) == [],
+ self.assertEqual(weakref.getweakrefs(1), [],
"list of refs does not match for int")
def test_newstyle_number_ops(self):
@@ -382,8 +381,8 @@
pass
f = F(2.0)
p = weakref.proxy(f)
- self.assertTrue(p + 1.0 == 3.0)
- self.assertTrue(1.0 + p == 3.0) # this used to SEGV
+ self.assertEqual(p + 1.0, 3.0)
+ self.assertEqual(1.0 + p, 3.0) # this used to SEGV
def test_callbacks_protected(self):
# Callbacks protected from already-set exceptions?
@@ -636,7 +635,7 @@
c.wr = weakref.ref(d, callback) # this won't trigger
d.wr = weakref.ref(callback, d.cb) # ditto
external_wr = weakref.ref(callback, safe_callback) # but this will
- self.assertTrue(external_wr() is callback)
+ self.assertIs(external_wr(), callback)
# The weakrefs attached to c and d should get cleared, so that
# C.cb is never called. But external_wr isn't part of the cyclic
@@ -808,11 +807,11 @@
return super(MyRef, self).__call__()
o = Object("foo")
mr = MyRef(o, value=24)
- self.assertTrue(mr() is o)
+ self.assertIs(mr(), o)
self.assertTrue(mr.called)
self.assertEqual(mr.value, 24)
del o
- self.assertTrue(mr() is None)
+ self.assertIsNone(mr())
self.assertTrue(mr.called)
def test_subclass_refs_dont_replace_standard_refs(self):
@@ -821,14 +820,14 @@
o = Object(42)
r1 = MyRef(o)
r2 = weakref.ref(o)
- self.assertTrue(r1 is not r2)
+ self.assertIsNot(r1, r2)
self.assertEqual(weakref.getweakrefs(o), [r2, r1])
self.assertEqual(weakref.getweakrefcount(o), 2)
r3 = MyRef(o)
self.assertEqual(weakref.getweakrefcount(o), 3)
refs = weakref.getweakrefs(o)
self.assertEqual(len(refs), 3)
- self.assertTrue(r2 is refs[0])
+ self.assertIs(r2, refs[0])
self.assertIn(r1, refs[1:])
self.assertIn(r3, refs[1:])
@@ -838,7 +837,7 @@
o = Object(42)
r1 = MyRef(o, id)
r2 = MyRef(o, str)
- self.assertTrue(r1 is not r2)
+ self.assertIsNot(r1, r2)
refs = weakref.getweakrefs(o)
self.assertIn(r1, refs)
self.assertIn(r2, refs)
@@ -906,7 +905,7 @@
def check_len_cycles(self, dict_type, cons):
N = 20
items = [RefCycle() for i in range(N)]
- dct = dict_type(cons(o) for o in items)
+ dct = dict_type(cons(i, o) for i, o in enumerate(items))
# Keep an iterator alive
it = dct.iteritems()
try:
@@ -916,18 +915,23 @@
del items
gc.collect()
n1 = len(dct)
+ list(it)
del it
gc.collect()
n2 = len(dct)
- # one item may be kept alive inside the iterator
- self.assertIn(n1, (0, 1))
+ # iteration should prevent garbage collection here
+ # Note that this is a test on an implementation detail. The requirement
+ # is only to provide stable iteration, not that the size of the container
+ # stay fixed.
+ self.assertEqual(n1, 20)
+ #self.assertIn(n1, (0, 1))
self.assertEqual(n2, 0)
def test_weak_keyed_len_cycles(self):
- self.check_len_cycles(weakref.WeakKeyDictionary, lambda k: (k, 1))
+ self.check_len_cycles(weakref.WeakKeyDictionary, lambda n, k: (k, n))
def test_weak_valued_len_cycles(self):
- self.check_len_cycles(weakref.WeakValueDictionary, lambda k: (1, k))
+ self.check_len_cycles(weakref.WeakValueDictionary, lambda n, k: (n, k))
def check_len_race(self, dict_type, cons):
# Extended sanity checks for len() in the face of cyclic collection
@@ -965,23 +969,23 @@
#
dict, objects = self.make_weak_valued_dict()
for o in objects:
- self.assertTrue(weakref.getweakrefcount(o) == 1,
+ self.assertEqual(weakref.getweakrefcount(o), 1,
"wrong number of weak references to %r!" % o)
- self.assertTrue(o is dict[o.arg],
+ self.assertIs(o, dict[o.arg],
"wrong object returned by weak dict!")
items1 = dict.items()
items2 = dict.copy().items()
items1.sort()
items2.sort()
- self.assertTrue(items1 == items2,
+ self.assertEqual(items1, items2,
"cloning of weak-valued dictionary did not work!")
del items1, items2
- self.assertTrue(len(dict) == self.COUNT)
+ self.assertEqual(len(dict), self.COUNT)
del objects[0]
- self.assertTrue(len(dict) == (self.COUNT - 1),
+ self.assertEqual(len(dict), (self.COUNT - 1),
"deleting object did not cause dictionary update")
del objects, o
- self.assertTrue(len(dict) == 0,
+ self.assertEqual(len(dict), 0,
"deleting the values did not clear the dictionary")
# regression on SF bug #447152:
dict = weakref.WeakValueDictionary()
@@ -996,21 +1000,21 @@
#
dict, objects = self.make_weak_keyed_dict()
for o in objects:
- self.assertTrue(weakref.getweakrefcount(o) == 1,
+ self.assertEqual(weakref.getweakrefcount(o), 1,
"wrong number of weak references to %r!" % o)
- self.assertTrue(o.arg is dict[o],
+ self.assertIs(o.arg, dict[o],
"wrong object returned by weak dict!")
items1 = dict.items()
items2 = dict.copy().items()
- self.assertTrue(set(items1) == set(items2),
+ self.assertEqual(set(items1), set(items2),
"cloning of weak-keyed dictionary did not work!")
del items1, items2
- self.assertTrue(len(dict) == self.COUNT)
+ self.assertEqual(len(dict), self.COUNT)
del objects[0]
- self.assertTrue(len(dict) == (self.COUNT - 1),
+ self.assertEqual(len(dict), (self.COUNT - 1),
"deleting object did not cause dictionary update")
del objects, o
- self.assertTrue(len(dict) == 0,
+ self.assertEqual(len(dict), 0,
"deleting the keys did not clear the dictionary")
o = Object(42)
dict[o] = "What is the meaning of the universe?"
@@ -1072,37 +1076,117 @@
items = dict.items()
for item in dict.iteritems():
items.remove(item)
- self.assertTrue(len(items) == 0, "iteritems() did not touch all items")
+ self.assertEqual(len(items), 0, "iteritems() did not touch all items")
# key iterator, via __iter__():
keys = dict.keys()
for k in dict:
keys.remove(k)
- self.assertTrue(len(keys) == 0, "__iter__() did not touch all keys")
+ self.assertEqual(len(keys), 0, "__iter__() did not touch all keys")
# key iterator, via iterkeys():
keys = dict.keys()
for k in dict.iterkeys():
keys.remove(k)
- self.assertTrue(len(keys) == 0, "iterkeys() did not touch all keys")
+ self.assertEqual(len(keys), 0, "iterkeys() did not touch all keys")
# value iterator:
values = dict.values()
for v in dict.itervalues():
values.remove(v)
- self.assertTrue(len(values) == 0,
+ self.assertEqual(len(values), 0,
"itervalues() did not touch all values")
+ def check_weak_destroy_while_iterating(self, dict, objects, iter_name):
+ n = len(dict)
+ it = iter(getattr(dict, iter_name)())
+ next(it) # Trigger internal iteration
+ # Destroy an object
+ del objects[-1]
+ gc.collect() # just in case
+ # We have removed either the first consumed object, or another one
+ self.assertIn(len(list(it)), [len(objects), len(objects) - 1])
+ del it
+ # The removal has been committed
+ self.assertEqual(len(dict), n - 1)
+
+ def check_weak_destroy_and_mutate_while_iterating(self, dict, testcontext):
+ # Check that we can explicitly mutate the weak dict without
+ # interfering with delayed removal.
+ # `testcontext` should create an iterator, destroy one of the
+ # weakref'ed objects and then return a new key/value pair corresponding
+ # to the destroyed object.
+ with testcontext() as (k, v):
+ self.assertFalse(k in dict)
+ with testcontext() as (k, v):
+ self.assertRaises(KeyError, dict.__delitem__, k)
+ self.assertFalse(k in dict)
+ with testcontext() as (k, v):
+ self.assertRaises(KeyError, dict.pop, k)
+ self.assertFalse(k in dict)
+ with testcontext() as (k, v):
+ dict[k] = v
+ self.assertEqual(dict[k], v)
+ ddict = copy.copy(dict)
+ with testcontext() as (k, v):
+ dict.update(ddict)
+ self.assertEqual(dict, ddict)
+ with testcontext() as (k, v):
+ dict.clear()
+ self.assertEqual(len(dict), 0)
+
+ def test_weak_keys_destroy_while_iterating(self):
+ # Issue #7105: iterators shouldn't crash when a key is implicitly removed
+ dict, objects = self.make_weak_keyed_dict()
+ self.check_weak_destroy_while_iterating(dict, objects, 'iterkeys')
+ self.check_weak_destroy_while_iterating(dict, objects, 'iteritems')
+ self.check_weak_destroy_while_iterating(dict, objects, 'itervalues')
+ self.check_weak_destroy_while_iterating(dict, objects, 'iterkeyrefs')
+ dict, objects = self.make_weak_keyed_dict()
+ @contextlib.contextmanager
+ def testcontext():
+ try:
+ it = iter(dict.iteritems())
+ next(it)
+ # Schedule a key/value for removal and recreate it
+ v = objects.pop().arg
+ gc.collect() # just in case
+ yield Object(v), v
+ finally:
+ it = None # should commit all removals
+ self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext)
+
+ def test_weak_values_destroy_while_iterating(self):
+ # Issue #7105: iterators shouldn't crash when a key is implicitly removed
+ dict, objects = self.make_weak_valued_dict()
+ self.check_weak_destroy_while_iterating(dict, objects, 'iterkeys')
+ self.check_weak_destroy_while_iterating(dict, objects, 'iteritems')
+ self.check_weak_destroy_while_iterating(dict, objects, 'itervalues')
+ self.check_weak_destroy_while_iterating(dict, objects, 'itervaluerefs')
+ dict, objects = self.make_weak_valued_dict()
+ @contextlib.contextmanager
+ def testcontext():
+ try:
+ it = iter(dict.iteritems())
+ next(it)
+ # Schedule a key/value for removal and recreate it
+ k = objects.pop().arg
+ gc.collect() # just in case
+ yield k, Object(k)
+ finally:
+ it = None # should commit all removals
+ self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext)
+
def test_make_weak_keyed_dict_from_dict(self):
o = Object(3)
dict = weakref.WeakKeyDictionary({o:364})
- self.assertTrue(dict[o] == 364)
+ self.assertEqual(dict[o], 364)
def test_make_weak_keyed_dict_from_weak_keyed_dict(self):
o = Object(3)
dict = weakref.WeakKeyDictionary({o:364})
dict2 = weakref.WeakKeyDictionary(dict)
- self.assertTrue(dict[o] == 364)
+ self.assertEqual(dict[o], 364)
def make_weak_keyed_dict(self):
dict = weakref.WeakKeyDictionary()
@@ -1122,19 +1206,19 @@
weakdict = klass()
weakdict[key1] = value1
weakdict[key2] = value2
- self.assertTrue(len(weakdict) == 2)
+ self.assertEqual(len(weakdict), 2)
k, v = weakdict.popitem()
- self.assertTrue(len(weakdict) == 1)
+ self.assertEqual(len(weakdict), 1)
if k is key1:
- self.assertTrue(v is value1)
+ self.assertIs(v, value1)
else:
- self.assertTrue(v is value2)
+ self.assertIs(v, value2)
k, v = weakdict.popitem()
- self.assertTrue(len(weakdict) == 0)
+ self.assertEqual(len(weakdict), 0)
if k is key1:
- self.assertTrue(v is value1)
+ self.assertIs(v, value1)
else:
- self.assertTrue(v is value2)
+ self.assertIs(v, value2)
def test_weak_valued_dict_popitem(self):
self.check_popitem(weakref.WeakValueDictionary,
@@ -1145,7 +1229,7 @@
C(), "value 1", C(), "value 2")
def check_setdefault(self, klass, key, value1, value2):
- self.assertTrue(value1 is not value2,
+ self.assertIsNot(value1, value2,
"invalid test"
" -- value parameters must be distinct objects")
weakdict = klass()
@@ -1204,10 +1288,10 @@
o2 = Object('2')
d[o1] = 'something'
d[o2] = 'something'
- self.assertTrue(len(d) == 2)
+ self.assertEqual(len(d), 2)
del d[o1]
- self.assertTrue(len(d) == 1)
- self.assertTrue(d.keys() == [o2])
+ self.assertEqual(len(d), 1)
+ self.assertEqual(d.keys(), [o2])
def test_weak_valued_delitem(self):
d = weakref.WeakValueDictionary()
@@ -1215,10 +1299,10 @@
o2 = Object('2')
d['something'] = o1
d['something else'] = o2
- self.assertTrue(len(d) == 2)
+ self.assertEqual(len(d), 2)
del d['something']
- self.assertTrue(len(d) == 1)
- self.assertTrue(d.items() == [('something else', o2)])
+ self.assertEqual(len(d), 1)
+ self.assertEqual(d.items(), [('something else', o2)])
def test_weak_keyed_bad_delitem(self):
d = weakref.WeakKeyDictionary()
diff -r 3a1db0d2747e Lib/test/test_weakset.py
--- a/Lib/test/test_weakset.py
+++ b/Lib/test/test_weakset.py
@@ -11,6 +11,7 @@
import collections
import gc
import contextlib
+from UserString import UserString as ustr
class Foo:
@@ -448,6 +449,59 @@
self.assertGreaterEqual(n2, 0)
self.assertLessEqual(n2, n1)
+ def test_weak_destroy_while_iterating(self):
+ # Issue #7105: iterators shouldn't crash when a key is implicitly removed
+ # Create new items to be sure no-one else holds a reference
+ items = [ustr(c) for c in ('a', 'b', 'c')]
+ s = WeakSet(items)
+ it = iter(s)
+ next(it) # Trigger internal iteration
+ # Destroy an item
+ del items[-1]
+ gc.collect() # just in case
+ # We have removed either the first consumed items, or another one
+ self.assertIn(len(list(it)), [len(items), len(items) - 1])
+ del it
+ # The removal has been committed
+ self.assertEqual(len(s), len(items))
+
+ def test_weak_destroy_and_mutate_while_iterating(self):
+ # Issue #7105: iterators shouldn't crash when a key is implicitly removed
+ items = [ustr(c) for c in string.ascii_letters]
+ s = WeakSet(items)
+ @contextlib.contextmanager
+ def testcontext():
+ try:
+ it = iter(s)
+ # Start iterator
+ yielded = ustr(str(next(it)))
+ # Schedule an item for removal and recreate it
+ u = ustr(str(items.pop()))
+ if yielded == u:
+ # The iterator still has a reference to the removed item,
+ # advance it (issue #20006).
+ next(it)
+ gc.collect() # just in case
+ yield u
+ finally:
+ it = None # should commit all removals
+
+ with testcontext() as u:
+ self.assertFalse(u in s)
+ with testcontext() as u:
+ self.assertRaises(KeyError, s.remove, u)
+ self.assertFalse(u in s)
+ with testcontext() as u:
+ s.add(u)
+ self.assertTrue(u in s)
+ t = s.copy()
+ with testcontext() as u:
+ s.update(t)
+ self.assertEqual(len(s), len(t))
+ with testcontext() as u:
+ s.clear()
+ self.assertEqual(len(s), 0)
+
def test_main(verbose=None):
test_support.run_unittest(TestWeakSet)
diff -r 3a1db0d2747e Lib/test/test_whichdb.py
--- a/Lib/test/test_whichdb.py
+++ b/Lib/test/test_whichdb.py
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
"""Test script for the whichdb module
based on test_anydbm.py
"""
diff -r 3a1db0d2747e Lib/test/test_winsound.py
--- a/Lib/test/test_winsound.py
+++ b/Lib/test/test_winsound.py
@@ -159,18 +159,15 @@
)
def test_alias_fallback(self):
- # This test can't be expected to work on all systems. The MS
- # PlaySound() docs say:
- #
- # If it cannot find the specified sound, PlaySound uses the
- # default system event sound entry instead. If the function
- # can find neither the system default entry nor the default
- # sound, it makes no sound and returns FALSE.
- #
- # It's known to return FALSE on some real systems.
-
- # winsound.PlaySound('!"$%&/(#+*', winsound.SND_ALIAS)
- return
+ # In the absense of the ability to tell if a sound was actually
+ # played, this test has two acceptable outcomes: success (no error,
+ # sound was theoretically played; although as issue #19987 shows
+ # a box without a soundcard can "succeed") or RuntimeError. Any
+ # other error is a failure.
+ try:
+ winsound.PlaySound('!"$%&/(#+*', winsound.SND_ALIAS)
+ except RuntimeError:
+ pass
def test_alias_nofallback(self):
if _have_soundcard():
diff -r 3a1db0d2747e Lib/test/test_with.py
--- a/Lib/test/test_with.py
+++ b/Lib/test/test_with.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
"""Unit tests for the with statement specified in PEP 343."""
diff -r 3a1db0d2747e Lib/test/test_wsgiref.py
--- a/Lib/test/test_wsgiref.py
+++ b/Lib/test/test_wsgiref.py
@@ -155,7 +155,7 @@
# Check existing value
env = {key:alt}
util.setup_testing_defaults(env)
- self.assertTrue(env[key] is alt)
+ self.assertIs(env[key], alt)
def checkCrossDefault(self,key,value,**kw):
util.setup_testing_defaults(kw)
@@ -245,6 +245,7 @@
def testAppURIs(self):
self.checkAppURI("http://127.0.0.1/")
self.checkAppURI("http://127.0.0.1/spam", SCRIPT_NAME="/spam")
+ self.checkAppURI("http://127.0.0.1/sp%E4m", SCRIPT_NAME="/sp\xe4m")
self.checkAppURI("http://spam.example.com:2071/",
HTTP_HOST="spam.example.com:2071", SERVER_PORT="2071")
self.checkAppURI("http://spam.example.com/",
@@ -258,14 +259,19 @@
def testReqURIs(self):
self.checkReqURI("http://127.0.0.1/")
self.checkReqURI("http://127.0.0.1/spam", SCRIPT_NAME="/spam")
+ self.checkReqURI("http://127.0.0.1/sp%E4m", SCRIPT_NAME="/sp\xe4m")
self.checkReqURI("http://127.0.0.1/spammity/spam",
SCRIPT_NAME="/spammity", PATH_INFO="/spam")
+ self.checkReqURI("http://127.0.0.1/spammity/sp%E4m",
+ SCRIPT_NAME="/spammity", PATH_INFO="/sp\xe4m")
self.checkReqURI("http://127.0.0.1/spammity/spam;ham",
SCRIPT_NAME="/spammity", PATH_INFO="/spam;ham")
self.checkReqURI("http://127.0.0.1/spammity/spam;cookie=1234,5678",
SCRIPT_NAME="/spammity", PATH_INFO="/spam;cookie=1234,5678")
self.checkReqURI("http://127.0.0.1/spammity/spam?say=ni",
SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="say=ni")
+ self.checkReqURI("http://127.0.0.1/spammity/spam?s%E4y=ni",
+ SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="s%E4y=ni")
self.checkReqURI("http://127.0.0.1/spammity/spam", 0,
SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="say=ni")
@@ -296,7 +302,7 @@
self.assertEqual(Headers(test[:]).keys(), ['x'])
self.assertEqual(Headers(test[:]).values(), ['y'])
self.assertEqual(Headers(test[:]).items(), test)
- self.assertFalse(Headers(test).items() is test) # must be copy!
+ self.assertIsNot(Headers(test).items(), test) # must be copy!
h=Headers([])
del h['foo'] # should not raise an error
diff -r 3a1db0d2747e Lib/test/test_xml_etree.py
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -713,14 +713,21 @@
end {namespace}root
end-ns None
+ >>> import StringIO
+
+ >>> events = ('start-ns', 'end-ns')
+ >>> context = ET.iterparse(StringIO.StringIO(r"<root xmlns=''/>"), events)
+ >>> for action, elem in context:
+ ... print action, elem
+ start-ns ('', '')
+ end-ns None
+
>>> events = ("start", "end", "bogus")
>>> with open(SIMPLE_XMLFILE, "rb") as f:
... iterparse(f, events)
Traceback (most recent call last):
ValueError: unknown event 'bogus'
- >>> import StringIO
-
>>> source = StringIO.StringIO(
... "<?xml version='1.0' encoding='iso-8859-1'?>\\n"
... "<body xmlns='http://éffbot.org/ns'\\n"
diff -r 3a1db0d2747e Lib/test/test_xmlrpc.py
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -19,6 +19,11 @@
threading = None
try:
+ import gzip
+except ImportError:
+ gzip = None
+
+try:
unicode
except NameError:
have_unicode = False
@@ -681,6 +686,7 @@
#A test case that verifies that gzip encoding works in both directions
#(for a request and the response)
+@unittest.skipUnless(gzip, 'gzip not available')
class GzipServerTestCase(BaseServerTestCase):
#a request handler that supports keep-alive and logs requests into a
#class variable
@@ -1011,11 +1017,7 @@
xmlrpc_tests.append(SimpleServerTestCase)
xmlrpc_tests.append(KeepaliveServerTestCase1)
xmlrpc_tests.append(KeepaliveServerTestCase2)
- try:
- import gzip
- xmlrpc_tests.append(GzipServerTestCase)
- except ImportError:
- pass #gzip not supported in this build
+ xmlrpc_tests.append(GzipServerTestCase)
xmlrpc_tests.append(MultiPathServerTestCase)
xmlrpc_tests.append(ServerProxyTestCase)
xmlrpc_tests.append(FailingServerTestCase)
diff -r 3a1db0d2747e Lib/test/test_zipfile.py
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -19,7 +19,7 @@
from unittest import skipUnless
from test.test_support import TESTFN, TESTFN_UNICODE, TESTFN_ENCODING, \
- run_unittest, findfile, unlink
+ run_unittest, findfile, unlink, check_warnings
try:
TESTFN_UNICODE.encode(TESTFN_ENCODING)
except (UnicodeError, TypeError):
@@ -148,7 +148,9 @@
# Create the ZIP archive
with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
zipfp.writestr("name", "foo")
- zipfp.writestr("name", "bar")
+ with check_warnings(('', UserWarning)):
+ zipfp.writestr("name", "bar")
+ self.assertEqual(zipfp.namelist(), ["name"] * 2)
with zipfile.ZipFile(TESTFN2, "r") as zipfp:
infos = zipfp.infolist()
@@ -1035,7 +1037,8 @@
# check a comment that is too long is truncated
with zipfile.ZipFile(TESTFN, mode="w") as zipf:
- zipf.comment = comment2 + 'oops'
+ with check_warnings(('', UserWarning)):
+ zipf.comment = comment2 + 'oops'
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
with zipfile.ZipFile(TESTFN, mode="r") as zipf:
self.assertEqual(zipf.comment, comment2)
diff -r 3a1db0d2747e Lib/test/test_zlib.py
--- a/Lib/test/test_zlib.py
+++ b/Lib/test/test_zlib.py
@@ -12,6 +12,13 @@
zlib = import_module('zlib')
+requires_Compress_copy = unittest.skipUnless(
+ hasattr(zlib.compressobj(), "copy"),
+ 'requires Compress.copy()')
+requires_Decompress_copy = unittest.skipUnless(
+ hasattr(zlib.decompressobj(), "copy"),
+ 'requires Decompress.copy()')
+
class ChecksumTestCase(unittest.TestCase):
# checksum test cases
@@ -339,39 +346,39 @@
"mode=%i, level=%i") % (sync, level))
del obj
+ @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
+ 'requires zlib.Z_SYNC_FLUSH')
def test_odd_flush(self):
# Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
import random
+ # Testing on 17K of "random" data
- if hasattr(zlib, 'Z_SYNC_FLUSH'):
- # Testing on 17K of "random" data
+ # Create compressor and decompressor objects
+ co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+ dco = zlib.decompressobj()
- # Create compressor and decompressor objects
- co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
- dco = zlib.decompressobj()
+ # Try 17K of data
+ # generate random data stream
+ try:
+ # In 2.3 and later, WichmannHill is the RNG of the bug report
+ gen = random.WichmannHill()
+ except AttributeError:
+ try:
+ # 2.2 called it Random
+ gen = random.Random()
+ except AttributeError:
+ # others might simply have a single RNG
+ gen = random
+ gen.seed(1)
+ data = genblock(1, 17 * 1024, generator=gen)
- # Try 17K of data
- # generate random data stream
- try:
- # In 2.3 and later, WichmannHill is the RNG of the bug report
- gen = random.WichmannHill()
- except AttributeError:
- try:
- # 2.2 called it Random
- gen = random.Random()
- except AttributeError:
- # others might simply have a single RNG
- gen = random
- gen.seed(1)
- data = genblock(1, 17 * 1024, generator=gen)
+ # compress, sync-flush, and decompress
+ first = co.compress(data)
+ second = co.flush(zlib.Z_SYNC_FLUSH)
+ expanded = dco.decompress(first + second)
- # compress, sync-flush, and decompress
- first = co.compress(data)
- second = co.flush(zlib.Z_SYNC_FLUSH)
- expanded = dco.decompress(first + second)
-
- # if decompressed data is different from the input data, choke.
- self.assertEqual(expanded, data, "17K random source doesn't match")
+ # if decompressed data is different from the input data, choke.
+ self.assertEqual(expanded, data, "17K random source doesn't match")
def test_empty_flush(self):
# Test that calling .flush() on unused objects works.
@@ -408,35 +415,36 @@
data = zlib.compress(input2)
self.assertEqual(dco.flush(), input1[1:])
- if hasattr(zlib.compressobj(), "copy"):
- def test_compresscopy(self):
- # Test copying a compression object
- data0 = HAMLET_SCENE
- data1 = HAMLET_SCENE.swapcase()
- c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
- bufs0 = []
- bufs0.append(c0.compress(data0))
+ @requires_Compress_copy
+ def test_compresscopy(self):
+ # Test copying a compression object
+ data0 = HAMLET_SCENE
+ data1 = HAMLET_SCENE.swapcase()
+ c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+ bufs0 = []
+ bufs0.append(c0.compress(data0))
- c1 = c0.copy()
- bufs1 = bufs0[:]
+ c1 = c0.copy()
+ bufs1 = bufs0[:]
- bufs0.append(c0.compress(data0))
- bufs0.append(c0.flush())
- s0 = ''.join(bufs0)
+ bufs0.append(c0.compress(data0))
+ bufs0.append(c0.flush())
+ s0 = ''.join(bufs0)
- bufs1.append(c1.compress(data1))
- bufs1.append(c1.flush())
- s1 = ''.join(bufs1)
+ bufs1.append(c1.compress(data1))
+ bufs1.append(c1.flush())
+ s1 = ''.join(bufs1)
- self.assertEqual(zlib.decompress(s0),data0+data0)
- self.assertEqual(zlib.decompress(s1),data0+data1)
+ self.assertEqual(zlib.decompress(s0),data0+data0)
+ self.assertEqual(zlib.decompress(s1),data0+data1)
- def test_badcompresscopy(self):
- # Test copying a compression object in an inconsistent state
- c = zlib.compressobj()
- c.compress(HAMLET_SCENE)
- c.flush()
- self.assertRaises(ValueError, c.copy)
+ @requires_Compress_copy
+ def test_badcompresscopy(self):
+ # Test copying a compression object in an inconsistent state
+ c = zlib.compressobj()
+ c.compress(HAMLET_SCENE)
+ c.flush()
+ self.assertRaises(ValueError, c.copy)
def test_decompress_unused_data(self):
# Repeated calls to decompress() after EOF should accumulate data in
@@ -463,35 +471,36 @@
self.assertEqual(dco.unconsumed_tail, b'')
self.assertEqual(dco.unused_data, remainder)
- if hasattr(zlib.decompressobj(), "copy"):
- def test_decompresscopy(self):
- # Test copying a decompression object
- data = HAMLET_SCENE
- comp = zlib.compress(data)
+ @requires_Decompress_copy
+ def test_decompresscopy(self):
+ # Test copying a decompression object
+ data = HAMLET_SCENE
+ comp = zlib.compress(data)
- d0 = zlib.decompressobj()
- bufs0 = []
- bufs0.append(d0.decompress(comp[:32]))
+ d0 = zlib.decompressobj()
+ bufs0 = []
+ bufs0.append(d0.decompress(comp[:32]))
- d1 = d0.copy()
- bufs1 = bufs0[:]
+ d1 = d0.copy()
+ bufs1 = bufs0[:]
- bufs0.append(d0.decompress(comp[32:]))
- s0 = ''.join(bufs0)
+ bufs0.append(d0.decompress(comp[32:]))
+ s0 = ''.join(bufs0)
- bufs1.append(d1.decompress(comp[32:]))
- s1 = ''.join(bufs1)
+ bufs1.append(d1.decompress(comp[32:]))
+ s1 = ''.join(bufs1)
- self.assertEqual(s0,s1)
- self.assertEqual(s0,data)
+ self.assertEqual(s0,s1)
+ self.assertEqual(s0,data)
- def test_baddecompresscopy(self):
- # Test copying a compression object in an inconsistent state
- data = zlib.compress(HAMLET_SCENE)
- d = zlib.decompressobj()
- d.decompress(data)
- d.flush()
- self.assertRaises(ValueError, d.copy)
+ @requires_Decompress_copy
+ def test_baddecompresscopy(self):
+ # Test copying a compression object in an inconsistent state
+ data = zlib.compress(HAMLET_SCENE)
+ d = zlib.decompressobj()
+ d.decompress(data)
+ d.flush()
+ self.assertRaises(ValueError, d.copy)
# Memory use of the following functions takes into account overallocation
diff -r 3a1db0d2747e Lib/token.py
--- a/Lib/token.py
+++ b/Lib/token.py
@@ -1,5 +1,3 @@
-#! /usr/bin/env python
-
"""Token constants (from "token.h")."""
# This file is automatically generated; please don't muck it up!
diff -r 3a1db0d2747e Lib/tokenize.py
--- a/Lib/tokenize.py
+++ b/Lib/tokenize.py
@@ -26,6 +26,7 @@
__credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, '
'Skip Montanaro, Raymond Hettinger')
+from itertools import chain
import string, re
from token import *
@@ -184,17 +185,26 @@
def add_whitespace(self, start):
row, col = start
- assert row <= self.prev_row
+ if row < self.prev_row or row == self.prev_row and col < self.prev_col:
+ raise ValueError("start ({},{}) precedes previous end ({},{})"
+ .format(row, col, self.prev_row, self.prev_col))
+ row_offset = row - self.prev_row
+ if row_offset:
+ self.tokens.append("\\\n" * row_offset)
+ self.prev_col = 0
col_offset = col - self.prev_col
if col_offset:
self.tokens.append(" " * col_offset)
def untokenize(self, iterable):
- for t in iterable:
+ it = iter(iterable)
+ for t in it:
if len(t) == 2:
- self.compat(t, iterable)
+ self.compat(t, it)
break
tok_type, token, start, end, line = t
+ if tok_type == ENDMARKER:
+ break
self.add_whitespace(start)
self.tokens.append(token)
self.prev_row, self.prev_col = end
@@ -204,16 +214,12 @@
return "".join(self.tokens)
def compat(self, token, iterable):
- startline = False
indents = []
toks_append = self.tokens.append
- toknum, tokval = token
- if toknum in (NAME, NUMBER):
- tokval += ' '
- if toknum in (NEWLINE, NL):
- startline = True
+ startline = token[0] in (NEWLINE, NL)
prevstring = False
- for tok in iterable:
+
+ for tok in chain([token], iterable):
toknum, tokval = tok[:2]
if toknum in (NAME, NUMBER):
@@ -263,7 +269,7 @@
def generate_tokens(readline):
"""
- The generate_tokens() generator requires one argment, readline, which
+ The generate_tokens() generator requires one argument, readline, which
must be a callable object which provides the same interface as the
readline() method of built-in file objects. Each call to the function
should return one line of input as a string. Alternately, readline
diff -r 3a1db0d2747e Lib/traceback.py
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -189,11 +189,12 @@
if badline is not None:
lines.append(' %s\n' % badline.strip())
if offset is not None:
- caretspace = badline.rstrip('\n')[:offset].lstrip()
+ caretspace = badline.rstrip('\n')
+ offset = min(len(caretspace), offset) - 1
+ caretspace = caretspace[:offset].lstrip()
# non-space whitespace (likes tabs) must be kept for alignment
caretspace = ((c.isspace() and c or ' ') for c in caretspace)
- # only three spaces to account for offset1 == pos 0
- lines.append(' %s^\n' % ''.join(caretspace))
+ lines.append(' %s^\n' % ''.join(caretspace))
value = msg
lines.append(_format_final_exc_line(stype, value))
diff -r 3a1db0d2747e Lib/unittest/test/test_case.py
--- a/Lib/unittest/test/test_case.py
+++ b/Lib/unittest/test/test_case.py
@@ -293,7 +293,7 @@
def test(self):
pass
- self.assertTrue(Foo('test').failureException is AssertionError)
+ self.assertIs(Foo('test').failureException, AssertionError)
# "This class attribute gives the exception raised by the test() method.
# If a test framework needs to use a specialized exception, possibly to
@@ -311,7 +311,7 @@
failureException = RuntimeError
- self.assertTrue(Foo('test').failureException is RuntimeError)
+ self.assertIs(Foo('test').failureException, RuntimeError)
Foo('test').run(result)
@@ -334,7 +334,7 @@
failureException = RuntimeError
- self.assertTrue(Foo('test').failureException is RuntimeError)
+ self.assertIs(Foo('test').failureException, RuntimeError)
Foo('test').run(result)
@@ -607,7 +607,7 @@
msg = e.args[0]
else:
self.fail('assertSequenceEqual did not fail.')
- self.assertTrue(len(msg) < len(diff))
+ self.assertLess(len(msg), len(diff))
self.assertIn(omitted, msg)
self.maxDiff = len(diff) * 2
@@ -617,7 +617,7 @@
msg = e.args[0]
else:
self.fail('assertSequenceEqual did not fail.')
- self.assertTrue(len(msg) > len(diff))
+ self.assertGreater(len(msg), len(diff))
self.assertNotIn(omitted, msg)
self.maxDiff = None
@@ -627,7 +627,7 @@
msg = e.args[0]
else:
self.fail('assertSequenceEqual did not fail.')
- self.assertTrue(len(msg) > len(diff))
+ self.assertGreater(len(msg), len(diff))
self.assertNotIn(omitted, msg)
def testTruncateMessage(self):
diff -r 3a1db0d2747e Lib/unittest/test/test_loader.py
--- a/Lib/unittest/test/test_loader.py
+++ b/Lib/unittest/test/test_loader.py
@@ -1279,7 +1279,7 @@
# "The default value is the TestSuite class"
def test_suiteClass__default_value(self):
loader = unittest.TestLoader()
- self.assertTrue(loader.suiteClass is unittest.TestSuite)
+ self.assertIs(loader.suiteClass, unittest.TestSuite)
# Make sure the dotted name resolution works even if the actual
# function doesn't have the same name as is used to find it.
diff -r 3a1db0d2747e Lib/unittest/test/test_result.py
--- a/Lib/unittest/test/test_result.py
+++ b/Lib/unittest/test/test_result.py
@@ -176,7 +176,7 @@
self.assertEqual(result.shouldStop, False)
test_case, formatted_exc = result.failures[0]
- self.assertTrue(test_case is test)
+ self.assertIs(test_case, test)
self.assertIsInstance(formatted_exc, str)
# "addError(test, err)"
@@ -224,7 +224,7 @@
self.assertEqual(result.shouldStop, False)
test_case, formatted_exc = result.errors[0]
- self.assertTrue(test_case is test)
+ self.assertIs(test_case, test)
self.assertIsInstance(formatted_exc, str)
def testGetDescriptionWithoutDocstring(self):
diff -r 3a1db0d2747e Lib/urllib.py
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -1125,10 +1125,13 @@
global _portprog
if _portprog is None:
import re
- _portprog = re.compile('^(.*):([0-9]+)$')
+ _portprog = re.compile('^(.*):([0-9]*)$')
match = _portprog.match(host)
- if match: return match.group(1, 2)
+ if match:
+ host, port = match.groups()
+ if port:
+ return host, port
return host, None
_nportprog = None
@@ -1145,12 +1148,12 @@
match = _nportprog.match(host)
if match:
host, port = match.group(1, 2)
- try:
- if not port: raise ValueError, "no digits"
- nport = int(port)
- except ValueError:
- nport = None
- return host, nport
+ if port:
+ try:
+ nport = int(port)
+ except ValueError:
+ nport = None
+ return host, nport
return host, defport
_queryprog = None
diff -r 3a1db0d2747e Lib/urlparse.py
--- a/Lib/urlparse.py
+++ b/Lib/urlparse.py
@@ -109,10 +109,11 @@
netloc = self.netloc.split('@')[-1].split(']')[-1]
if ':' in netloc:
port = netloc.split(':')[1]
- port = int(port, 10)
- # verify legal port
- if (0 <= port <= 65535):
- return port
+ if port:
+ port = int(port, 10)
+ # verify legal port
+ if (0 <= port <= 65535):
+ return port
return None
from collections import namedtuple
diff -r 3a1db0d2747e Lib/uuid.py
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -293,25 +293,38 @@
def _find_mac(command, args, hw_identifiers, get_index):
import os
- for dir in ['', '/sbin/', '/usr/sbin']:
+ path = os.environ.get("PATH", os.defpath).split(os.pathsep)
+ path.extend(('/sbin', '/usr/sbin'))
+ for dir in path:
executable = os.path.join(dir, command)
- if not os.path.exists(executable):
- continue
+ if (os.path.exists(executable) and
+ os.access(executable, os.F_OK | os.X_OK) and
+ not os.path.isdir(executable)):
+ break
+ else:
+ return None
- try:
- # LC_ALL to get English output, 2>/dev/null to
- # prevent output on stderr
- cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
- with os.popen(cmd) as pipe:
- for line in pipe:
- words = line.lower().split()
- for i in range(len(words)):
- if words[i] in hw_identifiers:
+ try:
+ # LC_ALL to ensure English output, 2>/dev/null to
+ # prevent output on stderr
+ cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
+ with os.popen(cmd) as pipe:
+ for line in pipe:
+ words = line.lower().split()
+ for i in range(len(words)):
+ if words[i] in hw_identifiers:
+ try:
return int(
words[get_index(i)].replace(':', ''), 16)
- except IOError:
- continue
- return None
+ except (ValueError, IndexError):
+ # Virtual interfaces, such as those provided by
+ # VPNs, do not have a colon-delimited MAC address
+ # as expected, but a 16-byte HWAddr separated by
+ # dashes. These should be ignored in favor of a
+ # real MAC address
+ pass
+ except IOError:
+ pass
def _ifconfig_getnode():
"""Get the hardware address on Unix by running ifconfig."""
diff -r 3a1db0d2747e Lib/wave.py
--- a/Lib/wave.py
+++ b/Lib/wave.py
@@ -82,14 +82,15 @@
_array_fmts = None, 'b', 'h', None, 'i'
-# Determine endian-ness
import struct
-if struct.pack("h", 1) == "\000\001":
- big_endian = 1
-else:
- big_endian = 0
+import sys
+from chunk import Chunk
-from chunk import Chunk
+def _byteswap3(data):
+ ba = bytearray(data)
+ ba[::3] = data[2::3]
+ ba[2::3] = data[::3]
+ return bytes(ba)
class Wave_read:
"""Variables used in this class:
@@ -231,7 +232,7 @@
self._data_seek_needed = 0
if nframes == 0:
return ''
- if self._sampwidth > 1 and big_endian:
+ if self._sampwidth in (2, 4) and sys.byteorder == 'big':
# unfortunately the fromfile() method does not take
# something that only looks like a file object, so
# we have to reach into the innards of the chunk object
@@ -252,6 +253,8 @@
data = data.tostring()
else:
data = self._data_chunk.read(nframes * self._framesize)
+ if self._sampwidth == 3 and sys.byteorder == 'big':
+ data = _byteswap3(data)
if self._convert and data:
data = self._convert(data)
self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth)
@@ -419,14 +422,18 @@
nframes = len(data) // (self._sampwidth * self._nchannels)
if self._convert:
data = self._convert(data)
- if self._sampwidth > 1 and big_endian:
+ if self._sampwidth in (2, 4) and sys.byteorder == 'big':
import array
- data = array.array(_array_fmts[self._sampwidth], data)
+ a = array.array(_array_fmts[self._sampwidth])
+ a.fromstring(data)
+ data = a
assert data.itemsize == self._sampwidth
data.byteswap()
data.tofile(self._file)
self._datawritten = self._datawritten + len(data) * self._sampwidth
else:
+ if self._sampwidth == 3 and sys.byteorder == 'big':
+ data = _byteswap3(data)
self._file.write(data)
self._datawritten = self._datawritten + len(data)
self._nframeswritten = self._nframeswritten + nframes
diff -r 3a1db0d2747e Lib/weakref.py
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -20,7 +20,7 @@
ProxyType,
ReferenceType)
-from _weakrefset import WeakSet
+from _weakrefset import WeakSet, _IterationGuard
from exceptions import ReferenceError
@@ -48,10 +48,24 @@
def remove(wr, selfref=ref(self)):
self = selfref()
if self is not None:
- del self.data[wr.key]
+ if self._iterating:
+ self._pending_removals.append(wr.key)
+ else:
+ del self.data[wr.key]
self._remove = remove
+ # A list of keys to be removed
+ self._pending_removals = []
+ self._iterating = set()
UserDict.UserDict.__init__(self, *args, **kw)
+ def _commit_removals(self):
+ l = self._pending_removals
+ d = self.data
+ # We shouldn't encounter any KeyError, because this method should
+ # always be called *before* mutating the dict.
+ while l:
+ del d[l.pop()]
+
def __getitem__(self, key):
o = self.data[key]()
if o is None:
@@ -59,6 +73,11 @@
else:
return o
+ def __delitem__(self, key):
+ if self._pending_removals:
+ self._commit_removals()
+ del self.data[key]
+
def __contains__(self, key):
try:
o = self.data[key]()
@@ -77,8 +96,15 @@
return "<WeakValueDictionary at %s>" % id(self)
def __setitem__(self, key, value):
+ if self._pending_removals:
+ self._commit_removals()
self.data[key] = KeyedRef(value, self._remove, key)
+ def clear(self):
+ if self._pending_removals:
+ self._commit_removals()
+ self.data.clear()
+
def copy(self):
new = WeakValueDictionary()
for key, wr in self.data.items():
@@ -120,16 +146,18 @@
return L
def iteritems(self):
- for wr in self.data.itervalues():
- value = wr()
- if value is not None:
- yield wr.key, value
+ with _IterationGuard(self):
+ for wr in self.data.itervalues():
+ value = wr()
+ if value is not None:
+ yield wr.key, value
def iterkeys(self):
- return self.data.iterkeys()
+ with _IterationGuard(self):
+ for k in self.data.iterkeys():
+ yield k
- def __iter__(self):
- return self.data.iterkeys()
+ __iter__ = iterkeys
def itervaluerefs(self):
"""Return an iterator that yields the weak references to the values.
@@ -141,15 +169,20 @@
keep the values around longer than needed.
"""
- return self.data.itervalues()
+ with _IterationGuard(self):
+ for wr in self.data.itervalues():
+ yield wr
def itervalues(self):
- for wr in self.data.itervalues():
- obj = wr()
- if obj is not None:
- yield obj
+ with _IterationGuard(self):
+ for wr in self.data.itervalues():
+ obj = wr()
+ if obj is not None:
+ yield obj
def popitem(self):
+ if self._pending_removals:
+ self._commit_removals()
while 1:
key, wr = self.data.popitem()
o = wr()
@@ -157,6 +190,8 @@
return key, o
def pop(self, key, *args):
+ if self._pending_removals:
+ self._commit_removals()
try:
o = self.data.pop(key)()
except KeyError:
@@ -172,12 +207,16 @@
try:
wr = self.data[key]
except KeyError:
+ if self._pending_removals:
+ self._commit_removals()
self.data[key] = KeyedRef(default, self._remove, key)
return default
else:
return wr()
def update(self, dict=None, **kwargs):
+ if self._pending_removals:
+ self._commit_removals()
d = self.data
if dict is not None:
if not hasattr(dict, "items"):
@@ -245,9 +284,29 @@
def remove(k, selfref=ref(self)):
self = selfref()
if self is not None:
- del self.data[k]
+ if self._iterating:
+ self._pending_removals.append(k)
+ else:
+ del self.data[k]
self._remove = remove
- if dict is not None: self.update(dict)
+ # A list of dead weakrefs (keys to be removed)
+ self._pending_removals = []
+ self._iterating = set()
+ if dict is not None:
+ self.update(dict)
+
+ def _commit_removals(self):
+ # NOTE: We don't need to call this method before mutating the dict,
+ # because a dead weakref never compares equal to a live weakref,
+ # even if they happened to refer to equal objects.
+ # However, it means keys may already have been removed.
+ l = self._pending_removals
+ d = self.data
+ while l:
+ try:
+ del d[l.pop()]
+ except KeyError:
+ pass
def __delitem__(self, key):
del self.data[ref(key)]
@@ -306,10 +365,11 @@
return L
def iteritems(self):
- for wr, value in self.data.iteritems():
- key = wr()
- if key is not None:
- yield key, value
+ with _IterationGuard(self):
+ for wr, value in self.data.iteritems():
+ key = wr()
+ if key is not None:
+ yield key, value
def iterkeyrefs(self):
"""Return an iterator that yields the weak references to the keys.
@@ -321,19 +381,23 @@
keep the keys around longer than needed.
"""
- return self.data.iterkeys()
+ with _IterationGuard(self):
+ for wr in self.data.iterkeys():
+ yield wr
def iterkeys(self):
- for wr in self.data.iterkeys():
- obj = wr()
- if obj is not None:
- yield obj
+ with _IterationGuard(self):
+ for wr in self.data.iterkeys():
+ obj = wr()
+ if obj is not None:
+ yield obj
- def __iter__(self):
- return self.iterkeys()
+ __iter__ = iterkeys
def itervalues(self):
- return self.data.itervalues()
+ with _IterationGuard(self):
+ for value in self.data.itervalues():
+ yield value
def keyrefs(self):
"""Return a list of weak references to the keys.
diff -r 3a1db0d2747e Lib/xml/etree/ElementInclude.py
--- a/Lib/xml/etree/ElementInclude.py
+++ b/Lib/xml/etree/ElementInclude.py
@@ -75,14 +75,13 @@
# @throws IOError If the loader fails to load the resource.
def default_loader(href, parse, encoding=None):
- file = open(href)
- if parse == "xml":
- data = ElementTree.parse(file).getroot()
- else:
- data = file.read()
- if encoding:
- data = data.decode(encoding)
- file.close()
+ with open(href) as file:
+ if parse == "xml":
+ data = ElementTree.parse(file).getroot()
+ else:
+ data = file.read()
+ if encoding:
+ data = data.decode(encoding)
return data
##
diff -r 3a1db0d2747e Lib/xmlrpclib.py
--- a/Lib/xmlrpclib.py
+++ b/Lib/xmlrpclib.py
@@ -1617,21 +1617,14 @@
if __name__ == "__main__":
- # simple test program (from the XML-RPC specification)
-
- # server = ServerProxy("http://localhost:8000") # local server
- server = ServerProxy("http://time.xmlrpc.com/RPC2")
+ server = ServerProxy("http://localhost:8000")
print server
- try:
- print server.currentTime.getCurrentTime()
- except Error, v:
- print "ERROR", v
-
multi = MultiCall(server)
- multi.currentTime.getCurrentTime()
- multi.currentTime.getCurrentTime()
+ multi.pow(2, 9)
+ multi.add(5, 1)
+ multi.add(24, 11)
try:
for response in multi():
print response
diff -r 3a1db0d2747e Lib/zipfile.py
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -606,7 +606,11 @@
"""Returns buffered bytes without advancing the position."""
if n > len(self._readbuffer) - self._offset:
chunk = self.read(n)
- self._offset -= len(chunk)
+ if len(chunk) > self._offset:
+ self._readbuffer = chunk + self._readbuffer[self._offset:]
+ self._offset = 0
+ else:
+ self._offset -= len(chunk)
# Return up to 512 bytes to reduce allocation overhead for tight loops.
return self._readbuffer[self._offset: self._offset + 512]
@@ -918,10 +922,10 @@
@comment.setter
def comment(self, comment):
# check for valid comment length
- if len(comment) >= ZIP_MAX_COMMENT:
- if self.debug:
- print('Archive comment is too long; truncating to %d bytes'
- % ZIP_MAX_COMMENT)
+ if len(comment) > ZIP_MAX_COMMENT:
+ import warnings
+ warnings.warn('Archive comment is too long; truncating to %d bytes'
+ % ZIP_MAX_COMMENT, stacklevel=2)
comment = comment[:ZIP_MAX_COMMENT]
self._comment = comment
self._didModify = True
@@ -1084,8 +1088,8 @@
def _writecheck(self, zinfo):
"""Check for errors before writing a file to the archive."""
if zinfo.filename in self.NameToInfo:
- if self.debug: # Warning for duplicate names
- print "Duplicate name:", zinfo.filename
+ import warnings
+ warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
if self.mode not in ("w", "a"):
raise RuntimeError, 'write() requires mode "w" or "a"'
if not self.fp:
diff -r 3a1db0d2747e Mac/IDLE/Info.plist.in
--- a/Mac/IDLE/Info.plist.in
+++ b/Mac/IDLE/Info.plist.in
@@ -36,7 +36,7 @@
<key>CFBundleExecutable</key>
<string>IDLE</string>
<key>CFBundleGetInfoString</key>
- <string>%VERSION%, © 2001-2013 Python Software Foundation</string>
+ <string>%VERSION%, © 2001-2014 Python Software Foundation</string>
<key>CFBundleIconFile</key>
<string>IDLE.icns</string>
<key>CFBundleIdentifier</key>
diff -r 3a1db0d2747e Mac/Modules/carbonevt/_CarbonEvtmodule.c
--- a/Mac/Modules/carbonevt/_CarbonEvtmodule.c
+++ b/Mac/Modules/carbonevt/_CarbonEvtmodule.c
@@ -1051,8 +1051,7 @@
_err = RemoveEventHandler(_self->ob_itself);
if (_err != noErr) return PyMac_Error(_err);
_self->ob_itself = NULL;
- Py_DECREF(_self->ob_callback);
- _self->ob_callback = NULL;
+ Py_CLEAR(_self->ob_callback);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
diff -r 3a1db0d2747e Mac/Modules/list/_Listmodule.c
--- a/Mac/Modules/list/_Listmodule.c
+++ b/Mac/Modules/list/_Listmodule.c
@@ -76,8 +76,7 @@
static void ListObj_dealloc(ListObject *self)
{
- Py_XDECREF(self->ob_ldef_func);
- self->ob_ldef_func = NULL;
+ Py_CLEAR(self->ob_ldef_func);
SetListRefCon(self->ob_itself, (long)0);
if (self->ob_must_be_disposed && self->ob_itself) LDispose(self->ob_itself);
self->ob_type->tp_free((PyObject *)self);
diff -r 3a1db0d2747e Mac/PythonLauncher/Info.plist.in
--- a/Mac/PythonLauncher/Info.plist.in
+++ b/Mac/PythonLauncher/Info.plist.in
@@ -40,7 +40,7 @@
<key>CFBundleExecutable</key>
<string>PythonLauncher</string>
<key>CFBundleGetInfoString</key>
- <string>%VERSION%, © 2001-2013 Python Software Foundation</string>
+ <string>%VERSION%, © 2001-2014 Python Software Foundation</string>
<key>CFBundleIconFile</key>
<string>PythonLauncher.icns</string>
<key>CFBundleIdentifier</key>
diff -r 3a1db0d2747e Mac/README
--- a/Mac/README
+++ b/Mac/README
@@ -81,6 +81,13 @@
$ ./configure --enable-universalsdk=/
+In general, universal builds depend on specific features provided by the
+Apple-supplied compilers and other build tools included in Apple's Xcode
+development tools. You should install Xcode and the command line tools
+component appropriate for the OS X release you are running on. See the
+Python Developer's Guide (http://docs.python.org/devguide/setup.html)
+for more information.
+
2.1 Flavours of universal binaries
..................................
diff -r 3a1db0d2747e Mac/Resources/app/Info.plist.in
--- a/Mac/Resources/app/Info.plist.in
+++ b/Mac/Resources/app/Info.plist.in
@@ -20,7 +20,7 @@
<key>CFBundleExecutable</key>
<string>Python</string>
<key>CFBundleGetInfoString</key>
- <string>%version%, (c) 2004-2013 Python Software Foundation.</string>
+ <string>%version%, (c) 2004-2014 Python Software Foundation.</string>
<key>CFBundleHelpBookFolder</key>
<array>
<string>Documentation</string>
@@ -37,7 +37,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
- <string>%version%, (c) 2004-2013 Python Software Foundation.</string>
+ <string>%version%, (c) 2004-2014 Python Software Foundation.</string>
<key>CFBundleName</key>
<string>Python</string>
<key>CFBundlePackageType</key>
@@ -55,7 +55,7 @@
<key>NSAppleScriptEnabled</key>
<true/>
<key>NSHumanReadableCopyright</key>
- <string>(c) 2013 Python Software Foundation.</string>
+ <string>(c) 2014 Python Software Foundation.</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
diff -r 3a1db0d2747e Mac/Resources/framework/Info.plist.in
--- a/Mac/Resources/framework/Info.plist.in
+++ b/Mac/Resources/framework/Info.plist.in
@@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>%VERSION%, (c) 2004-2013 Python Software Foundation.</string>
+ <string>%VERSION%, (c) 2004-2014 Python Software Foundation.</string>
<key>CFBundleLongVersionString</key>
- <string>%VERSION%, (c) 2004-2013 Python Software Foundation.</string>
+ <string>%VERSION%, (c) 2004-2014 Python Software Foundation.</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff -r 3a1db0d2747e Makefile.pre.in
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -750,7 +750,8 @@
Include/warnings.h \
Include/weakrefobject.h \
pyconfig.h \
- $(PARSER_HEADERS)
+ $(PARSER_HEADERS) \
+ $(AST_H)
$(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
@@ -930,7 +931,9 @@
PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages
LIBSUBDIRS= lib-tk lib-tk/test lib-tk/test/test_tkinter \
lib-tk/test/test_ttk site-packages test test/audiodata test/data \
- test/cjkencodings test/decimaltestdata test/xmltestdata test/subprocessdata \
+ test/cjkencodings test/decimaltestdata test/xmltestdata \
+ test/imghdrdata \
+ test/subprocessdata \
test/tracedmodules \
encodings compiler hotshot \
email email/mime email/test email/test/data \
@@ -939,7 +942,8 @@
logging bsddb bsddb/test csv importlib wsgiref \
lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \
lib2to3/tests/data lib2to3/tests/data/fixers lib2to3/tests/data/fixers/myfixes \
- ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
+ ctypes ctypes/test ctypes/macholib \
+ idlelib idlelib/Icons idlelib/idle_test \
distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
multiprocessing multiprocessing/dummy \
unittest unittest/test \
diff -r 3a1db0d2747e Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1,4 +1,3 @@
-
Acknowledgements
----------------
@@ -14,39 +13,53 @@
Aahz
Michael Abbott
+Rajiv Abraham
David Abrahams
+Marc Abramowitz
+Ron Adam
+Ali Afshar
Jim Ahlstrom
Farhan Ahmad
+Matthew Ahrens
Nir Aides
Yaniv Aknin
Jyrki Alakuijala
Steve Alexander
Fred Allen
+Ray Allen
Billy G. Allie
Kevin Altis
Joe Amenta
A. Amoroso
Mark Anacker
+Shashwat Anand
Anders Andersen
John Anderson
Pehr Anderson
Erik Andersén
Oliver Andrich
Ross Andrus
+Juancarlo Añez
+Chris Angelico
+Jérémy Anger
Ankur Ankan
+Jon Anglin
Heidi Annexstad
+Ramchandra Apte
Éric Araujo
+Alicia Arlen
Jeffrey Armstrong
Jason Asbahr
David Ascher
Chris AtLee
+Aymeric Augustin
John Aycock
-Jan-Hein Bührman
Donovan Baarda
Arne Babenhauserheide
Attila Babo
+Matt Bachmann
+Marcin Bachry
Alfonso Baciero
-Marcin Bachry
Dwayne Bailey
Stig Bakken
Greg Ball
@@ -54,53 +67,66 @@
Jeff Balogh
Manuel Balsera
Matt Bandy
+Dmi Baranov
Michael J. Barber
Daniel Barclay
+Nicolas Bareil
Chris Barker
Anton Barkovsky
Nick Barnes
Quentin Barnes
+David Barnett
Matthew Barnett
Richard Barran
Cesar Eduardo Barros
Des Barry
Ulf Bartelt
Don Bashford
+Pior Bastida
Nick Bastin
Ned Batchelder
Jeff Bauer
-Mike Bayer
Michael R Bax
Anthony Baxter
+Mike Bayer
Samuel L. Bayer
Donald Beaudry
David Beazley
+Neal Becker
Robin Becker
-Neal Becker
Torsten Becker
Bill Bedford
+Stefan Behnel
Reimer Behrends
Ben Bell
Thomas Bellman
Alexander “Саша” Belopolsky
+Eli Bendersky
David Benjamin
Oscar Benjamin
Andrew Bennetts
Andy Bensky
Bennett Benson
+Ezra Berch
Michel Van den Bergh
+Julian Berman
+Brice Berna
+Olivier Bernard
Eric Beser
Steven Bethard
Stephen Bevan
Ron Bickers
Natalia B. Bidart
+Adrian von Bidder
David Binger
Dominic Binks
Philippe Biondi
Michael Birtwell
Stuart Bishop
Roy Bixler
+Daniel Black
Jonathan Black
+Renaud Blanch
Mike Bland
Martin Bless
Pablo Bleyer
@@ -113,9 +139,13 @@
David Bolen
Wouter Bolsterlee
Gawain Bolton
+Forest Bond
Gregory Bond
+Matias Bordese
+Jonas Borgström
Jurjen Bos
Peter Bosch
+Dan Boswell
Eric Bouck
Thierry Bousch
Sebastian Boving
@@ -126,44 +156,58 @@
Georg Brandl
Christopher Brannon
Terrence Brannon
+Germán M. Bravo
+Sven Brauch
Erik Bray
Brian Brazil
+Demian Brecht
Dave Brennan
Tom Bridgman
+Anthony Briggs
Keith Briggs
+Tobias Brink
Richard Brodie
Michael Broghton
Daniel Brotsky
Jean Brouwers
Gary S. Brown
+Titus Brown
Oleg Broytmann
Dave Brueck
Francisco Martín Brugué
Ian Bruntlett
+Floris Bruynooghe
+Matt Bryant
Stan Bubrouski
Erik de Bueger
+Jan-Hein Bührman
+Lars Buitinck
Dick Bulterman
Bill Bumgarner
Jimmy Burgett
+Edmond Burnett
Tommy Burnette
Roger Burnham
Alastair Burt
Tarn Weisner Burton
Lee Busby
Ralph Butler
+Nicolas Cadou
Jp Calderone
Arnaud Calmettes
Daniel Calvelo
Tony Campbell
Brett Cannon
Mike Carlton
+Pierre Carrier
Terry Carroll
-Damien Cassou
+Edward Catmur
Lorenzo M. Catucci
Donn Cave
Charles Cazabon
Jesús Cea Avión
Per Cederqvist
+Matej Cepl
Carl Cerecke
Octavian Cerna
Dave Chambers
@@ -171,13 +215,16 @@
John Chandler
Hye-Shik Chang
Jeffrey Chang
+Godefroid Chapelle
+Brad Chapman
+Greg Chapman
Mitch Chapman
-Greg Chapman
-Brad Chapman
Yogesh Chaudhari
David Chaum
Nicolas Chauvat
+Jerry Chen
Michael Chermside
+Ingrid Cheung
Albert Chin-A-Young
Adal Chiriliuc
Matt Chisholm
@@ -188,21 +235,30 @@
David Cinege
Craig Citro
Gilles Civario
+Chris Clark
+Laurie Clark-Michalek
Mike Clarkson
Andrew Clegg
Brad Clements
+Robbie Clemons
Steve Clift
+Hervé Coatanhay
Nick Coghlan
Josh Cogliati
Dave Cole
+Terrence Cole
Benjamin Collar
Jeffery Collins
Robert Collins
Paul Colomiets
+Christophe Combelles
Geremy Condra
+Denver Coneybeare
+Phil Connell
Juan José Conti
Matt Conway
David M. Cooke
+Jason R. Coombs
Garrett Cooper
Greg Copeland
Aldo Cortesi
@@ -224,8 +280,10 @@
Joaquin Cuenca Abela
John Cugini
Tom Culliton
+Antonio Cuni
Brian Curtin
Lisandro Dalcin
+Darren Dale
Andrew Dalke
Lars Damerow
Evan Dandrea
@@ -234,35 +292,45 @@
Ben Darnell
Kushal Das
Jonathan Dasteel
+Pierre-Yves David
A. Jesse Jiryu Davis
+Merlijn van Deen
John DeGood
Ned Deily
Vincent Delft
Arnaud Delobelle
+Konrad Delong
Erik Demaine
John Dennis
L. Peter Deutsch
Roger Dev
Philippe Devalkeneer
Raghuram Devarakonda
+Caleb Deveraux
Catherine Devlin
Scott Dial
Toby Dickenson
Mark Dickinson
Jack Diederich
Daniel Diniz
+Humberto Diogenes
Yves Dionne
Daniel Dittmar
+Josip Djolonga
Jaromir Dolecek
Ismail Donmez
Robert Donohue
Marcos Donolo
Dima Dorfman
+Yves Dorfsman
Cesar Douady
Dean Draayer
Fred L. Drake, Jr.
+Derk Drukker
John DuBois
Paul Dubois
+Jacques Ducasse
+Andrei Dorian Duma
Graham Dumpleton
Quinn Dunkan
Robin Dunn
@@ -276,36 +344,52 @@
Maxim Dzumanenko
Walter Dörwald
Hans Eckardt
+Rodolpho Eckhardt
+Ulrich Eckhardt
David Edelsohn
+John Edmonds
Grant Edwards
John Ehresman
+Tal Einat
Eric Eisner
Andrew Eland
+Julien Élie
Lance Ellinghaus
+Daniel Ellis
+Phil Elson
David Ely
Jeff Epler
Tom Epperly
+Gökcen Eraslan
Stoffel Erasmus
Jürgen A. Erhard
Michael Ernst
Ben Escoto
Andy Eskilsson
+André Espaze
Stefan Esser
+Nicolas Estibals
+Carey Evans
Stephen D Evans
-Carey Evans
Tim Everett
Paul Everitt
David Everly
Daniel Evers
+Winston Ewert
Greg Ewing
Martijn Faassen
Clovis Fabricio
Andreas Faerber
Bill Fancher
+Michael Farrell
Troy J. Farrell
Mark Favas
+Boris Feld
+Thomas Fenzl
Niels Ferguson
Sebastian Fernandez
+Florian Festi
+John Feuerstein
Carl Feynman
Vincent Fiack
Tomer Filiba
@@ -322,16 +406,20 @@
Amaury Forgeot d'Arc
Doug Fort
John Fouhy
+Andrew Francis
Stefan Franke
Martin Franklin
+Kent Frazier
Bruce Frederiksen
Robin Friedrich
Bradley Froehle
Ivan Frohne
+Matthias Fuchs
Jim Fulton
Tadayoshi Funaba
Gyro Funch
Peter Funk
+Ethan Furman
Geoff Furnish
Ulisses Furquim
Hagen Fürstenau
@@ -343,6 +431,7 @@
Yitzchak Gale
Matthew Gallagher
Quentin Gallet-Gilles
+Riccardo Attilio Galli
Raymund Galvin
Nitin Ganatra
Fred Gansevles
@@ -356,15 +445,23 @@
Thomas Gellekum
Gabriel Genellina
Christos Georgiou
+Elazar Gershuni
Ben Gertzfield
Nadim Ghaznavi
Dinu Gherman
Jonathan Giddy
Johannes Gijsbers
Michael Gilfix
+Julian Gindi
+Yannick Gingras
+Matt Giuca
Wim Glenn
+Michael Goderbauer
+Jeroen Van Goey
Christoph Gohlke
Tim Golden
+Guilherme Gonçalves
+Tiago Gonçalves
Chris Gonnerman
Shelley Gooch
David Goodger
@@ -372,15 +469,18 @@
Nathaniel Gray
Eddy De Greef
Grant Griffin
+Andrea Griffini
Duncan Grisby
Fabian Groffen
-John S. Gruber
+Eric Groo
Dag Gruneau
Filip Gruszczyński
Thomas Guettler
+Anuj Gupta
Michael Guravage
Lars Gustäbel
Thomas Güttler
+Jonas H.
Barry Haddow
Philipp Hagemeister
Paul ten Hagen
@@ -388,9 +488,11 @@
Peter Haight
Václav Haisman
Zbigniew Halas
+Walker Hale IV
Bob Halley
Jesse Hallio
Jun Hamano
+Alexandre Hamelin
Anders Hammarquist
Mark Hammond
Harald Hanche-Olsen
@@ -401,6 +503,8 @@
Lynda Hardman
Derek Harland
Jason Harper
+Brian Harring
+Jonathan Hartley
Travis B. Hartwell
Larry Hastings
Tim Hatch
@@ -409,12 +513,14 @@
Rycharde Hawkes
Ben Hayden
Jochen Hayek
+Tim Heaney
Henrik Heimbuerger
Christian Heimes
Thomas Heller
Malte Helmert
Lance Finn Helsten
Jonathan Hendry
+Michael Henry
James Henstridge
Kasun Herath
Chris Herborth
@@ -427,6 +533,7 @@
Magnus L. Hetland
Raymond Hettinger
Kevan Heydon
+Kelsey Hightower
Jason Hildebrand
Richie Hindle
Konrad Hinsen
@@ -445,6 +552,7 @@
Gerrit Holl
Shane Holloway
Rune Holm
+Thomas Holmes
Philip Homburg
Naofumi Honda
Jeffrey Honig
@@ -453,85 +561,111 @@
Brian Hooper
Randall Hopper
Nadav Horesh
+Alon Horev
Jan Hosang
+Alan Hourihane
Ken Howard
Brad Howes
Mike Hoy
Chih-Hao Huang
+Christian Hudon
Lawrence Hudson
Michael Hudson
Jim Hugunin
Greg Humphreys
Eric Huss
+Nehal Hussain
+Taihyun Hwang
Jeremy Hylton
Ludwig Hähne
Gerhard Häring
Fredrik Håård
Catalin Iacob
Mihai Ibanescu
+Ali Ikinci
+Aaron Iles
Lars Immisch
Bobby Impollonia
Meador Inge
+Peter Ingebretson
Tony Ingraldi
John Interrante
Bob Ippolito
Roger Irwin
Atsuo Ishimoto
+Adam Jackson
+Ben Jackson
Paul Jackson
-Ben Jackson
Manuel Jacob
David Jacobs
Kevin Jacobs
Kjetil Jacobsen
+Bertrand Janin
Geert Jansen
Jack Jansen
Bill Janssen
Thomas Jarosch
+Juhana Jauhiainen
Rajagopalasarma Jayakrishnan
+Zbigniew Jędrzejewski-Szmek
+Julien Jehannet
Drew Jenkins
Flemming Kjær Jensen
Philip H. Jensen
Philip Jenvey
+MunSic Jeong
Chris Jerdonek
-Jiba
+Jim Jewett
Pedro Diaz Jimenez
Orjan Johansen
Fredrik Johansson
Gregory K. Johnson
Kent Johnson
+Michael Johnson
Simon Johnston
+Matt Joiner
+Thomas Jollans
Nicolas Joly
+Brian K. Jones
Evan Jones
Jeremy Jones
Richard Jones
Irmen de Jong
Lucas de Jonge
+Kristján Valur Jónsson
+Jens B. Jorgensen
John Jorgensen
-Jens B. Jorgensen
Sijin Joseph
Andreas Jung
Tattoo Mabonzo K.
Sarah K.
+Sunny K
Bohuslav Kabrda
+Alexey Kachayev
Bob Kahn
Kurt B. Kaiser
Tamito Kajiyama
+Jan Kaliszewski
Peter van Kampen
+Rafe Kaplan
Jacob Kaplan-Moss
-Piotr Kasprzyk
+Janne Karila
+Per Øyvind Karlsen
Anton Kasyanov
Lou Kates
Hiroaki Kawai
Sebastien Keim
Ryan Kelly
+Dan Kenigsberg
+Randall Kern
Robert Kern
-Randall Kern
Jim Kerr
Magnus Kessler
Lawrence Kesteloot
-Rafe Kettler
Vivek Khera
+Dhiru Kholia
Mads Kiilerich
+Jason Killen
Jan Kim
Taek Joo Kim
W. Trevor King
@@ -541,6 +675,7 @@
Kamil Kisiel
Akira Kitada
Ron Klatchko
+Reid Kleckner
Bastian Kleineidam
Bob Kline
Matthias Klose
@@ -550,12 +685,17 @@
Lenny Kneler
Pat Knight
Jeff Knupp
+Kubilay Kocak
Greg Kochanski
Damon Kohler
Marko Kohtala
Vajrasky Kok
Guido Kollerie
+Jacek Konieczny
+Марк Коренберг
+Arkady Koplyarov
Peter A. Koren
+Vlad Korolev
Joseph Koshy
Daniel Kozan
Jerzy Kozera
@@ -567,34 +707,45 @@
Michael Kremer
Fabian Kreutz
Cédric Krier
+Pedro Kroger
Hannu Krosing
Andrej Krpic
Ivan Krstić
Steven Kryskalla
Andrew Kuchling
-Ralf W. Grosse-Kunstleve
Dave Kuhlman
+Jon Kuhn
+Toshio Kuratomi
Vladimir Kushnir
Erno Kuusela
-Kirill Kuzminykh (Кирилл Кузьминых)
Ross Lagerwall
Cameron Laird
+David Lam
Thomas Lamb
+Valerie Lambert
+Jean-Baptiste "Jiba" Lamy
+Ronan Lamy
Torsten Landschoff
Łukasz Langa
Tino Lange
+Glenn Langford
Andrew Langmead
Detlef Lannert
Soren Larsen
+Amos Latteier
Piers Lauder
Ben Laurie
Simon Law
+Julia Lawall
Chris Lawrence
Brian Leair
+Mathieu Leduc-Hamel
+Christopher Lee
+Inyeol Lee
+James Lee
John J. Lee
-Inyeol Lee
Thomas Lee
-Christopher Lee
+Tennessee Leeuwenburg
Luc Lefebvre
Pierre Paul Lefebvre
Glyph Lefkowitz
@@ -609,14 +760,20 @@
Mateusz Lenik
John Lenton
Kostyantyn Leschenko
+Benno Leslie
Christopher Tur Lesniewski-Laas
+Alain Leufroy
Mark Levinson
+Mark Levitt
William Lewis
+Akira Li
Xuanji Li
Robert van Liere
Ross Light
Shawn Ligocki
Martin Ligr
+Gediminas Liktaras
+Grant Limberg
Christopher Lindblad
Ulf A. Lindgren
Björn Lindqvist
@@ -627,47 +784,63 @@
Mirko Liss
Nick Lockwood
Stephanie Lockwood
+Hugo Lopes Tavares
Anne Lord
Tom Loredo
Justin Love
+Ned Jackson Lovely
Jason Lowe
Tony Lownds
Ray Loyzaga
+Kang-Hao (Kenny) Lu
Lukas Lueg
Loren Luke
Fredrik Lundh
Zhongyue Luo
Mark Lutz
+Taras Lyapun
Jim Lynch
Mikael Lyngvig
Martin von Löwis
-Till Maas
+Guillermo López-Anglada
Jeff MacDonald
John Machin
Andrew I MacIntyre
Tim MacKenzie
Nick Maclaren
+Don MacMillen
+Tomasz Maćkowiak
Steve Majewski
+Marek Majkowski
Grzegorz Makarewicz
David Malcolm
+Greg Malcolm
+William Mallard
Ken Manheimer
Vladimir Marangozov
+Colin Marc
Vincent Marchetti
David Marek
Doug Marien
Sven Marnach
Alex Martelli
Anthony Martin
+Owen Martin
Westley Martínez
Sébastien Martini
+Sidney San Martín
Roger Masse
Nick Mathewson
+Simon Mathieu
Laura Matson
Graham Matthews
Martin Matusiak
Dieter Maurer
Daniel May
+Madison May
+Lucas Maystre
Arnaud Mazin
+Matt McClure
Rebecca McCreary
Kirk McDonald
Chris McDonough
@@ -675,10 +848,11 @@
Alan McIntyre
Jessica McKellar
Michael McLay
+Brendan McLoughlin
Mark Mc Mahon
Gordon McMillan
+Andrew McNamara
Caolan McNamara
-Andrew McNamara
Jeff McNeil
Craig McPheeters
Lambert Meertens
@@ -691,38 +865,55 @@
Carl Meyer
Mike Meyer
Piotr Meyer
+Alexis Métaireau
Steven Miale
+Trent Mick
Jason Michalski
-Trent Mick
+Franck Michea
Tom Middleton
+Thomas Miedema
Stan Mihai
+Stefan Mihaila
Aristotelis Mikropoulos
Paolo Milani
+Chad Miller
Damien Miller
-Chad Miller
Jason V. Miller
Jay T. Miller
+Katie Miller
Roman Milner
+Julien Miotte
Andrii V. Mishkovskyi
+Dom Mitchell
Dustin J. Mitchell
-Dom Mitchell
+Zubin Mithra
Florian Mladitsch
Doug Moen
The Dragon De Monsyne
+Bastien Montagne
Skip Montanaro
+Peter Moody
Paul Moore
Ross Moore
+Ben Morgan
Derek Morr
James A Morrison
+Martin Morrison
+Derek McTavish Mounce
Alessandro Moura
Pablo Mouzo
+Mher Movsisyan
Ruslan Mstoi
+Valentina Mukhamedzhanova
+Michael Mulich
+Sape Mullender
Sjoerd Mullender
-Sape Mullender
Michael Muller
Neil Muller
+Louis Munro
R. David Murray
Matti Mäki
+Jörg Müller
Dale Nagata
John Nagle
Takahiro Nakayama
@@ -730,17 +921,18 @@
Charles-François Natali
Vilmos Nebehaj
Fredrik Nehr
+Tony Nelson
Trent Nelson
-Tony Nelson
Chad Netzer
Max Neunhöffer
George Neville-Neil
Hieu Nguyen
Johannes Nicolai
Samuel Nicolary
+Jonathan Niehof
Gustavo Niemeyer
Oscar Nierstrasz
-Hrvoje Niksic
+Hrvoje Nikšić
Gregory Nofi
Jesse Noller
Bill Noon
@@ -748,13 +940,19 @@
Tim Northover
Joe Norton
Neal Norwitz
+Mikhail Novikov
Michal Nowikowski
Steffen Daode Nurpmeso
Nigel O'Brian
+John O'Connor
Kevin O'Connor
Tim O'Malley
Zooko O'Whielacronx
+Aaron Oakley
+James Oakley
Elena Oat
+Jon Oberheide
+Milan Oberkirch
Pascal Oberndoerfer
Jeffrey Ollie
Adam Olsen
@@ -767,6 +965,7 @@
Michele Orrù
Oleg Oshmyan
Denis S. Otkidach
+Peter Otten
Michael Otteneder
R. M. Oudkerk
Russel Owen
@@ -778,6 +977,7 @@
Todd R. Palmer
Juan David Ibáñez Palomar
Jan Palus
+Mathias Panzenböck
M. Papillon
Peter Parente
Alexandre Parenteau
@@ -785,56 +985,82 @@
William Park
Heikki Partanen
Harri Pasanen
+Gaël Pasgrimaud
+Ashish Nitin Patil
Randy Pausch
Samuele Pedroni
+Justin Peel
Marcel van der Peijl
Berker Peksag
Andreas Pelme
Steven Pemberton
Bo Peng
Santiago Peresón
+George Peristerakis
+Mathieu Perreault
Mark Perrego
Trevor Perrin
Gabriel de Perthuis
Tim Peters
Benjamin Peterson
+Joe Peterson
Chris Petrilli
+Roumen Petrov
Bjorn Pettersen
Justin D. Pettit
+Esa Peuha
+Ronny Pfannschmidt
Geoff Philbrick
Gavrie Philipson
Adrian Phillips
Christopher J. Phoenix
Neale Pickett
-Matti Picus
Jim St. Pierre
Dan Pierson
Martijn Pieters
+Anand B. Pillai
François Pinard
Tom Pinckney
Zach Pincus
+Zero Piraeus
Michael Piotrowski
Antoine Pitrou
Jean-François Piéronne
Oleg Plakhotnyuk
+Remi Pointel
+Ariel Poliak
Guilherme Polo
+Illia Polosukhin
Michael Pomraning
+Martin Pool
Iustin Pop
+Claudiu Popa
John Popplewell
+Guillaume Pratte
Amrit Prem
Paul Prescod
Donovan Preston
+Paul Price
+Iuliia Proskurnia
+Jyrki Pulliainen
Steve Purcell
+Eduardo Pérez
Fernando Pérez
-Eduardo Pérez
+Pierre Quentel
Brian Quinlan
+Kevin Jing Qiu
Anders Qvist
Thomas Rachel
+Ram Rachum
+Jérôme Radix
Burton Radons
Jeff Ramnani
Brodie Rao
+Senko Rasic
Antti Rasinen
+Nikolaus Rath
Sridhar Ratnakumar
+Ysj Ray
Eric S. Raymond
Edward K. Ream
Chris Rebert
@@ -844,36 +1070,47 @@
Gareth Rees
Steve Reeves
Lennart Regebro
+John Regehr
+Federico Reghenzani
Ofir Reichenberg
Sean Reifschneider
Michael P. Reilly
Bernhard Reiter
Steven Reiz
Roeland Rengelink
+Antoine Reversat
+Flávio Ribeiro
+Francesco Ricciardi
Tim Rice
-Francesco Ricciardi
Jan Pieter Riegel
Armin Rigo
+Arc Riley
Nicholas Riley
Jean-Claude Rimbault
Vlad Riscutia
Wes Rishel
-Dan Riti
+Daniel Riti
Juan M. Bello Rivas
Davide Rizzo
Anthony Roach
Carl Robben
Mark Roberts
+Andy Robinson
Jim Robinson
-Andy Robinson
+Mark Roddy
Kevin Rodgers
+Sean Rodman
Giampaolo Rodola
+Elson Rodriguez
Adi Roiban
+Luis Rojas
Mike Romberg
Armin Ronacher
Case Roole
Timothy Roscoe
+Erik Rose
Jim Roskind
+Brian Rosner
Guido van Rossum
Just van Rossum
Hugo van Rossum
@@ -885,22 +1122,29 @@
Clinton Roy
Paul Rubin
Sam Ruby
+Demur Rumed
Audun S. Runde
Eran Rundstein
Rauli Ruohonen
Jeff Rush
Sam Rushing
Mark Russell
+Rusty Russell
Nick Russo
Chris Ryland
Constantina S.
+Patrick Sabin
Sébastien Sablé
Suman Saha
Hajime Saitou
George Sakkis
Rich Salz
Kevin Samborn
+Adrian Sampson
+James Sanders
Ilya Sandler
+Rafael Santos
+Simon Sapin
Mark Sapiro
Ty Sarna
Hugh Sasse
@@ -908,39 +1152,46 @@
Ben Sayer
sbt
Marco Scataglini
+Andrew Schaaf
Michael Scharf
+Andreas Schawo
Neil Schemenauer
David Scherer
+Wolfgang Scherer
Hynek Schlawack
+Bob Schmertz
Gregor Schmid
Ralf Schmitt
Michael Schneider
Peter Schneider-Kamp
Arvin Schnell
Scott Schram
+Robin Schreiber
Chad J. Schroeder
Christian Schubert
Sam Schulenburg
Stefan Schwarzer
Dietmar Schwertberger
Federico Schwindt
+Barry Scott
Steven Scott
-Barry Scott
Nick Seidenman
-Žiga Seilnach
+Žiga Seilnacht
Yury Selivanov
Fred Sells
Jiwon Seo
+Iñigo Serna
Joakim Sernbrant
-Roger Serwy
+Roger D. Serwy
Jerry Seutter
Pete Sevander
Denis Severson
Ian Seyer
-Aman Shah
+Daniel Shahaf
Ha Shao
Mark Shannon
Richard Shapiro
+Varun Sharma
Vlad Shcherbina
Justin Sheehy
Charlie Shepherd
@@ -950,18 +1201,18 @@
Michael Shiplett
John W. Shipman
Joel Shprentz
-Itamar Shtull-Trauring
Yue Shuaijie
Terrel Shumway
Eric Siegerman
Paul Sijben
+SilentGhost
Tim Silk
Michael Simcich
Ionel Simionescu
Kirill Simonov
Nathan Paul Simons
Guilherme Simões
-Kyle Simpson
+Adam Simpkins
Ravi Sinha
Janne Sinkkonen
Ng Pheng Siong
@@ -969,15 +1220,21 @@
J. Sipprell
Kragen Sitaker
Michael Sloan
+Nick Sloan
+Václav Šmilauer
+Christopher Smith
Eric V. Smith
-Christopher Smith
Gregory P. Smith
+Mark Smith
Roy Smith
+Ryan Smith-Roberts
Rafal Smotrzyk
+Eric Snow
Dirk Soede
Paul Sokolovsky
Evgeny Sologubov
Cody Somerville
+Edoardo Spadolini
Clay Spence
Stefan Sperling
Nicholas Spies
@@ -989,10 +1246,13 @@
Tage Stabell-Kulo
Quentin Stafford-Fraser
Frank Stajano
+Joel Stanley
Anthony Starks
Oliver Steele
Greg Stein
+Baruch Sterin
Chris Stern
+Alex Stewart
Victor Stinner
Richard Stoakley
Peter Stoehr
@@ -1000,28 +1260,34 @@
Michael Stone
Serhiy Storchaka
Ken Stox
-Patrick Strawderman
Dan Stromberg
+Donald Stufft
Daniel Stutzbach
Andreas Stührk
+Colin Su
+Pal Subbiah
Nathan Sullivan
Mark Summerfield
Reuben Sumner
+Marek Šuppa
Hisao Suzuki
+Kalle Svensson
Andrew Svetlov
-Kalle Svensson
Paul Swartz
Thenault Sylvain
Péter Szabó
Amir Szekely
Arfrever Frehtes Taifersar Arahesis
+Hideaki Takahashi
+Indra Talip
+Neil Tallim
Geoff Talvola
+Musashi Tamura
William Tanksley
Christian Tanzer
-Stefano Taschini
Steven Taschuk
+Amy Taylor
Monty Taylor
-Amy Taylor
Anatoly Techtonik
Mikhail Terekhov
Victor Terrón
@@ -1032,28 +1298,40 @@
Nicolas M. Thiéry
James Thomas
Robin Thomas
+Brian Thorne
Stephen Thorne
+Jeremy Thurgood
Eric Tiedemann
+July Tikhonov
Tracy Tims
Oren Tirosh
Jason Tishler
Christian Tismer
Jim Tittsler
Frank J. Tobin
+Bennett Todd
R Lindsay Todd
-Bennett Todd
Eugene Toder
+Erik Tollerud
+Stephen Tonkin
Matias Torchinsky
Sandro Tosi
Richard Townsend
+David Townshend
+Nathan Trapuzzano
Laurence Tratt
+Alberto Trevino
+Matthias Troffaes
Tom Tromey
John Tromp
+Diane Trout
Jason Trowbridge
Brent Tubbs
Anthony Tuininga
+Erno Tukia
David Turner
Stephen Turner
+Itamar Turner-Trauring
Theodore Turocy
Bill Tutt
Fraser Tweedale
@@ -1061,19 +1339,23 @@
Eren Türkay
Lionel Ulmer
Roger Upole
+Daniel Urban
Michael Urman
Hector Urtubia
Ville Vainio
Andi Vajda
Case Van Horsen
Kyle VanderBeek
+Andrew Vant
Atul Varma
Dmitry Vasiliev
Sebastian Ortiz Vasquez
Alexandre Vassalotti
+Nadeem Vawda
Frank Vercruesse
Mike Verdone
Jaap Vermeulen
+Nikita Vetoshkin
Al Vezza
Jacques A. Vidrine
John Viega
@@ -1081,22 +1363,28 @@
Kannan Vijayan
Kurt Vile
Norman Vine
+Pauli Virtanen
Frank Visser
Johannes Vogel
Alex Volkov
Martijn Vries
+Sjoerd de Vries
Niki W. Waibel
Wojtek Walczak
Charles Waldman
Richard Walker
Larry Wall
Kevin Walzer
+Rodrigo Steinmuller Wanderley
Ke Wang
Greg Ward
+Tom Wardill
Zachary Ware
+Jonas Wagner
Barry Warsaw
Steve Waterbury
Bob Watson
+David Watson
Aaron Watters
Henrik Weber
Corran Webster
@@ -1116,12 +1404,14 @@
Felix Wiemann
Gerry Wiener
Frank Wierzbicki
+Santoso Wijaya
Bryce "Zooko" Wilcox-O'Hearn
Timothy Wild
+Jakub Wilk
+Gerald S. Williams
Jason Williams
John Williams
Sue Williams
-Gerald S. Williams
Steven Willis
Frank Willison
Geoff Wilson
@@ -1137,25 +1427,30 @@
John Wiseman
Chris Withers
Stefan Witzel
+Irek Wlizlo
David Wolever
Klaus-Juergen Wolf
Dan Wolfe
Richard Wolff
Adam Woodbeck
Steven Work
+Gordon Worley
Darren Worrall
-Gordon Worley
Thomas Wouters
+Daniel Wozniak
Heiko Wundram
Doug Wyatt
Robert Xiao
Florent Xicluna
Hirokazu Yamamoto
Ka-Ping Yee
+Jason Yeo
+EungJun Yi
Bob Yodlowski
Danny Yoo
Rory Yorke
George Yoshida
+Kazuhiro Yoshida
Masazumi Yoshikawa
Arnaud Ysmal
Bernard Yue
@@ -1166,7 +1461,10 @@
Yury V. Zaytsev
Siebren van der Zee
Nickolai Zeldovich
+Yuxiao Zeng
Uwe Zessin
Cheng Zhang
+Kai Zhu
Tarek Ziadé
+Gennadiy Zlobin
Peter Åstrand
diff -r 3a1db0d2747e Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1,6 +1,337 @@
++++++++++++
Python News
+++++++++++
+What's New in Python 2.7.7?
+===========================
+
+*Release date: XXXX-XX-XX*
+
+Core and Builtins
+-----------------
+
+- Issue #20437: Fixed 43 potential bugs when deleting objects references.
+
+- Issue #20494: Ensure that free()d memory arenas are really released on POSIX
+ systems supporting anonymous memory mappings. Patch by Charles-François
+ Natali.
+
+- Issue #17825: Cursor "^" is correctly positioned for SyntaxError and
+ IndentationError.
+
+- Raise a better error when non-unicode codecs are used for a file's coding
+ cookie.
+
+- Issue #17976: Fixed potential problem with file.write() not detecting IO error
+ by inspecting the return value of fwrite(). Based on patches by Jaakko Moisio
+ and Victor Stinner.
+
+- Issue #14432: Generator now clears the borrowed reference to the thread
+ state. Fix a crash when a generator is created in a C thread that is
+ destroyed while the generator is still used. The issue was that a generator
+ contains a frame, and the frame kept a reference to the Python state of the
+ destroyed C thread. The crash occurs when a trace function is setup.
+
+- Issue #19932: Fix typo in import.h, missing whitespaces in function prototypes.
+
+- Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2
+ billion characters) input strings in _Py_dg_strtod.
+
+Library
+-------
+
+- Issue #20283: RE pattern methods now accept the string keyword parameters
+ as documented. The pattern and source keyword parameters are left as
+ deprecated aliases.
+
+- Issue #11599: When an external command (e.g. compiler) fails, distutils now
+ prints out the whole command line (instead of just the command name) if the
+ environment variable DISTUTILS_DEBUG is set.
+
+- Issue #4931: distutils should not produce unhelpful "error: None" messages
+ anymore. distutils.util.grok_environment_error is kept but doc-deprecated.
+
+- Improve the random module's default seeding to use 256 bits of entropy
+ from os.urandom(). This was already done for Python 3, mildly improving
+ security with a bigger seed space.
+
+- Issue #15618: Make turtle.py compatible with 'from __future__ import
+ unicode_literals'. Initial patch by Juancarlo Añez.
+
+- Issue #20501: fileinput module no longer reads whole file into memory when using
+ fileinput.hook_encoded.
+
+- Issue #6815: os.path.expandvars() now supports non-ASCII Unicode environment
+ variables names and values.
+
+- Issue #20635: Fixed grid_columnconfigure() and grid_rowconfigure() methods of
+ Tkinter widgets to work in wantobjects=True mode.
+
+- Issue #17671: Fixed a crash when use non-initialized io.BufferedRWPair.
+ Based on patch by Stephen Tu.
+
+- Issue #8478: Untokenizer.compat processes first token from iterator input.
+ Patch based on lines from Georg Brandl, Eric Snow, and Gareth Rees.
+
+- Issue #20594: Avoid name clash with the libc function posix_close.
+
+- Issue #19856: shutil.move() failed to move a directory to other directory
+ on Windows if source name ends with os.altsep.
+
+- Issue #14983: email.generator now always adds a line end after each MIME
+ boundary marker, instead of doing so only when there is an epilogue. This
+ fixes an RFC compliance bug and solves an issue with signed MIME parts.
+
+- Issue #20013: Some imap servers disconnect if the current mailbox is
+ deleted, and imaplib did not handle that case gracefully. Now it
+ handles the 'bye' correctly.
+
+- Issue #20426: When passing the re.DEBUG flag, re.compile() displays the
+ debug output every time it is called, regardless of the compilation cache.
+
+- Issue #20368: The null character now correctly passed from Tcl to Python (in
+ unicode strings only). Improved error handling in variables-related commands.
+
+- Issue #20435: Fix _pyio.StringIO.getvalue() to take into account newline
+ translation settings.
+
+- Issue #20288: fix handling of invalid numeric charrefs in HTMLParser.
+
+- Issue #19456: ntpath.join() now joins relative paths correctly when a drive
+ is present.
+
+- Issue #8260: The read(), readline() and readlines() methods of
+ codecs.StreamReader returned incomplete data when were called after
+ readline() or read(size). Based on patch by Amaury Forgeot d'Arc.
+
+- Issue #20374: Fix build with GNU readline >= 6.3.
+
+- Issue #14548: Make multiprocessing finalizers check pid before
+ running to cope with possibility of gc running just after fork.
+ (Backport from 3.x.)
+
+- Issue #20262: Warnings are raised now when duplicate names are added in the
+ ZIP file or too long ZIP file comment is truncated.
+
+- Issue #20270: urllib and urlparse now support empty ports.
+
+- Issue #20243: TarFile no longer raise ReadError when opened in write mode.
+
+- Issue #20245: The open functions in the tarfile module now correctly handle
+ empty mode.
+
+- Issue #20086: Restored the use of locale-independent mapping instead of
+ locale-dependent str.lower() in locale.normalize().
+
+- Issue #20246: Fix buffer overflow in socket.recvfrom_into.
+
+- Issue #19082: Working SimpleXMLRPCServer and xmlrpclib examples, both in
+ modules and documentation.
+
+- Issue #13107: argparse and optparse no longer raises an exception when output
+ a help on environment with too small COLUMNS. Based on patch by
+ Elazar Gershuni.
+
+- Issue #20207: Always disable SSLv2 except when PROTOCOL_SSLv2 is explicitly
+ asked for.
+
+- Issue #20072: Fixed multiple errors in tkinter with wantobjects is False.
+
+- Issue #1065986: pydoc can now handle unicode strings.
+
+- Issue #16039: CVE-2013-1752: Change use of readline in imaplib module to
+ limit line length. Patch by Emil Lind.
+
+- Issue #19422: Explicitly disallow non-SOCK_STREAM sockets in the ssl
+ module, rather than silently let them emit clear text data.
+
+- Issue #20027: Fixed locale aliases for devanagari locales.
+
+- Issue #20067: Tkinter variables now work when wantobjects is false.
+
+- Issue #19020: Tkinter now uses splitlist() instead of split() in configure
+ methods.
+
+- Issue #12226: HTTPS is now used by default when connecting to PyPI.
+
+- Issue #20048: Fixed ZipExtFile.peek() when it is called on the boundary of
+ the uncompress buffer and read() goes through more than one readbuffer.
+
+- Issue #20034: Updated alias mapping to most recent locale.alias file
+ from X.org distribution using makelocalealias.py.
+
+- Issue #5815: Fixed support for locales with modifiers. Fixed support for
+ locale encodings with hyphens.
+
+- Issue #20026: Fix the sqlite module to handle correctly invalid isolation
+ level (wrong type).
+
+- Issue #18829: csv.Dialect() now checks type for delimiter, escapechar and
+ quotechar fields. Original patch by Vajrasky Kok.
+
+- Issue #19855: uuid.getnode() on Unix now looks on the PATH for the
+ executables used to find the mac address, with /sbin and /usr/sbin as
+ fallbacks.
+
+- Issue #20007: HTTPResponse.read(0) no more prematurely closes connection.
+ Original patch by Simon Sapin.
+
+- Issue #19912: Fixed numerous bugs in ntpath.splitunc().
+
+- Issue #19623: Fixed writing to unseekable files in the aifc module.
+ Fixed writing 'ulaw' (lower case) compressed AIFC files.
+
+- Issue #17919: select.poll.register() again works with poll.POLLNVAL on AIX.
+ Fixed integer overflow in the eventmask parameter.
+
+- Issue #17200: telnetlib's read_until and expect timeout was broken by the
+ fix to Issue #14635 in Python 2.7.4 to be interpreted as milliseconds
+ instead of seconds when the platform supports select.poll (ie: everywhere).
+ It is now treated as seconds once again.
+
+- Issue #19099: The struct module now supports Unicode format strings.
+
+- Issue #19878: Fix segfault in bz2 module after calling __init__ twice with
+ non-existent filename. Initial patch by Vajrasky Kok.
+
+- Issue #16373: Prevent infinite recursion for ABC Set class comparisons.
+
+- Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows a match when
+ no exception detail exists (no colon following the exception's name, or
+ a colon does follow but no text follows the colon).
+
+- Issue #16231: Fixed pickle.Pickler to only fallback to its default pickling
+ behaviour when Pickler.persistent_id returns None, but not for any other
+ false values. This allows false values other than None to be used as
+ persistent IDs. This behaviour is consistent with cPickle.
+
+- Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with
+ virtual interface. Original patch by Kent Frazier.
+
+- Issue #11489: JSON decoder now accepts lone surrogates.
+
+- Fix test.test_support.bind_port() to not cause an error when Python was
+ compiled on a system with SO_REUSEPORT defined in the headers but run on
+ a system with an OS kernel that does not support that new socket option.
+
+- Issue #19633: Fixed writing not compressed 16- and 32-bit wave files on
+ big-endian platforms.
+
+- Issue #19449: in csv's writerow, handle non-string keys when generating the
+ error message that certain keys are not in the 'fieldnames' list.
+
+- Issue #12853: Fix NameError in distutils.command.upload.
+
+- Issue #19523: Closed FileHandler leak which occurred when delay was set.
+
+- Issue #1575020: Fixed support of 24-bit wave files on big-endian platforms.
+
+- Issue #19480: HTMLParser now accepts all valid start-tag names as defined
+ by the HTML5 standard.
+
+- Issue #17827: Add the missing documentation for ``codecs.encode`` and
+ ``codecs.decode``.
+
+- Issue #6157: Fixed Tkinter.Text.debug(). Original patch by Guilherme Polo.
+
+- Issue #6160: The bbox() method of tkinter.Spinbox now returns a tuple of
+ integers instead of a string. Based on patch by Guilherme Polo.
+
+- Issue #19286: Directories in ``package_data`` are no longer added to
+ the filelist, preventing failure outlined in the ticket.
+
+Tools/Demos
+-----------
+
+- Issue #19936: Added executable bits or shebang lines to Python scripts which
+ requires them. Disable executable bits and shebang lines in test and
+ benchmark files in order to prevent using a random system python, and in
+ source files of modules which don't provide command line interface.
+
+IDLE
+----
+
+- Issue #20406: Use Python application icons for Idle window title bars.
+ Patch mostly by Serhiy Storchaka.
+
+- Issue #17721: Remove non-functional configuration dialog help button until we
+ make it actually gives some help when clicked. Patch by Guilherme Simões.
+
+- Issue #17390: Add Python version to Idle editor window title bar.
+ Original patches by Edmond Burnett and Kent Johnson.
+
+- Issue #20058: sys.stdin.readline() in IDLE now always returns only one line.
+
+- Issue #19481: print() of unicode, str or bytearray subclass instance in IDLE
+ no more hangs.
+
+- Issue #18270: Prevent possible IDLE AttributeError on OS X when no initial
+ shell window is present.
+
+Tests
+-----
+
+- Issue #20946: Correct alignment assumptions of some ctypes tests.
+
+- Issue #20743: Fix a reference leak in test_tcl.
+
+- Issue #20510: Rewrote test_exit in test_sys to match existing comments,
+ use modern unittest features, and use helpers from test.script_helper
+ instead of using subprocess directly. Initial patch by Gareth Rees.
+
+- Issue #20532: Tests which use _testcapi now are marked as CPython only.
+
+- Issue #19920: Added tests for TarFile.list(). Based on patch by Vajrasky Kok.
+
+- Issue #19990: Added tests for the imghdr module. Based on patch by
+ Claudiu Popa.
+
+- Issue #19804: The test_find_mac test in test_uuid is now skipped if the
+ ifconfig executable is not available.
+
+- Issue #19886: Use better estimated memory requirements for bigmem tests.
+
+- Backported tests for Tkinter variables.
+
+- Issue #19320: test_tcl no longer fails when wantobjects is false.
+
+- Issue #19683: Removed empty tests from test_minidom. Initial patch by
+ Ajitesh Gupta.
+
+- Issue #19928: Implemented a test for repr() of cell objects.
+
+- Issue #19595, #19987: Re-enabled a long-disabled test in test_winsound.
+
+- Issue #19588: Fixed tests in test_random that were silently skipped most
+ of the time. Patch by Julian Gindi.
+
+- Issue #17883: Tweak test_tcl testLoadWithUNC to skip the test in the
+ event of a permission error on Windows and to properly report other
+ skip conditions.
+
+- Issue #17883: Backported _is_gui_available() in test.test_support to
+ avoid hanging Windows buildbots on test_ttk_guionly.
+
+- Issue #18702, #19572: All skipped tests now reported as skipped.
+
+- Issue #19085: Added basic tests for all tkinter widget options.
+
+- Issue #20605: Make test_socket getaddrinfo OS X segfault test more robust.
+
+- Issue #20939: Fix test_geturl failure in test_urllibnet due to
+ new redirect of http://www.python.org/ to https://www.python.org.
+
+Documentation
+-------------
+
+- Issue #20255: Update the about and bugs pages.
+
+- Issue #18840: Introduce the json module in the tutorial, and de-emphasize
+ the pickle module.
+
+- Issue #19795: Improved markup of True/False constants.
+
+
Whats' New in Python 2.7.6?
===========================
diff -r 3a1db0d2747e Modules/_bsddb.c
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -949,8 +949,7 @@
* DBTxns and closing any open DBs first. */
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# Copyright 1992-2013 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# Copyright 1992-2013 Free Software Foundation, Inc.