Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
8f374fd1
Commit
8f374fd1
authored
May 01, 2011
by
Éric Araujo
Browse files
Options
Browse Files
Download
Plain Diff
Branch merge
parents
4f25d149
5172db37
Changes
41
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
1040 additions
and
491 deletions
+1040
-491
Doc/c-api/exceptions.rst
Doc/c-api/exceptions.rst
+2
-0
Doc/c-api/init.rst
Doc/c-api/init.rst
+2
-2
Doc/c-api/object.rst
Doc/c-api/object.rst
+3
-0
Doc/documenting/markup.rst
Doc/documenting/markup.rst
+21
-4
Doc/howto/advocacy.rst
Doc/howto/advocacy.rst
+1
-1
Doc/library/argparse.rst
Doc/library/argparse.rst
+147
-139
Doc/library/collections.rst
Doc/library/collections.rst
+20
-0
Doc/library/configparser.rst
Doc/library/configparser.rst
+6
-4
Doc/library/logging.config.rst
Doc/library/logging.config.rst
+21
-7
Doc/library/multiprocessing.rst
Doc/library/multiprocessing.rst
+1
-1
Doc/library/signal.rst
Doc/library/signal.rst
+2
-0
Doc/library/subprocess.rst
Doc/library/subprocess.rst
+108
-4
Doc/library/sys.rst
Doc/library/sys.rst
+24
-0
Doc/library/urllib.rst
Doc/library/urllib.rst
+5
-5
Include/pystate.h
Include/pystate.h
+1
-0
Lib/anydbm.py
Lib/anydbm.py
+13
-11
Lib/collections.py
Lib/collections.py
+125
-105
Lib/distutils/command/sdist.py
Lib/distutils/command/sdist.py
+14
-11
Lib/getpass.py
Lib/getpass.py
+1
-1
Lib/subprocess.py
Lib/subprocess.py
+9
-2
Lib/tarfile.py
Lib/tarfile.py
+2
-0
Lib/test/string_tests.py
Lib/test/string_tests.py
+57
-0
Lib/test/test_bytes.py
Lib/test/test_bytes.py
+62
-0
Lib/test/test_collections.py
Lib/test/test_collections.py
+9
-0
Lib/test/test_pydoc.py
Lib/test/test_pydoc.py
+9
-1
Lib/test/test_startfile.py
Lib/test/test_startfile.py
+6
-0
Lib/test/test_str.py
Lib/test/test_str.py
+12
-1
Lib/test/test_tarfile.py
Lib/test/test_tarfile.py
+28
-0
Lib/test/test_unicode.py
Lib/test/test_unicode.py
+11
-0
Lib/test/test_zipfile.py
Lib/test/test_zipfile.py
+110
-112
Lib/unittest/case.py
Lib/unittest/case.py
+8
-0
Lib/unittest/test/test_case.py
Lib/unittest/test/test_case.py
+36
-0
Misc/ACKS
Misc/ACKS
+3
-0
Misc/NEWS
Misc/NEWS
+32
-0
Modules/signalmodule.c
Modules/signalmodule.c
+17
-10
Objects/bytearrayobject.c
Objects/bytearrayobject.c
+5
-8
Objects/stringlib/find.h
Objects/stringlib/find.h
+48
-19
Objects/stringobject.c
Objects/stringobject.c
+15
-20
Objects/unicodeobject.c
Objects/unicodeobject.c
+26
-22
Python/pystate.c
Python/pystate.c
+17
-0
Tools/pybench/pybench.py
Tools/pybench/pybench.py
+1
-1
No files found.
Doc/c-api/exceptions.rst
View file @
8f374fd1
...
...
@@ -347,6 +347,8 @@ is a separate error indicator for each thread.
error checking. *fd* should be a valid file descriptor. The function should
only be called from the main thread.
.. versionadded:: 2.6
.. cfunction:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)
...
...
Doc/c-api/init.rst
View file @
8f374fd1
...
...
@@ -474,7 +474,7 @@ the fork, and releasing them afterwards. In addition, it resets any
:ref:`lock-objects` in the child. When extending or embedding Python, there
is no way to inform Python of additional (non-Python) locks that need to be
acquired before or reset after a fork. OS facilities such as
:cfunc:`p
osix
_atfork` would need to be used to accomplish the same thing.
:cfunc:`p
thread
_atfork` would need to be used to accomplish the same thing.
Additionally, when extending or embedding Python, calling :cfunc:`fork`
directly rather than through :func:`os.fork` (and returning to or calling
into Python) may result in a deadlock by one of Python's internal locks
...
...
@@ -906,7 +906,7 @@ a worker thread and the actual call than made at the earliest convenience by the
main thread where it has possession of the global interpreter lock and can
perform any Python API calls.
.. cfunction::
void Py_AddPendingCall( int (*func)(void *, void *arg)
)
.. cfunction::
int Py_AddPendingCall(int (*func)(void *), void *arg
)
.. index:: single: Py_AddPendingCall()
...
...
Doc/c-api/object.rst
View file @
8f374fd1
...
...
@@ -108,6 +108,9 @@ Object Protocol
Python expression ``o1 op o2``, where ``op`` is the operator corresponding to
*opid*.
.. note::
If *o1* and *o2* are the same object, :cfunc:`PyObject_RichCompareBool`
will always return ``1`` for :const:`Py_EQ` and ``0`` for :const:`Py_NE`.
.. cfunction:: int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
...
...
Doc/documenting/markup.rst
View file @
8f374fd1
...
...
@@ -152,7 +152,7 @@ The directives are:
Describes
global
data
in
a
module
,
including
both
variables
and
values
used
as
"defined constants."
Class
and
object
attributes
are
not
documented
using
this
environment
.
using
this
directive
.
..
describe
::
exception
...
...
@@ -165,7 +165,7 @@ The directives are:
parameters
,
enclosing
optional
parameters
in
brackets
.
Default
values
can
be
given
if
it
enhances
clarity
.
For
example
::
..
function
::
Timer
.
repeat
([
repeat
=
3
[,
number
=
1000000
]])
..
function
::
repeat
([
repeat
=
3
[,
number
=
1000000
]])
Object
methods
are
not
documented
using
this
directive
.
Bound
object
methods
placed
in
the
module
namespace
as
part
of
the
public
interface
of
the
module
...
...
@@ -186,13 +186,30 @@ The directives are:
Describes
an
object
data
attribute
.
The
description
should
include
information
about
the
type
of
the
data
to
be
expected
and
whether
it
may
be
changed
directly
.
changed
directly
.
This
directive
should
be
nested
in
a
class
directive
,
like
in
this
example
::
..
class
::
Spam
Description
of
the
class
.
..
data
::
ham
Description
of
the
attribute
.
If
is
also
possible
to
document
an
attribute
outside
of
a
class
directive
,
for
example
if
the
documentation
for
different
attributes
and
methods
is
split
in
multiple
sections
.
The
class
name
should
then
be
included
explicitly
::
..
data
::
Spam
.
eggs
..
describe
::
method
Describes
an
object
method
.
The
parameters
should
not
include
the
``
self
``
parameter
.
The
description
should
include
similar
information
to
that
described
for
``
function
``.
described
for
``
function
``.
This
method
should
be
nested
in
a
class
method
,
like
in
the
example
above
.
..
describe
::
opcode
...
...
Doc/howto/advocacy.rst
View file @
8f374fd1
...
...
@@ -308,7 +308,7 @@ http://www.pythonology.com/success
buying, but the publishers have made the first chapter available on
the Web.
http://
home.pacbell.net/ouster
/scripting.html
http://
www.tcl.tk/doc
/scripting.html
John Ousterhout's white paper on scripting is a good argument for the utility of
scripting languages, though naturally enough, he emphasizes Tcl, the language he
developed. Most of the arguments would apply to any scripting language.
...
...
Doc/library/argparse.rst
View file @
8f374fd1
:mod:`argparse` --- Parser for command
line options, arguments and sub-commands
:mod:`argparse` --- Parser for command
-
line options, arguments and sub-commands
===============================================================================
.. module:: argparse
:synopsis: Command-line option and argument
parsing library.
:synopsis: Command-line option and argument
-
parsing library.
.. moduleauthor:: Steven Bethard <steven.bethard@gmail.com>
.. versionadded:: 2.7
.. sectionauthor:: Steven Bethard <steven.bethard@gmail.com>
The :mod:`argparse` module makes it easy to write user
friendly command
line
The :mod:`argparse` module makes it easy to write user
-friendly command-
line
interfaces. The program defines what arguments it requires, and :mod:`argparse`
will figure out how to parse those out of :data:`sys.argv`. The :mod:`argparse`
module also automatically generates help and usage messages and issues errors
...
...
@@ -75,7 +75,7 @@ The first step in using the :mod:`argparse` is creating an
>>> parser = argparse.ArgumentParser(description='Process some integers.')
The :class:`ArgumentParser` object will hold all the information necessary to
parse the command line into
p
ython data types.
parse the command line into
P
ython data types.
Adding arguments
...
...
@@ -93,7 +93,7 @@ used when :meth:`~ArgumentParser.parse_args` is called. For example::
... const=sum, default=max,
... help='sum the integers (default: find the max)')
Later, calling :meth:`parse_args` will return an object with
Later, calling :meth:`
~ArgumentParser.
parse_args` will return an object with
two attributes, ``integers`` and ``accumulate``. The ``integers`` attribute
will be a list of one or more ints, and the ``accumulate`` attribute will be
either the :func:`sum` function, if ``--sum`` was specified at the command line,
...
...
@@ -104,10 +104,10 @@ Parsing arguments
^^^^^^^^^^^^^^^^^
:class:`ArgumentParser` parses args through the
:meth:`~ArgumentParser.parse_args` method. This will inspect the command
-
line,
:meth:`~ArgumentParser.parse_args` method. This will inspect the command
line,
convert each arg to the appropriate type and then invoke the appropriate action.
In most cases, this means a simple namespace object will be built up from
attributes parsed out of the command
-
line::
attributes parsed out of the command
line::
>>> parser.parse_args(['--sum', '7', '-1', '42'])
Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])
...
...
@@ -120,9 +120,7 @@ command-line args from :data:`sys.argv`.
ArgumentParser objects
----------------------
.. class:: ArgumentParser([description], [epilog], [prog], [usage], [add_help], \
[argument_default], [parents], [prefix_chars], \
[conflict_handler], [formatter_class])
.. class:: ArgumentParser([description], [epilog], [prog], [usage], [add_help], [argument_default], [parents], [prefix_chars], [conflict_handler], [formatter_class])
Create a new :class:`ArgumentParser` object. Each parameter has its own more
detailed description below, but in short they are:
...
...
@@ -217,7 +215,7 @@ the parser's help message. For example, consider a file named
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()
If ``-h`` or ``--help`` is supplied
is at the command-
line, the ArgumentParser
If ``-h`` or ``--help`` is supplied
at the command
line, the ArgumentParser
help will be printed::
$ python myprogram.py --help
...
...
@@ -291,10 +289,10 @@ arguments they contain. For example::
Namespace(f='bar')
Arguments read from a file must by default be one per line (but see also
:meth:`
convert_arg_line_to_args`) and are treated as if they were in the same
place as the original file referencing argument on the command line. So in the
example above, the expression ``['-f', 'foo', '@args.txt']`` is considered
equivalent to the expression ``['-f', 'foo', '-f', 'bar']``.
:meth:`
~ArgumentParser.convert_arg_line_to_args`) and are treated as if they
were in the same place as the original file referencing argument on the command
line. So in the example above, the expression ``['-f', 'foo', '@args.txt']``
is considered
equivalent to the expression ``['-f', 'foo', '-f', 'bar']``.
The ``fromfile_prefix_chars=`` argument defaults to ``None``, meaning that
arguments will never be treated as file references.
...
...
@@ -304,11 +302,12 @@ argument_default
^^^^^^^^^^^^^^^^
Generally, argument defaults are specified either by passing a default to
:meth:`add_argument` or by calling the :meth:`set_defaults` methods with a
specific set of name-value pairs. Sometimes however, it may be useful to
specify a single parser-wide default for arguments. This can be accomplished by
passing the ``argument_default=`` keyword argument to :class:`ArgumentParser`.
For example, to globally suppress attribute creation on :meth:`parse_args`
:meth:`~ArgumentParser.add_argument` or by calling the
:meth:`~ArgumentParser.set_defaults` methods with a specific set of name-value
pairs. Sometimes however, it may be useful to specify a single parser-wide
default for arguments. This can be accomplished by passing the
``argument_default=`` keyword argument to :class:`ArgumentParser`. For example,
to globally suppress attribute creation on :meth:`~ArgumentParser.parse_args`
calls, we supply ``argument_default=SUPPRESS``::
>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
...
...
@@ -358,11 +357,14 @@ formatter_class
:class:`ArgumentParser` objects allow the help formatting to be customized by
specifying an alternate formatting class. Currently, there are three such
classes: :class:`argparse.RawDescriptionHelpFormatter`,
:class:`argparse.RawTextHelpFormatter` and
:class:`argparse.ArgumentDefaultsHelpFormatter`. The first two allow more
control over how textual descriptions are displayed, while the last
automatically adds information about argument default values.
classes:
.. class:: RawDescriptionHelpFormatter
RawTextHelpFormatter
ArgumentDefaultsHelpFormatter
The first two allow more control over how textual descriptions are displayed,
while the last automatically adds information about argument default values.
By default, :class:`ArgumentParser` objects line-wrap the description_ and
epilog_ texts in command-line help messages::
...
...
@@ -387,7 +389,7 @@ epilog_ texts in command-line help messages::
likewise for this epilog whose whitespace will be cleaned up and whose words
will be wrapped across a couple lines
Passing :class:`argparse.RawDescriptionHelpFormatter` as ``formatter_class=``
Passing :class:`
~
argparse.RawDescriptionHelpFormatter` as ``formatter_class=``
indicates that description_ and epilog_ are already correctly formatted and
should not be line-wrapped::
...
...
@@ -570,27 +572,25 @@ your usage messages.
The add_argument() method
-------------------------
.. method:: ArgumentParser.add_argument(name or flags..., [action], [nargs], \
[const], [default], [type], [choices], [required], \
[help], [metavar], [dest])
.. method:: ArgumentParser.add_argument(name or flags..., [action], [nargs], [const], [default], [type], [choices], [required], [help], [metavar], [dest])
Define how a single command
line argument should be parsed. Each parameter
Define how a single command
-
line argument should be parsed. Each parameter
has its own more detailed description below, but in short they are:
* `name or flags`_ - Either a name or a list of option strings, e.g. ``foo``
or ``-f, --foo``
or ``-f, --foo``
.
* action_ - The basic type of action to be taken when this argument is
encountered at the command
-
line.
encountered at the command
line.
* nargs_ - The number of command-line arguments that should be consumed.
* const_ - A constant value required by some action_ and nargs_ selections.
* default_ - The value produced if the argument is absent from the
command
-
line.
command
line.
* type_ - The type to which the command-line arg should be converted.
* type_ - The type to which the command-line arg
ument
should be converted.
* choices_ - A container of the allowable values for the argument.
...
...
@@ -610,11 +610,12 @@ The following sections describe how each of these are used.
name or flags
^^^^^^^^^^^^^
The :meth:`add_argument` method must know whether an optional argument, like
``-f`` or ``--foo``, or a positional argument, like a list of filenames, is
expected. The first arguments passed to :meth:`add_argument` must therefore be
either a series of flags, or a simple argument name. For example, an optional
argument could be created like::
The :meth:`~ArgumentParser.add_argument` method must know whether an optional
argument, like ``-f`` or ``--foo``, or a positional argument, like a list of
filenames, is expected. The first arguments passed to
:meth:`~ArgumentParser.add_argument` must therefore be either a series of
flags, or a simple argument name. For example, an optional argument could
be created like::
>>> parser.add_argument('-f', '--foo')
...
...
@@ -622,8 +623,9 @@ while a positional argument could be created like::
>>> parser.add_argument('bar')
When :meth:`parse_args` is called, optional arguments will be identified by the
``-`` prefix, and the remaining arguments will be assumed to be positional::
When :meth:`~ArgumentParser.parse_args` is called, optional arguments will be
identified by the ``-`` prefix, and the remaining arguments will be assumed to
be positional::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
...
...
@@ -643,11 +645,11 @@ action
:class:`ArgumentParser` objects associate command-line args with actions. These
actions can do just about anything with the command-line args associated with
them, though most actions simply add an attribute to the object returned by
:meth:`
parse_args`. The ``action`` keyword argument specifies how the
command-line args should be handled. The supported actions are:
:meth:`
~ArgumentParser.parse_args`. The ``action`` keyword argument specifies
how the
command-line args should be handled. The supported actions are:
* ``'store'`` - This just stores the argument's value. This is the default
action. For example::
action. For example::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
...
...
@@ -655,9 +657,9 @@ command-line args should be handled. The supported actions are:
Namespace(foo='1')
* ``'store_const'`` - This stores the value specified by the const_ keyword
argument. (Note that the const_ keyword argument defaults to the rather
unhelpful ``None``.) The ``'store_const'`` action is most commonly used with
optional arguments that specify some sort of flag. For example::
argument. (Note that the const_ keyword argument defaults to the rather
unhelpful ``None``.) The ``'store_const'`` action is most commonly used with
optional arguments that specify some sort of flag. For example::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
...
...
@@ -696,8 +698,8 @@ command-line args should be handled. The supported actions are:
Namespace(types=[<type 'str'>, <type 'int'>])
* ``'version'`` - This expects a ``version=`` keyword argument in the
:meth:`
add_argument` call, and prints version information and exits whe
n
invoked.
:meth:`
~ArgumentParser.add_argument` call, and prints version informatio
n
and exits when
invoked.
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
...
...
@@ -713,11 +715,12 @@ the Action API. The easiest way to do this is to extend
* ``parser`` - The ArgumentParser object which contains this action.
* ``namespace`` - The namespace object that will be returned by
:meth:`parse_args`. Most actions add an attribute to this object.
:meth:`~ArgumentParser.parse_args`. Most actions add an attribute to this
object.
* ``values`` - The associated command-line args, with any type-conversions
applied. (Type-conversions are specified with the type_ keyword argument to
:meth:`add_argument`.
:meth:`
~ArgumentParser.
add_argument`.
* ``option_string`` - The option string that was used to invoke this action.
The ``option_string`` argument is optional, and will be absent if the action
...
...
@@ -745,10 +748,10 @@ nargs
ArgumentParser objects usually associate a single command-line argument with a
single action to be taken. The ``nargs`` keyword argument associates a
different number of command-line arguments with a single action.
.
The supported
different number of command-line arguments with a single action. The supported
values are:
* N (an integer). N args from the command
-
line will be gathered together into a
* N (an integer). N args from the command
line will be gathered together into a
list. For example::
>>> parser = argparse.ArgumentParser()
...
...
@@ -760,7 +763,7 @@ values are:
Note that ``nargs=1`` produces a list of one item. This is different from
the default, in which the item is produced by itself.
* ``'?'``. One arg will be consumed from the command
-
line if possible, and
* ``'?'``. One arg will be consumed from the command
line if possible, and
produced as a single item. If no command-line arg is present, the value from
default_ will be produced. Note that for optional arguments, there is an
additional case - the option string is present but not followed by a
...
...
@@ -824,21 +827,20 @@ will be consumed and a single item (not a list) will be produced.
const
^^^^^
The ``const`` argument of :meth:`
add_argument` is used to hold constant values
that are not read from the command line but are required for the various
ArgumentParser
actions. The two most common uses of it are:
The ``const`` argument of :meth:`
~ArgumentParser.add_argument` is used to hold
constant values that are not read from the command line but are required for
the various :class:`ArgumentParser`
actions. The two most common uses of it are:
* When :meth:`add_argument` is called with ``action='store_const'`` or
``action='append_const'``. These actions add the ``const`` value to one of
the attributes of the object returned by :meth:`parse_args`. See the action_
description for examples.
* When :meth:`~ArgumentParser.add_argument` is called with
``action='store_const'`` or ``action='append_const'``. These actions add the
``const`` value to one of the attributes of the object returned by :meth:`~ArgumentParser.parse_args`. See the action_ description for examples.
* When :meth:`
add_argument` is called with option strings (like ``-f`` or
``--foo``) and ``nargs='?'``. This creates an optional argument that can be
followed by zero or one command-line args. When parsing the command-line, if
the option string is encountered with no command-line arg following it, the
value of ``const`` will be assumed instead. See the nargs_ description for
examples.
* When :meth:`
~ArgumentParser.add_argument` is called with option strings
(like ``-f`` or ``--foo``) and ``nargs='?'``. This creates an optional
argument that can be followed by zero or one command-line args.
When parsing the command line, if the option string is encountered with no
command-line arg following it, the value of ``const`` will be assumed instead.
See the nargs_ description for
examples.
The ``const`` keyword argument defaults to ``None``.
...
...
@@ -847,10 +849,11 @@ default
^^^^^^^
All optional arguments and some positional arguments may be omitted at the
command-line. The ``default`` keyword argument of :meth:`add_argument`, whose
value defaults to ``None``, specifies what value should be used if the
command-line arg is not present. For optional arguments, the ``default`` value
is used when the option string was not present at the command line::
command line. The ``default`` keyword argument of
:meth:`~ArgumentParser.add_argument`, whose value defaults to ``None``,
specifies what value should be used if the command-line arg is not present.
For optional arguments, the ``default`` value is used when the option string
was not present at the command line::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
...
...
@@ -887,9 +890,9 @@ type
By default, ArgumentParser objects read command-line args in as simple strings.
However, quite often the command-line string should instead be interpreted as
another type, like a :class:`float`, :class:`int` or :class:`file`. The
``type`` keyword argument of :meth:`
add_argument` allows any necessar
y
type-checking and type-conversions to be performed. Many common built-in types
can be used directly as the value of the ``type`` argument::
``type`` keyword argument of :meth:`
~ArgumentParser.add_argument` allows an
y
necessary type-checking and type-conversions to be performed. Many common
built-in types
can be used directly as the value of the ``type`` argument::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
...
...
@@ -945,9 +948,9 @@ choices
Some command-line args should be selected from a restricted set of values.
These can be handled by passing a container object as the ``choices`` keyword
argument to :meth:`
add_argument`. When the command-line is parsed, arg value
s
will be checked, and an error message will be displayed if the arg was not one
of the acceptable values::
argument to :meth:`
~ArgumentParser.add_argument`. When the command line i
s
parsed, arg values will be checked, and an error message will be displayed if
the arg was not one
of the acceptable values::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', choices='abc')
...
...
@@ -977,10 +980,10 @@ etc. are all supported.
required
^^^^^^^^
In general, the
argparse
module assumes that flags like ``-f`` and ``--bar``
indicate *optional* arguments, which can always be omitted at the command
-
line.
In general, the
:mod:`argparse`
module assumes that flags like ``-f`` and ``--bar``
indicate *optional* arguments, which can always be omitted at the command
line.
To make an option *required*, ``True`` can be specified for the ``required=``
keyword argument to :meth:`add_argument`::
keyword argument to :meth:`
~ArgumentParser.
add_argument`::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
...
...
@@ -990,8 +993,9 @@ keyword argument to :meth:`add_argument`::
usage: argparse.py [-h] [--foo FOO]
argparse.py: error: option --foo is required
As the example shows, if an option is marked as ``required``, :meth:`parse_args`
will report an error if that option is not present at the command line.
As the example shows, if an option is marked as ``required``,
:meth:`~ArgumentParser.parse_args` will report an error if that option is not
present at the command line.
.. note::
...
...
@@ -1004,7 +1008,7 @@ help
The ``help`` value is a string containing a brief description of the argument.
When a user requests help (usually by using ``-h`` or ``--help`` at the
command
-
line), these ``help`` descriptions will be displayed with each
command
line), these ``help`` descriptions will be displayed with each
argument::
>>> parser = argparse.ArgumentParser(prog='frobble')
...
...
@@ -1025,7 +1029,7 @@ argument::
The ``help`` strings can include various format specifiers to avoid repetition
of things like the program name or the argument default_. The available
specifiers include the program name, ``%(prog)s`` and most keyword arguments to
:meth:`add_argument`, e.g. ``%(default)s``, ``%(type)s``, etc.::
:meth:`
~ArgumentParser.
add_argument`, e.g. ``%(default)s``, ``%(type)s``, etc.::
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('bar', nargs='?', type=int, default=42,
...
...
@@ -1085,8 +1089,8 @@ An alternative name can be specified with ``metavar``::
--foo YYY
Note that ``metavar`` only changes the *displayed* name - the name of the
attribute on the :meth:`
parse_args` object is still determined by the dest_
value.
attribute on the :meth:`
~ArgumentParser.parse_args` object is still determined
by the dest_
value.
Different values of ``nargs`` may cause the metavar to be used multiple times.
Providing a tuple to ``metavar`` specifies a different display for each of the
...
...
@@ -1108,10 +1112,11 @@ dest
^^^^
Most :class:`ArgumentParser` actions add some value as an attribute of the
object returned by :meth:`parse_args`. The name of this attribute is determined
by the ``dest`` keyword argument of :meth:`add_argument`. For positional
argument actions, ``dest`` is normally supplied as the first argument to
:meth:`add_argument`::
object returned by :meth:`~ArgumentParser.parse_args`. The name of this
attribute is determined by the ``dest`` keyword argument of
:meth:`~ArgumentParser.add_argument`. For positional argument actions,
``dest`` is normally supplied as the first argument to
:meth:`~ArgumentParser.add_argument`::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
...
...
@@ -1162,9 +1167,9 @@ The parse_args() method
Option value syntax
^^^^^^^^^^^^^^^^^^^
The :meth:`
parse_args` method supports several ways of specifying the value
of
an option (if it takes one). In the simplest case, the option and its value ar
e
passed as two separate arguments::
The :meth:`
~ArgumentParser.parse_args` method supports several ways
of
specifying the value of an option (if it takes one). In the simplest case, th
e
option and its value are
passed as two separate arguments::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
...
...
@@ -1175,7 +1180,7 @@ passed as two separate arguments::
Namespace(foo='FOO', x=None)
For long options (options with names longer than a single character), the option
and value can also be passed as a single command
line argument, using ``=`` to
and value can also be passed as a single command
-
line argument, using ``=`` to
separate them::
>>> parser.parse_args('--foo=FOO'.split())
...
...
@@ -1201,10 +1206,10 @@ as long as only the last option (or none of them) requires a value::
Invalid arguments
^^^^^^^^^^^^^^^^^
While parsing the command
-line, ``parse_args`` checks for a variety of errors,
including ambiguous options, invalid types, invalid options, wrong number of
positional arguments, etc. When it encounters such an error, it exits and
prints the error along with a usage message::
While parsing the command
line, :meth:`~ArgumentParser.parse_args` checks for a
variety of errors, including ambiguous options, invalid types, invalid options,
wrong number of positional arguments, etc. When it encounters such an error,
it exits and
prints the error along with a usage message::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
...
...
@@ -1229,13 +1234,13 @@ prints the error along with a usage message::
Arguments containing ``"-"``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The
``parse_args`` method attempts to give errors whenever the user has clearly
made a mistake, but some situations are inherently ambiguous. For example, the
command-line arg ``'-1'`` could either be an attempt to specify an option or
an
attempt to
provide a positional argument. The ``parse_args`` method is cautious
here: positional arguments may only begin with ``'-'`` if they look like
negative numbers and there are no options in the parser that look like negative
numbers::
The
:meth:`~ArgumentParser.parse_args` method attempts to give errors whenever
the user has clearly made a mistake, but some situations are inherently
ambiguous. For example, the command-line arg ``'-1'`` could either be
an
attempt to
specify an option or an attempt to provide a positional argument.
The :meth:`~ArgumentParser.parse_args` method is cautious here: positional
arguments may only begin with ``'-'`` if they look like negative numbers and
there are no options in the parser that look like negative
numbers::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
...
...
@@ -1269,7 +1274,8 @@ numbers::
If you have positional arguments that must begin with ``'-'`` and don't look
like negative numbers, you can insert the pseudo-argument ``'--'`` which tells
``parse_args`` that everything after that is a positional argument::
:meth:`~ArgumentParser.parse_args` that everything after that is a positional
argument::
>>> parser.parse_args(['--', '-f'])
Namespace(foo='-f', one=None)
...
...
@@ -1278,8 +1284,8 @@ like negative numbers, you can insert the pseudo-argument ``'--'`` which tells
Argument abbreviations
^^^^^^^^^^^^^^^^^^^^^^
The :meth:`
parse_args` method allows long options to be abbreviated if th
e
abbreviation is unambiguous::
The :meth:`
~ArgumentParser.parse_args` method allows long options to b
e
abbreviat
ed if the abbreviat
ion is unambiguous::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon')
...
...
@@ -1300,7 +1306,8 @@ Beyond ``sys.argv``
Sometimes it may be useful to have an ArgumentParser parse args other than those
of :data:`sys.argv`. This can be accomplished by passing a list of strings to
``parse_args``. This is useful for testing at the interactive prompt::
:meth:`~ArgumentParser.parse_args`. This is useful for testing at the
interactive prompt::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
...
...
@@ -1318,11 +1325,11 @@ of :data:`sys.argv`. This can be accomplished by passing a list of strings to
The Namespace object
^^^^^^^^^^^^^^^^^^^^
By default, :meth:`
parse_args` will return a new object of type :class:`Namespace`
where the necessary attributes have been set. This class is deliberately simple,
just an :class:`object` subclass with a readable string representation. If you
prefer to have dict-like view of the attributes, you can use the standard Python
idiom via :func:`vars`::
By default, :meth:`
~ArgumentParser.parse_args` will return a new object of type
:class:`Namespace` where the necessary attributes have been set. This class is
deliberately simple, just an :class:`object` subclass with a readable string
representation. If you prefer to have dict-like view of the attributes, you
can use the standard Python
idiom via :func:`vars`::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
...
...
@@ -1361,9 +1368,9 @@ Sub-commands
:class:`ArgumentParser` supports the creation of such sub-commands with the
:meth:`add_subparsers` method. The :meth:`add_subparsers` method is normally
called with no arguments and returns an special action object. This object
has a single method,
``add_parser``, which takes a command name and any
:class:`ArgumentParser` constructor arguments, and returns an
:class:`ArgumentParser` object that can be modified as usual.
has a single method,
:meth:`~ArgumentParser.add_parser`, which takes a
command name and any :class:`ArgumentParser` constructor arguments, and
returns an
:class:`ArgumentParser` object that can be modified as usual.
Some example usage::
...
...
@@ -1397,7 +1404,7 @@ Sub-commands
for that particular parser will be printed. The help message will not
include parent parser or sibling parser messages. (A help message for each
subparser command, however, can be given by supplying the ``help=`` argument
to
``add_parser`
` as above.)
to
:meth:`add_parser
` as above.)
::
...
...
@@ -1587,9 +1594,9 @@ Mutual exclusion
.. method:: add_mutually_exclusive_group(required=False)
Create a mutually exclusive group.
argparse will make sure that only one of
the arguments in the mutually exclusive group was present on the command
line::
Create a mutually exclusive group.
:mod:`argparse` will make sure that only
one of the arguments in the mutually exclusive group was present on the
command
line::
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group()
...
...
@@ -1616,7 +1623,8 @@ Mutual exclusion
PROG: error: one of the arguments --foo --bar is required
Note that currently mutually exclusive argument groups do not support the
*title* and *description* arguments of :meth:`add_argument_group`.
*title* and *description* arguments of
:meth:`~ArgumentParser.add_argument_group`.
Parser defaults
...
...
@@ -1626,8 +1634,8 @@ Parser defaults
Most of the time, the attributes of the object returned by :meth:`parse_args`
will be fully determined by inspecting the command-line args and the argument
actions. :meth:`
ArgumentParser.
set_defaults` allows some additional
attributes that are determined without any inspection of the command
-
line to
actions. :meth:`set_defaults` allows some additional
attributes that are determined without any inspection of the command
line to
be added::
>>> parser = argparse.ArgumentParser()
...
...
@@ -1663,9 +1671,9 @@ Parser defaults
Printing help
^^^^^^^^^^^^^
In most typical applications, :meth:`
parse_args` will take care of formatting
and printing any usage or error messages. However, several formatting methods
are available:
In most typical applications, :meth:`
~ArgumentParser.parse_args` will take
care of formatting and printing any usage or error messages. However, several
formatting methods
are available:
.. method:: ArgumentParser.print_usage(file=None)
...
...
@@ -1698,9 +1706,9 @@ Partial parsing
.. method:: ArgumentParser.parse_known_args(args=None, namespace=None)
Sometimes a script may only parse a few of the command
line arguments, passing
Sometimes a script may only parse a few of the command
-
line arguments, passing
the remaining arguments on to another script or program. In these cases, the
:meth:`parse_known_args` method can be useful. It works much like
:meth:`
~ArgumentParser.
parse_known_args` method can be useful. It works much like
:meth:`~ArgumentParser.parse_args` except that it does not produce an error when
extra arguments are present. Instead, it returns a two item tuple containing
the populated namespace and the list of remaining argument strings.
...
...
@@ -1757,17 +1765,17 @@ Exiting methods
Upgrading optparse code
-----------------------
Originally, the
argparse module had attempted to maintain compatibility with
optparse. However, optparse was difficult to extend transparently, particularly
with the changes required to support the new ``nargs=`` specifiers and better
usage messages. When most everything in optparse had either been copy-pasted
over or monkey-patched, it no longer seemed practical to try to maintain the
backwards compatibility.
Originally, the
:mod:`argparse` module had attempted to maintain compatibility
with :mod:`optparse`. However, :mod:`optparse` was difficult to extend
transparently, particularly with the changes required to support the new
``nargs=`` specifiers and better usage messages. When most everything in
:mod:`optparse` had either been copy-pasted over or monkey-patched, it no
longer seemed practical to try to maintain the
backwards compatibility.
A partial upgrade path from
optparse to argparse
:
A partial upgrade path from
:mod:`optparse` to :mod:`argparse`
:
* Replace all
``add_option()`` calls with :meth:`ArgumentParser.add_argument`
calls.
* Replace all
:meth:`optparse.OptionParser.add_option` calls with
:meth:`ArgumentParser.add_argument`
calls.
* Replace ``options, args = parser.parse_args()`` with ``args =
parser.parse_args()`` and add additional :meth:`ArgumentParser.add_argument`
...
...
@@ -1784,7 +1792,7 @@ A partial upgrade path from optparse to argparse:
:exc:`ArgumentError`.
* Replace strings with implicit arguments such as ``%default`` or ``%prog`` with
the standard
p
ython syntax to use dictionaries to format strings, that is,
the standard
P
ython syntax to use dictionaries to format strings, that is,
``%(default)s`` and ``%(prog)s``.
* Replace the OptionParser constructor ``version`` argument with a call to
...
...
Doc/library/collections.rst
View file @
8f374fd1
...
...
@@ -818,6 +818,9 @@ semantics pass-in keyword arguments using a regular unordered dictionary.
`Equivalent OrderedDict recipe <http://code.activestate.com/recipes/576693/>`_
that runs on Python 2.4 or later.
:class:`OrderedDict` Examples and Recipes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since an ordered dictionary remembers its insertion order, it can be used
in conjuction with sorting to make a sorted dictionary::
...
...
@@ -846,12 +849,29 @@ If a new entry overwrites an existing entry, the
original insertion position is changed and moved to the end::
class LastUpdatedOrderedDict(OrderedDict):
'Store items in the order the keys were last added'
def __setitem__(self, key, value):
if key in self:
del self[key]
OrderedDict.__setitem__(self, key, value)
An ordered dictionary can combined with the :class:`Counter` class
so that the counter remembers the order elements are first encountered::
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first encountered'
def __init__(self, iterable=None, **kwds):
OrderedDict.__init__(self)
Counter.__init__(self, iterable, **kwds)
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
.. _abstract-base-classes:
...
...
Doc/library/configparser.rst
View file @
8f374fd1
...
...
@@ -96,6 +96,9 @@ write-back, as will be the keys within each section.
This class does not
support the magical interpolation behavior.
All option names are passed through the :meth:`optionxform` method. Its
default implementation converts option names to lower case.
.. versionadded:: 2.3
.. versionchanged:: 2.6
...
...
@@ -116,10 +119,9 @@ write-back, as will be the keys within each section.
*defaults*.
All option names used in interpolation will be passed through the
:meth:`optionxform` method just like any other option name reference. For
example, using the default implementation of :meth:`optionxform` (which converts
option names to lower case), the values ``foo %(bar)s`` and ``foo %(BAR)s`` are
equivalent.
:meth:`optionxform` method just like any other option name reference. Using
the default implementation of :meth:`optionxform`, the values ``foo %(bar)s``
and ``foo %(BAR)s`` are equivalent.
.. versionadded:: 2.3
...
...
Doc/library/logging.config.rst
View file @
8f374fd1
...
...
@@ -74,15 +74,29 @@ in :mod:`logging` itself) and defining handlers which are declared either in
..
versionadded
::
2.7
..
function
::
fileConfig
(
fname
[,
defaults
]
)
..
function
::
fileConfig
(
fname
,
defaults
=
None
,
disable_existing_loggers
=
True
)
Reads
the
logging
configuration
from
a
:
mod
:`
configparser
`\-
format
file
named
*
fname
*.
This
function
can
be
called
several
times
from
an
application
,
allowing
an
end
user
to
select
from
various
pre
-
canned
Reads
the
logging
configuration
from
a
:
mod
:`
configparser
`\-
format
file
named
*
fname
*.
This
function
can
be
called
several
times
from
an
a
pplication
,
a
llowing
an
end
user
to
select
from
various
pre
-
canned
configurations
(
if
the
developer
provides
a
mechanism
to
present
the
choices
and
load
the
chosen
configuration
).
Defaults
to
be
passed
to
the
ConfigParser
can
be
specified
in
the
*
defaults
*
argument
.
and
load
the
chosen
configuration
).
:
param
defaults
:
Defaults
to
be
passed
to
the
ConfigParser
can
be
specified
in
this
argument
.
:
param
disable_existing_loggers
:
If
specified
as
``
False
``,
loggers
which
exist
when
this
call
is
made
are
left
alone
.
The
default
is
``
True
``
because
this
enables
old
behaviour
in
a
backward
-
compatible
way
.
This
behaviour
is
to
disable
any
existing
loggers
unless
they
or
their
ancestors
are
explicitly
named
in
the
logging
configuration
.
..
versionchanged
::
2.6
The
``
disable_existing_loggers
``
keyword
argument
was
added
.
Previously
,
existing
loggers
were
*
always
*
disabled
.
..
function
::
listen
(
port
=
DEFAULT_LOGGING_CONFIG_PORT
)
...
...
Doc/library/multiprocessing.rst
View file @
8f374fd1
...
...
@@ -28,7 +28,7 @@ Windows.
.. note::
Functionality within this package requires that the ``__main__`` m
ethod
be
Functionality within this package requires that the ``__main__`` m
odule
be
importable by the children. This is covered in :ref:`multiprocessing-programming`
however it is worth pointing out here. This means that some examples, such
as the :class:`multiprocessing.Pool` examples will not work in the
...
...
Doc/library/signal.rst
View file @
8f374fd1
...
...
@@ -204,6 +204,8 @@ The :mod:`signal` module defines the following functions:
attempting to call it from other threads will cause a :exc:`ValueError`
exception to be raised.
.. versionadded:: 2.6
.. function:: siginterrupt(signalnum, flag)
...
...
Doc/library/subprocess.rst
View file @
8f374fd1
...
...
@@ -178,9 +178,10 @@ This module defines one class called :class:`Popen`:
:attr:`stdout`, :attr:`stdin` and :attr:`stderr` are not updated by the
communicate() method.
The *startupinfo* and *creationflags*, if given, will be passed to the
underlying CreateProcess() function. They can specify things such as appearance
of the main window and priority for the new process. (Windows only)
If given, *startupinfo* will be a :class:`STARTUPINFO` object, which is
passed to the underlying ``CreateProcess`` function.
*creationflags*, if given, can be :data:`CREATE_NEW_CONSOLE` or
:data:`CREATE_NEW_PROCESS_GROUP`. (Windows only)
.. data:: PIPE
...
...
@@ -200,7 +201,7 @@ This module defines one class called :class:`Popen`:
Convenience Functions
^^^^^^^^^^^^^^^^^^^^^
This module also defines t
wo
shortcut functions:
This module also defines t
he following
shortcut functions:
.. function:: call(*popenargs, **kwargs)
...
...
@@ -413,6 +414,109 @@ The following attributes are also available:
``N`` (Unix only).
Windows Popen Helpers
---------------------
The :class:`STARTUPINFO` class and following constants are only available
on Windows.
.. class:: STARTUPINFO()
Partial support of the Windows
`STARTUPINFO <http://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx>`__
structure is used for :class:`Popen` creation.
.. attribute:: dwFlags
A bit field that determines whether certain :class:`STARTUPINFO` members
are used when the process creates a window. ::
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
.. attribute:: hStdInput
If :attr:`dwFlags` specifies :data:`STARTF_USESTDHANDLES`, this member is
the standard input handle for the process. If :data:`STARTF_USESTDHANDLES`
is not specified, the default for standard input is the keyboard buffer.
.. attribute:: hStdOutput
If :attr:`dwFlags` specifies :data:`STARTF_USESTDHANDLES`, this member is
the standard output handle for the process. Otherwise, this member is
ignored and the default for standard output is the console window's
buffer.
.. attribute:: hStdError
If :attr:`dwFlags` specifies :data:`STARTF_USESTDHANDLES`, this member is
the standard error handle for the process. Otherwise, this member is
ignored and the default for standard error is the console window's buffer.
.. attribute:: wShowWindow
If :attr:`dwFlags` specifies :data:`STARTF_USESHOWWINDOW`, this member
can be any of the values that can be specified in the ``nCmdShow``
parameter for the
`ShowWindow <http://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx>`__
function, except for ``SW_SHOWDEFAULT``. Otherwise, this member is
ignored.
:data:`SW_HIDE` is provided for this attribute. It is used when
:class:`Popen` is called with ``shell=True``.
Constants
^^^^^^^^^
The :mod:`subprocess` module exposes the following constants.
.. data:: STD_INPUT_HANDLE
The standard input device. Initially, this is the console input buffer,
``CONIN$``.
.. data:: STD_OUTPUT_HANDLE
The standard output device. Initially, this is the active console screen
buffer, ``CONOUT$``.
.. data:: STD_ERROR_HANDLE
The standard error device. Initially, this is the active console screen
buffer, ``CONOUT$``.
.. data:: SW_HIDE
Hides the window. Another window will be activated.
.. data:: STARTF_USESTDHANDLES
Specifies that the :attr:`STARTUPINFO.hStdInput`,
:attr:`STARTUPINFO.hStdOutput`, and :attr:`STARTUPINFO.hStdError` members
contain additional information.
.. data:: STARTF_USESHOWWINDOW
Specifies that the :attr:`STARTUPINFO.wShowWindow` member contains
additional information.
.. data:: CREATE_NEW_CONSOLE
The new process has a new console, instead of inheriting its parent's
console (the default).
This flag is always set when :class:`Popen` is created with ``shell=True``.
.. data:: CREATE_NEW_PROCESS_GROUP
A :class:`Popen` ``creationflags`` parameter to specify that a new process
group will be created. This flag is necessary for using :func:`os.kill`
on the subprocess.
This flag is ignored if :data:`CREATE_NEW_CONSOLE` is specified.
.. _subprocess-replacements:
Replacing Older Functions with the subprocess Module
...
...
Doc/library/sys.rst
View file @
8f374fd1
...
...
@@ -562,6 +562,30 @@ always available.
``version_info`` value may be used for a more human-friendly encoding of the
same information.
The ``hexversion`` is a 32-bit number with the following layout
+-------------------------+------------------------------------------------+
| bits (big endian order) | meaning |
+=========================+================================================+
| :const:`1-8` | ``PY_MAJOR_VERSION`` (the ``2`` in |
| | ``2.1.0a3``) |
+-------------------------+------------------------------------------------+
| :const:`9-16` | ``PY_MINOR_VERSION`` (the ``1`` in |
| | ``2.1.0a3``) |
+-------------------------+------------------------------------------------+
| :const:`17-24` | ``PY_MICRO_VERSION`` (the ``0`` in |
| | ``2.1.0a3``) |
+-------------------------+------------------------------------------------+
| :const:`25-28` | ``PY_RELEASE_LEVEL`` (``0xA`` for alpha, |
| | ``0xB`` for beta, ``0xC`` for gamma and |
| | ``0xF`` for final) |
+-------------------------+------------------------------------------------+
| :const:`29-32` | ``PY_RELEASE_SERIAL`` (the ``3`` in |
| | ``2.1.0a3``) |
+-------------------------+------------------------------------------------+
thus ``2.1.0a3`` is hexversion ``0x020100a3``
.. versionadded:: 1.5.2
...
...
Doc/library/urllib.rst
View file @
8f374fd1
...
...
@@ -167,15 +167,15 @@ High-level interface
the download is interrupted.
The *Content-Length* is treated as a lower bound: if there's more data to read,
urlretrieve reads more data, but if less data is available, it raises the
exception.
:func:`urlretrieve` reads more data, but if less data is available, it raises
the
exception.
You can still retrieve the downloaded data in this case, it is stored in the
:attr:`content` attribute of the exception instance.
If no *Content-Length* header was supplied,
urlretrieve can not check the size
of the data it has downloaded, and just returns it. In this case you just have
to assume that the download was successful.
If no *Content-Length* header was supplied,
:func:`urlretrieve` can not check
the size of the data it has downloaded, and just returns it. In this case you
just have
to assume that the download was successful.
.. data:: _urlopener
...
...
Include/pystate.h
View file @
8f374fd1
...
...
@@ -111,6 +111,7 @@ PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
PyAPI_FUNC
(
void
)
PyThreadState_Delete
(
PyThreadState
*
);
#ifdef WITH_THREAD
PyAPI_FUNC
(
void
)
PyThreadState_DeleteCurrent
(
void
);
PyAPI_FUNC
(
void
)
_PyGILState_Reinit
(
void
);
#endif
PyAPI_FUNC
(
PyThreadState
*
)
PyThreadState_Get
(
void
);
...
...
Lib/anydbm.py
View file @
8f374fd1
...
...
@@ -29,17 +29,8 @@ It has the following interface (key and data are strings):
list = d.keys() # return a list of all existing keys (slow!)
Future versions may change the order in which implementations are
tested for existence, add interfaces to other dbm-like
tested for existence, a
nd a
dd interfaces to other dbm-like
implementations.
The open function has an optional second argument. This can be 'r',
for read-only access, 'w', for read-write access of an existing
database, 'c' for read-write access to a new or existing database, and
'n' for read-write access to a new database. The default is 'r'.
Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it
only if it doesn't exist; and 'n' always creates a new database.
"""
class
error
(
Exception
):
...
...
@@ -63,7 +54,18 @@ if not _defaultmod:
error
=
tuple
(
_errors
)
def
open
(
file
,
flag
=
'r'
,
mode
=
0666
):
def
open
(
file
,
flag
=
'r'
,
mode
=
0666
):
"""Open or create database at path given by *file*.
Optional argument *flag* can be 'r' (default) for read-only access, 'w'
for read-write access of an existing database, 'c' for read-write access
to a new or existing database, and 'n' for read-write access to a new
database.
Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it
only if it doesn't exist; and 'n' always creates a new database.
"""
# guess the type of an existing database
from
whichdb
import
whichdb
result
=
whichdb
(
file
)
...
...
Lib/collections.py
View file @
8f374fd1
...
...
@@ -6,37 +6,16 @@ import _abcoll
__all__
+=
_abcoll
.
__all__
from
_collections
import
deque
,
defaultdict
from
operator
import
itemgetter
as
_itemgetter
,
eq
as
_eq
from
operator
import
itemgetter
as
_itemgetter
from
keyword
import
iskeyword
as
_iskeyword
import
sys
as
_sys
import
heapq
as
_heapq
from
itertools
import
repeat
as
_repeat
,
chain
as
_chain
,
starmap
as
_starmap
,
\
ifilter
as
_ifilter
,
imap
as
_imap
from
itertools
import
repeat
as
_repeat
,
chain
as
_chain
,
starmap
as
_starmap
try
:
from
thread
import
get_ident
from
thread
import
get_ident
as
_get_ident
except
ImportError
:
from
dummy_thread
import
get_ident
def
_recursive_repr
(
user_function
):
'Decorator to make a repr function return "..." for a recursive call'
repr_running
=
set
()
def
wrapper
(
self
):
key
=
id
(
self
),
get_ident
()
if
key
in
repr_running
:
return
'...'
repr_running
.
add
(
key
)
try
:
result
=
user_function
(
self
)
finally
:
repr_running
.
discard
(
key
)
return
result
# Can't use functools.wraps() here because of bootstrap issues
wrapper
.
__module__
=
getattr
(
user_function
,
'__module__'
)
wrapper
.
__doc__
=
getattr
(
user_function
,
'__doc__'
)
wrapper
.
__name__
=
getattr
(
user_function
,
'__name__'
)
return
wrapper
from
dummy_thread
import
get_ident
as
_get_ident
################################################################################
...
...
@@ -48,17 +27,17 @@ class OrderedDict(dict):
# An inherited dict maps keys to values.
# The inherited dict provides __getitem__, __len__, __contains__, and get.
# The remaining methods are order-aware.
# Big-O running times for all methods are the same as
for
regular dictionaries.
# Big-O running times for all methods are the same as regular dictionaries.
# The internal self.__map dict
ionary
maps keys to links in a doubly linked list.
# The internal self.__map dict maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
# Each link is stored as a list of length three: [PREV, NEXT, KEY].
def
__init__
(
self
,
*
args
,
**
kwds
):
'''Initialize an ordered dictionary.
Signature is the same as for
regular dictionaries, but keyword arguments are not recommended
because
their insertion order is arbitrary.
'''Initialize an ordered dictionary.
The signature is the same as
regular dictionaries, but keyword arguments are not recommended
because
their insertion order is arbitrary.
'''
if
len
(
args
)
>
1
:
...
...
@@ -66,17 +45,15 @@ class OrderedDict(dict):
try
:
self
.
__root
except
AttributeError
:
self
.
__root
=
root
=
[
None
,
None
,
None
]
# sentinel node
PREV
=
0
NEXT
=
1
root
[
PREV
]
=
root
[
NEXT
]
=
root
self
.
__root
=
root
=
[]
# sentinel node
root
[:]
=
[
root
,
root
,
None
]
self
.
__map
=
{}
self
.
__update
(
*
args
,
**
kwds
)
def
__setitem__
(
self
,
key
,
value
,
PREV
=
0
,
NEXT
=
1
,
dict_setitem
=
dict
.
__setitem__
):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link
which goes at the end of the linked
#
list,
and the inherited dictionary is updated with the new key/value pair.
# Setting a new item creates a new link
at the end of the linked list,
# and the inherited dictionary is updated with the new key/value pair.
if
key
not
in
self
:
root
=
self
.
__root
last
=
root
[
PREV
]
...
...
@@ -85,79 +62,82 @@ class OrderedDict(dict):
def
__delitem__
(
self
,
key
,
PREV
=
0
,
NEXT
=
1
,
dict_delitem
=
dict
.
__delitem__
):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which
i
s
#
then
removed by updating the links in the predecessor and successor nodes.
# Deleting an existing item uses self.__map to find the link which
get
s
# removed by updating the links in the predecessor and successor nodes.
dict_delitem
(
self
,
key
)
link
=
self
.
__map
.
pop
(
key
)
link_prev
=
link
[
PREV
]
link_next
=
link
[
NEXT
]
link_prev
,
link_next
,
key
=
self
.
__map
.
pop
(
key
)
link_prev
[
NEXT
]
=
link_next
link_next
[
PREV
]
=
link_prev
def
__iter__
(
self
,
NEXT
=
1
,
KEY
=
2
):
def
__iter__
(
self
):
'od.__iter__() <==> iter(od)'
# Traverse the linked list in order.
NEXT
,
KEY
=
1
,
2
root
=
self
.
__root
curr
=
root
[
NEXT
]
while
curr
is
not
root
:
yield
curr
[
KEY
]
curr
=
curr
[
NEXT
]
def
__reversed__
(
self
,
PREV
=
0
,
KEY
=
2
):
def
__reversed__
(
self
):
'od.__reversed__() <==> reversed(od)'
# Traverse the linked list in reverse order.
PREV
,
KEY
=
0
,
2
root
=
self
.
__root
curr
=
root
[
PREV
]
while
curr
is
not
root
:
yield
curr
[
KEY
]
curr
=
curr
[
PREV
]
def
__reduce__
(
self
):
'Return state information for pickling'
items
=
[[
k
,
self
[
k
]]
for
k
in
self
]
tmp
=
self
.
__map
,
self
.
__root
del
self
.
__map
,
self
.
__root
inst_dict
=
vars
(
self
).
copy
()
self
.
__map
,
self
.
__root
=
tmp
if
inst_dict
:
return
(
self
.
__class__
,
(
items
,),
inst_dict
)
return
self
.
__class__
,
(
items
,)
def
clear
(
self
):
'od.clear() -> None. Remove all items from od.'
try
:
for
node
in
self
.
__map
.
itervalues
():
del
node
[:]
self
.
__root
[:]
=
[
self
.
__root
,
self
.
__root
,
None
]
self
.
__map
.
clear
()
except
AttributeError
:
pass
for
node
in
self
.
__map
.
itervalues
():
del
node
[:]
root
=
self
.
__root
root
[:]
=
[
root
,
root
,
None
]
self
.
__map
.
clear
()
dict
.
clear
(
self
)
update
=
__update
=
MutableMapping
.
update
keys
=
MutableMapping
.
keys
values
=
MutableMapping
.
values
items
=
MutableMapping
.
items
iterkeys
=
MutableMapping
.
iterkeys
itervalues
=
MutableMapping
.
itervalues
iteritems
=
MutableMapping
.
iteritems
__ne__
=
MutableMapping
.
__ne__
# -- the following methods do not depend on the internal structure --
def
view
keys
(
self
):
"od.viewkeys() -> a set-like object providing a view on od's keys"
return
KeysView
(
self
)
def
keys
(
self
):
'od.keys() -> list of keys in od'
return
list
(
self
)
def
v
iewv
alues
(
self
):
"od.viewvalues() -> an object providing a view on od's values"
return
ValuesView
(
self
)
def
values
(
self
):
'od.values() -> list of values in od'
return
[
self
[
key
]
for
key
in
self
]
def
viewitems
(
self
):
"od.viewitems() -> a set-like object providing a view on od's items"
return
ItemsView
(
self
)
def
items
(
self
):
'od.items() -> list of (key, value) pairs in od'
return
[(
key
,
self
[
key
])
for
key
in
self
]
def
iterkeys
(
self
):
'od.iterkeys() -> an iterator over the keys in od'
return
iter
(
self
)
def
itervalues
(
self
):
'od.itervalues -> an iterator over the values in od'
for
k
in
self
:
yield
self
[
k
]
def
iteritems
(
self
):
'od.iteritems -> an iterator over the (key, value) pairs in od'
for
k
in
self
:
yield
(
k
,
self
[
k
])
update
=
MutableMapping
.
update
__update
=
update
# let subclasses override update without breaking __init__
__marker
=
object
()
def
pop
(
self
,
key
,
default
=
__marker
):
'''od.pop(k[,d]) -> v, remove specified key and return the corresponding
value. If key is not found, d is returned if given, otherwise KeyError
is raised.
'''
if
key
in
self
:
result
=
self
[
key
]
del
self
[
key
]
...
...
@@ -184,12 +164,28 @@ class OrderedDict(dict):
value
=
self
.
pop
(
key
)
return
key
,
value
@
_recursive_repr
def
__repr__
(
self
):
def
__repr__
(
self
,
_repr_running
=
{}):
'od.__repr__() <==> repr(od)'
if
not
self
:
return
'%s()'
%
(
self
.
__class__
.
__name__
,)
return
'%s(%r)'
%
(
self
.
__class__
.
__name__
,
self
.
items
())
call_key
=
id
(
self
),
_get_ident
()
if
call_key
in
_repr_running
:
return
'...'
_repr_running
[
call_key
]
=
1
try
:
if
not
self
:
return
'%s()'
%
(
self
.
__class__
.
__name__
,)
return
'%s(%r)'
%
(
self
.
__class__
.
__name__
,
self
.
items
())
finally
:
del
_repr_running
[
call_key
]
def
__reduce__
(
self
):
'Return state information for pickling'
items
=
[[
k
,
self
[
k
]]
for
k
in
self
]
inst_dict
=
vars
(
self
).
copy
()
for
k
in
vars
(
OrderedDict
()):
inst_dict
.
pop
(
k
,
None
)
if
inst_dict
:
return
(
self
.
__class__
,
(
items
,),
inst_dict
)
return
self
.
__class__
,
(
items
,)
def
copy
(
self
):
'od.copy() -> a shallow copy of od'
...
...
@@ -197,14 +193,14 @@ class OrderedDict(dict):
@
classmethod
def
fromkeys
(
cls
,
iterable
,
value
=
None
):
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
and values equal to v (which defaults to None)
.
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
.
If not specified, the value defaults to None
.
'''
d
=
cls
()
self
=
cls
()
for
key
in
iterable
:
d
[
key
]
=
value
return
d
self
[
key
]
=
value
return
self
def
__eq__
(
self
,
other
):
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
...
...
@@ -212,10 +208,27 @@ class OrderedDict(dict):
'''
if
isinstance
(
other
,
OrderedDict
):
return
len
(
self
)
==
len
(
other
)
and
\
all
(
_imap
(
_eq
,
self
.
iteritems
(),
other
.
iteritems
()))
return
len
(
self
)
==
len
(
other
)
and
self
.
items
()
==
other
.
items
()
return
dict
.
__eq__
(
self
,
other
)
def
__ne__
(
self
,
other
):
'od.__ne__(y) <==> od!=y'
return
not
self
==
other
# -- the following methods support python 3.x style dictionary views --
def
viewkeys
(
self
):
"od.viewkeys() -> a set-like object providing a view on od's keys"
return
KeysView
(
self
)
def
viewvalues
(
self
):
"od.viewvalues() -> an object providing a view on od's values"
return
ValuesView
(
self
)
def
viewitems
(
self
):
"od.viewitems() -> a set-like object providing a view on od's items"
return
ItemsView
(
self
)
################################################################################
### namedtuple
...
...
@@ -516,8 +529,8 @@ class Counter(dict):
self
.
subtract
(
kwds
)
def
copy
(
self
):
'
Like dict.copy() but returns a Counter instance instead of a dict
.'
return
Counter
(
self
)
'
Return a shallow copy
.'
return
self
.
__class__
(
self
)
def
__reduce__
(
self
):
return
self
.
__class__
,
(
dict
(
self
),)
...
...
@@ -552,10 +565,13 @@ class Counter(dict):
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
result
=
Counter
()
for
elem
in
set
(
self
)
|
set
(
other
):
newcount
=
self
[
elem
]
+
other
[
elem
]
for
elem
,
count
in
self
.
items
(
):
newcount
=
count
+
other
[
elem
]
if
newcount
>
0
:
result
[
elem
]
=
newcount
for
elem
,
count
in
other
.
items
():
if
elem
not
in
self
and
count
>
0
:
result
[
elem
]
=
count
return
result
def
__sub__
(
self
,
other
):
...
...
@@ -568,10 +584,13 @@ class Counter(dict):
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
result
=
Counter
()
for
elem
in
set
(
self
)
|
set
(
other
):
newcount
=
self
[
elem
]
-
other
[
elem
]
for
elem
,
count
in
self
.
items
(
):
newcount
=
count
-
other
[
elem
]
if
newcount
>
0
:
result
[
elem
]
=
newcount
for
elem
,
count
in
other
.
items
():
if
elem
not
in
self
and
count
<
0
:
result
[
elem
]
=
0
-
count
return
result
def
__or__
(
self
,
other
):
...
...
@@ -584,11 +603,14 @@ class Counter(dict):
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
result
=
Counter
()
for
elem
in
set
(
self
)
|
set
(
other
):
p
,
q
=
self
[
elem
],
other
[
elem
]
newcount
=
q
if
p
<
q
else
p
for
elem
,
count
in
self
.
items
(
):
other_count
=
other
[
elem
]
newcount
=
other_count
if
count
<
other_count
else
count
if
newcount
>
0
:
result
[
elem
]
=
newcount
for
elem
,
count
in
other
.
items
():
if
elem
not
in
self
and
count
>
0
:
result
[
elem
]
=
count
return
result
def
__and__
(
self
,
other
):
...
...
@@ -601,11 +623,9 @@ class Counter(dict):
if
not
isinstance
(
other
,
Counter
):
return
NotImplemented
result
=
Counter
()
if
len
(
self
)
<
len
(
other
):
self
,
other
=
other
,
self
for
elem
in
_ifilter
(
self
.
__contains__
,
other
):
p
,
q
=
self
[
elem
],
other
[
elem
]
newcount
=
p
if
p
<
q
else
q
for
elem
,
count
in
self
.
items
():
other_count
=
other
[
elem
]
newcount
=
count
if
count
<
other_count
else
other_count
if
newcount
>
0
:
result
[
elem
]
=
newcount
return
result
...
...
Lib/distutils/command/sdist.py
View file @
8f374fd1
...
...
@@ -306,17 +306,20 @@ class sdist(Command):
rstrip_ws
=
1
,
collapse_join
=
1
)
while
1
:
line
=
template
.
readline
()
if
line
is
None
:
# end of file
break
try
:
self
.
filelist
.
process_template_line
(
line
)
except
DistutilsTemplateError
,
msg
:
self
.
warn
(
"%s, line %d: %s"
%
(
template
.
filename
,
template
.
current_line
,
msg
))
try
:
while
1
:
line
=
template
.
readline
()
if
line
is
None
:
# end of file
break
try
:
self
.
filelist
.
process_template_line
(
line
)
except
DistutilsTemplateError
,
msg
:
self
.
warn
(
"%s, line %d: %s"
%
(
template
.
filename
,
template
.
current_line
,
msg
))
finally
:
template
.
close
()
def
prune_file_list
(
self
):
"""Prune off branches that might slip into the file list as created
...
...
Lib/getpass.py
View file @
8f374fd1
...
...
@@ -62,7 +62,7 @@ def unix_getpass(prompt='Password: ', stream=None):
try
:
old
=
termios
.
tcgetattr
(
fd
)
# a copy to save
new
=
old
[:]
new
[
3
]
&=
~
(
termios
.
ECHO
|
termios
.
ISIG
)
# 3 == 'lflags'
new
[
3
]
&=
~
termios
.
ECHO
# 3 == 'lflags'
tcsetattr_flags
=
termios
.
TCSAFLUSH
if
hasattr
(
termios
,
'TCSASOFT'
):
tcsetattr_flags
|=
termios
.
TCSASOFT
...
...
Lib/subprocess.py
View file @
8f374fd1
...
...
@@ -441,8 +441,15 @@ __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call",
"check_output"
,
"CalledProcessError"
]
if
mswindows
:
from
_subprocess
import
CREATE_NEW_CONSOLE
,
CREATE_NEW_PROCESS_GROUP
__all__
.
extend
([
"CREATE_NEW_CONSOLE"
,
"CREATE_NEW_PROCESS_GROUP"
])
from
_subprocess
import
(
CREATE_NEW_CONSOLE
,
CREATE_NEW_PROCESS_GROUP
,
STD_INPUT_HANDLE
,
STD_OUTPUT_HANDLE
,
STD_ERROR_HANDLE
,
SW_HIDE
,
STARTF_USESTDHANDLES
,
STARTF_USESHOWWINDOW
)
__all__
.
extend
([
"CREATE_NEW_CONSOLE"
,
"CREATE_NEW_PROCESS_GROUP"
,
"STD_INPUT_HANDLE"
,
"STD_OUTPUT_HANDLE"
,
"STD_ERROR_HANDLE"
,
"SW_HIDE"
,
"STARTF_USESTDHANDLES"
,
"STARTF_USESHOWWINDOW"
])
try
:
MAXFD
=
os
.
sysconf
(
"SC_OPEN_MAX"
)
except
:
...
...
Lib/tarfile.py
View file @
8f374fd1
...
...
@@ -2239,6 +2239,8 @@ class TarFile(object):
if hasattr(os, "
symlink
") and hasattr(os, "
link
"):
# For systems that support symbolic and hard links.
if tarinfo.issym():
if os.path.exists(targetpath):
os.unlink(targetpath)
os.symlink(tarinfo.linkname, targetpath)
else:
# See extract().
...
...
Lib/test/string_tests.py
View file @
8f374fd1
...
...
@@ -1177,6 +1177,63 @@ class MixinStrUnicodeUserStringTest:
# mixed use of str and unicode
self
.
assertEqual
(
'a/b/c'
.
rpartition
(
u'/'
),
(
'a/b'
,
'/'
,
'c'
))
def
test_none_arguments
(
self
):
# issue 11828
s
=
'hello'
self
.
checkequal
(
2
,
s
,
'find'
,
'l'
,
None
)
self
.
checkequal
(
3
,
s
,
'find'
,
'l'
,
-
2
,
None
)
self
.
checkequal
(
2
,
s
,
'find'
,
'l'
,
None
,
-
2
)
self
.
checkequal
(
0
,
s
,
'find'
,
'h'
,
None
,
None
)
self
.
checkequal
(
3
,
s
,
'rfind'
,
'l'
,
None
)
self
.
checkequal
(
3
,
s
,
'rfind'
,
'l'
,
-
2
,
None
)
self
.
checkequal
(
2
,
s
,
'rfind'
,
'l'
,
None
,
-
2
)
self
.
checkequal
(
0
,
s
,
'rfind'
,
'h'
,
None
,
None
)
self
.
checkequal
(
2
,
s
,
'index'
,
'l'
,
None
)
self
.
checkequal
(
3
,
s
,
'index'
,
'l'
,
-
2
,
None
)
self
.
checkequal
(
2
,
s
,
'index'
,
'l'
,
None
,
-
2
)
self
.
checkequal
(
0
,
s
,
'index'
,
'h'
,
None
,
None
)
self
.
checkequal
(
3
,
s
,
'rindex'
,
'l'
,
None
)
self
.
checkequal
(
3
,
s
,
'rindex'
,
'l'
,
-
2
,
None
)
self
.
checkequal
(
2
,
s
,
'rindex'
,
'l'
,
None
,
-
2
)
self
.
checkequal
(
0
,
s
,
'rindex'
,
'h'
,
None
,
None
)
self
.
checkequal
(
2
,
s
,
'count'
,
'l'
,
None
)
self
.
checkequal
(
1
,
s
,
'count'
,
'l'
,
-
2
,
None
)
self
.
checkequal
(
1
,
s
,
'count'
,
'l'
,
None
,
-
2
)
self
.
checkequal
(
0
,
s
,
'count'
,
'x'
,
None
,
None
)
self
.
checkequal
(
True
,
s
,
'endswith'
,
'o'
,
None
)
self
.
checkequal
(
True
,
s
,
'endswith'
,
'lo'
,
-
2
,
None
)
self
.
checkequal
(
True
,
s
,
'endswith'
,
'l'
,
None
,
-
2
)
self
.
checkequal
(
False
,
s
,
'endswith'
,
'x'
,
None
,
None
)
self
.
checkequal
(
True
,
s
,
'startswith'
,
'h'
,
None
)
self
.
checkequal
(
True
,
s
,
'startswith'
,
'l'
,
-
2
,
None
)
self
.
checkequal
(
True
,
s
,
'startswith'
,
'h'
,
None
,
-
2
)
self
.
checkequal
(
False
,
s
,
'startswith'
,
'x'
,
None
,
None
)
def
test_find_etc_raise_correct_error_messages
(
self
):
# issue 11828
s
=
'hello'
x
=
'x'
self
.
assertRaisesRegexp
(
TypeError
,
r'\bfind\b'
,
s
.
find
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\brfind\b'
,
s
.
rfind
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\bindex\b'
,
s
.
index
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\brindex\b'
,
s
.
rindex
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'^count\
(
', s.count,
x, None, None, None)
self.assertRaisesRegexp(TypeError, r'
^
startswith
\
(
', s.startswith,
x, None, None, None)
self.assertRaisesRegexp(TypeError, r'
^
endswith
\
(
', s.endswith,
x, None, None, None)
class MixinStrStringUserStringTest:
# Additional tests for 8bit strings, i.e. str, UserString and
# the string module
...
...
Lib/test/test_bytes.py
View file @
8f374fd1
...
...
@@ -456,6 +456,68 @@ class BaseBytesTest(unittest.TestCase):
self
.
assertEqual
([
ord
(
b
[
i
:
i
+
1
])
for
i
in
range
(
len
(
b
))],
[
0
,
65
,
127
,
128
,
255
])
def
test_none_arguments
(
self
):
# issue 11828
b
=
self
.
type2test
(
b'hello'
)
l
=
self
.
type2test
(
b'l'
)
h
=
self
.
type2test
(
b'h'
)
x
=
self
.
type2test
(
b'x'
)
o
=
self
.
type2test
(
b'o'
)
self
.
assertEqual
(
2
,
b
.
find
(
l
,
None
))
self
.
assertEqual
(
3
,
b
.
find
(
l
,
-
2
,
None
))
self
.
assertEqual
(
2
,
b
.
find
(
l
,
None
,
-
2
))
self
.
assertEqual
(
0
,
b
.
find
(
h
,
None
,
None
))
self
.
assertEqual
(
3
,
b
.
rfind
(
l
,
None
))
self
.
assertEqual
(
3
,
b
.
rfind
(
l
,
-
2
,
None
))
self
.
assertEqual
(
2
,
b
.
rfind
(
l
,
None
,
-
2
))
self
.
assertEqual
(
0
,
b
.
rfind
(
h
,
None
,
None
))
self
.
assertEqual
(
2
,
b
.
index
(
l
,
None
))
self
.
assertEqual
(
3
,
b
.
index
(
l
,
-
2
,
None
))
self
.
assertEqual
(
2
,
b
.
index
(
l
,
None
,
-
2
))
self
.
assertEqual
(
0
,
b
.
index
(
h
,
None
,
None
))
self
.
assertEqual
(
3
,
b
.
rindex
(
l
,
None
))
self
.
assertEqual
(
3
,
b
.
rindex
(
l
,
-
2
,
None
))
self
.
assertEqual
(
2
,
b
.
rindex
(
l
,
None
,
-
2
))
self
.
assertEqual
(
0
,
b
.
rindex
(
h
,
None
,
None
))
self
.
assertEqual
(
2
,
b
.
count
(
l
,
None
))
self
.
assertEqual
(
1
,
b
.
count
(
l
,
-
2
,
None
))
self
.
assertEqual
(
1
,
b
.
count
(
l
,
None
,
-
2
))
self
.
assertEqual
(
0
,
b
.
count
(
x
,
None
,
None
))
self
.
assertEqual
(
True
,
b
.
endswith
(
o
,
None
))
self
.
assertEqual
(
True
,
b
.
endswith
(
o
,
-
2
,
None
))
self
.
assertEqual
(
True
,
b
.
endswith
(
l
,
None
,
-
2
))
self
.
assertEqual
(
False
,
b
.
endswith
(
x
,
None
,
None
))
self
.
assertEqual
(
True
,
b
.
startswith
(
h
,
None
))
self
.
assertEqual
(
True
,
b
.
startswith
(
l
,
-
2
,
None
))
self
.
assertEqual
(
True
,
b
.
startswith
(
h
,
None
,
-
2
))
self
.
assertEqual
(
False
,
b
.
startswith
(
x
,
None
,
None
))
def
test_find_etc_raise_correct_error_messages
(
self
):
# issue 11828
b
=
self
.
type2test
(
b'hello'
)
x
=
self
.
type2test
(
b'x'
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\bfind\b'
,
b
.
find
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\brfind\b'
,
b
.
rfind
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\bindex\b'
,
b
.
index
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\brindex\b'
,
b
.
rindex
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\bcount\b'
,
b
.
count
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\bstartswith\b'
,
b
.
startswith
,
x
,
None
,
None
,
None
)
self
.
assertRaisesRegexp
(
TypeError
,
r'\bendswith\b'
,
b
.
endswith
,
x
,
None
,
None
,
None
)
class
ByteArrayTest
(
BaseBytesTest
):
type2test
=
bytearray
...
...
Lib/test/test_collections.py
View file @
8f374fd1
...
...
@@ -689,6 +689,15 @@ class TestCounter(unittest.TestCase):
self
.
assertEqual
(
len
(
dup
),
len
(
words
))
self
.
assertEqual
(
type
(
dup
),
type
(
words
))
def
test_copy_subclass
(
self
):
class
MyCounter
(
Counter
):
pass
c
=
MyCounter
(
'slartibartfast'
)
d
=
c
.
copy
()
self
.
assertEqual
(
d
,
c
)
self
.
assertEqual
(
len
(
d
),
len
(
c
))
self
.
assertEqual
(
type
(
d
),
type
(
c
))
def
test_conversions
(
self
):
# Convert to: set, list, dict
s
=
'she sells sea shells by the sea shore'
...
...
Lib/test/test_pydoc.py
View file @
8f374fd1
...
...
@@ -6,6 +6,7 @@ import subprocess
import
re
import
pydoc
import
inspect
import
keyword
import
unittest
import
xml.etree
import
test.test_support
...
...
@@ -351,9 +352,16 @@ class TestDescriptions(unittest.TestCase):
self
.
assertIn
(
'_asdict'
,
helptext
)
class
TestHelper
(
unittest
.
TestCase
):
def
test_keywords
(
self
):
self
.
assertEqual
(
sorted
(
pydoc
.
Helper
.
keywords
),
sorted
(
keyword
.
kwlist
))
def
test_main
():
test
.
test_support
.
run_unittest
(
PyDocDocTest
,
TestDescriptions
)
TestDescriptions
,
TestHelper
)
if
__name__
==
"__main__"
:
test_main
()
Lib/test/test_startfile.py
View file @
8f374fd1
...
...
@@ -11,6 +11,7 @@ import unittest
from
test
import
test_support
import
os
from
os
import
path
from
time
import
sleep
startfile
=
test_support
.
get_attribute
(
os
,
'startfile'
)
...
...
@@ -26,11 +27,16 @@ class TestCase(unittest.TestCase):
empty
=
path
.
join
(
path
.
dirname
(
__file__
),
"empty.vbs"
)
startfile
(
empty
)
startfile
(
empty
,
"open"
)
# Give the child process some time to exit before we finish.
# Otherwise the cleanup code will not be able to delete the cwd,
# because it is still in use.
sleep
(
0.1
)
def
test_empty_u
(
self
):
empty
=
path
.
join
(
path
.
dirname
(
__file__
),
"empty.vbs"
)
startfile
(
unicode
(
empty
,
"mbcs"
))
startfile
(
unicode
(
empty
,
"mbcs"
),
"open"
)
sleep
(
0.1
)
def
test_main
():
test_support
.
run_unittest
(
TestCase
)
...
...
Lib/test/test_str.py
View file @
8f374fd1
...
...
@@ -414,7 +414,18 @@ class StrTest(
self
.
assertEqual
(
'Andr
\
202
x'
.
decode
(
'ascii'
,
'replace'
),
'Andr
\
202
x'
.
decode
(
encoding
=
'ascii'
,
errors
=
'replace'
))
def
test_startswith_endswith_errors
(
self
):
with
self
.
assertRaises
(
UnicodeDecodeError
):
'
\
xff
'
.
startswith
(
u'x'
)
with
self
.
assertRaises
(
UnicodeDecodeError
):
'
\
xff
'
.
endswith
(
u'x'
)
for
meth
in
(
'foo'
.
startswith
,
'foo'
.
endswith
):
with
self
.
assertRaises
(
TypeError
)
as
cm
:
meth
([
'f'
])
exc
=
str
(
cm
.
exception
)
self
.
assertIn
(
'unicode'
,
exc
)
self
.
assertIn
(
'str'
,
exc
)
self
.
assertIn
(
'tuple'
,
exc
)
def
test_main
():
test_support
.
run_unittest
(
StrTest
)
...
...
Lib/test/test_tarfile.py
View file @
8f374fd1
...
...
@@ -843,6 +843,34 @@ class WriteTest(WriteTestBase):
finally
:
os
.
chdir
(
cwd
)
@
unittest
.
skipUnless
(
hasattr
(
os
,
'symlink'
),
"needs os.symlink"
)
def
test_extractall_symlinks
(
self
):
# Test if extractall works properly when tarfile contains symlinks
tempdir
=
os
.
path
.
join
(
TEMPDIR
,
"testsymlinks"
)
temparchive
=
os
.
path
.
join
(
TEMPDIR
,
"testsymlinks.tar"
)
os
.
mkdir
(
tempdir
)
try
:
source_file
=
os
.
path
.
join
(
tempdir
,
'source'
)
target_file
=
os
.
path
.
join
(
tempdir
,
'symlink'
)
with
open
(
source_file
,
'w'
)
as
f
:
f
.
write
(
'something
\
n
'
)
os
.
symlink
(
source_file
,
target_file
)
tar
=
tarfile
.
open
(
temparchive
,
'w'
)
tar
.
add
(
source_file
,
arcname
=
os
.
path
.
basename
(
source_file
))
tar
.
add
(
target_file
,
arcname
=
os
.
path
.
basename
(
target_file
))
tar
.
close
()
# Let's extract it to the location which contains the symlink
tar
=
tarfile
.
open
(
temparchive
,
'r'
)
# this should not raise OSError: [Errno 17] File exists
try
:
tar
.
extractall
(
path
=
tempdir
)
except
OSError
:
self
.
fail
(
"extractall failed with symlinked files"
)
finally
:
tar
.
close
()
finally
:
os
.
unlink
(
temparchive
)
shutil
.
rmtree
(
tempdir
)
class
StreamWriteTest
(
WriteTestBase
):
...
...
Lib/test/test_unicode.py
View file @
8f374fd1
...
...
@@ -442,6 +442,17 @@ class UnicodeTest(
return
u'
\
u1234
'
self
.
assertEqual
(
'%s'
%
Wrapper
(),
u'
\
u1234
'
)
def
test_startswith_endswith_errors
(
self
):
for
meth
in
(
u'foo'
.
startswith
,
u'foo'
.
endswith
):
with
self
.
assertRaises
(
UnicodeDecodeError
):
meth
(
'
\
xff
'
)
with
self
.
assertRaises
(
TypeError
)
as
cm
:
meth
([
'f'
])
exc
=
str
(
cm
.
exception
)
self
.
assertIn
(
'unicode'
,
exc
)
self
.
assertIn
(
'str'
,
exc
)
self
.
assertIn
(
'tuple'
,
exc
)
@
test_support
.
run_with_locale
(
'LC_ALL'
,
'de_DE'
,
'fr_FR'
)
def
test_format_float
(
self
):
# should not format with a comma, but always with C locale
...
...
Lib/test/test_zipfile.py
View file @
8f374fd1
...
...
@@ -115,20 +115,20 @@ class TestsWithSourceFile(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
,
compression
)
as
zipfp
:
zipdata1
=
[]
zipopen1
=
zipfp
.
open
(
TESTFN
)
while
True
:
read_data
=
zipopen1
.
read
(
256
)
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
with
zipfp
.
open
(
TESTFN
)
as
zipopen1
:
while
True
:
read_data
=
zipopen1
.
read
(
256
)
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
zipdata2
=
[]
zipopen2
=
zipfp
.
open
(
"another.name"
)
while
True
:
read_data
=
zipopen2
.
read
(
256
)
if
not
read_data
:
break
zipdata2
.
append
(
read_data
)
with
zipfp
.
open
(
"another.name"
)
as
zipopen2
:
while
True
:
read_data
=
zipopen2
.
read
(
256
)
if
not
read_data
:
break
zipdata2
.
append
(
read_data
)
self
.
assertEqual
(
''
.
join
(
zipdata1
),
self
.
data
)
self
.
assertEqual
(
''
.
join
(
zipdata2
),
self
.
data
)
...
...
@@ -147,7 +147,8 @@ class TestsWithSourceFile(unittest.TestCase):
infos
=
zipfp
.
infolist
()
data
=
""
for
info
in
infos
:
data
+=
zipfp
.
open
(
info
).
read
()
with
zipfp
.
open
(
info
)
as
f
:
data
+=
f
.
read
()
self
.
assertTrue
(
data
==
"foobar"
or
data
==
"barfoo"
)
data
=
""
for
info
in
infos
:
...
...
@@ -160,12 +161,12 @@ class TestsWithSourceFile(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
,
compression
)
as
zipfp
:
zipdata1
=
[]
zipopen1
=
zipfp
.
open
(
TESTFN
)
while
True
:
read_data
=
zipopen1
.
read
(
randint
(
1
,
1024
))
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
with
zipfp
.
open
(
TESTFN
)
as
zipopen1
:
while
True
:
read_data
=
zipopen1
.
read
(
randint
(
1
,
1024
))
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
self
.
assertEqual
(
''
.
join
(
zipdata1
),
self
.
data
)
...
...
@@ -177,16 +178,14 @@ class TestsWithSourceFile(unittest.TestCase):
f
=
StringIO
()
data
=
'a
\
r
\
n
'
*
16
*
1024
zipfp
=
zipfile
.
ZipFile
(
f
,
'w'
,
zipfile
.
ZIP_STORED
)
zipfp
.
writestr
(
TESTFN
,
data
)
zipfp
.
close
()
with
zipfile
.
ZipFile
(
f
,
'w'
,
zipfile
.
ZIP_STORED
)
as
zipfp
:
zipfp
.
writestr
(
TESTFN
,
data
)
data2
=
''
zipfp
=
zipfile
.
ZipFile
(
f
,
'r'
)
zipopen
=
zipfp
.
open
(
TESTFN
,
'rU'
)
for
line
in
zipopen
:
data2
+=
line
zipfp
.
close
()
with
zipfile
.
ZipFile
(
f
,
'r'
)
as
zipfp
:
with
zipfp
.
open
(
TESTFN
,
'rU'
)
as
zipopen
:
for
line
in
zipopen
:
data2
+=
line
self
.
assertEqual
(
data
,
data2
.
replace
(
'
\
n
'
,
'
\
r
\
n
'
))
...
...
@@ -194,42 +193,41 @@ class TestsWithSourceFile(unittest.TestCase):
self
.
make_test_archive
(
f
,
compression
)
# Read the ZIP archive
zipfp
=
zipfile
.
ZipFile
(
f
,
"r"
)
zipopen
=
zipfp
.
open
(
TESTFN
)
data
=
''
while
True
:
read
=
zipopen
.
readline
()
if
not
read
:
break
data
+=
read
read
=
zipopen
.
read
(
100
)
if
not
read
:
break
data
+=
read
with
zipfile
.
ZipFile
(
f
,
"r"
)
as
zipfp
:
with
zipfp
.
open
(
TESTFN
)
as
zipopen
:
data
=
''
while
True
:
read
=
zipopen
.
readline
()
if
not
read
:
break
data
+=
read
read
=
zipopen
.
read
(
100
)
if
not
read
:
break
data
+=
read
self
.
assertEqual
(
data
,
self
.
data
)
zipfp
.
close
()
def
zip_readline_test
(
self
,
f
,
compression
):
self
.
make_test_archive
(
f
,
compression
)
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
)
as
zipfp
:
zipopen
=
zipfp
.
open
(
TESTFN
)
for
line
in
self
.
line_gen
:
linedata
=
zipopen
.
readline
()
self
.
assertEqual
(
linedata
,
line
+
'
\
n
'
)
with
zipfp
.
open
(
TESTFN
)
as
zipopen
:
for
line
in
self
.
line_gen
:
linedata
=
zipopen
.
readline
()
self
.
assertEqual
(
linedata
,
line
+
'
\
n
'
)
def
zip_readlines_test
(
self
,
f
,
compression
):
self
.
make_test_archive
(
f
,
compression
)
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
)
as
zipfp
:
ziplines
=
zipfp
.
open
(
TESTFN
).
readlines
()
for
line
,
zipline
in
zip
(
self
.
line_gen
,
ziplines
):
self
.
assertEqual
(
zipline
,
line
+
'
\
n
'
)
with
zipfp
.
open
(
TESTFN
)
as
zo
:
ziplines
=
zo
.
readlines
()
for
line
,
zipline
in
zip
(
self
.
line_gen
,
ziplines
):
self
.
assertEqual
(
zipline
,
line
+
'
\
n
'
)
def
zip_iterlines_test
(
self
,
f
,
compression
):
self
.
make_test_archive
(
f
,
compression
)
...
...
@@ -301,9 +299,9 @@ class TestsWithSourceFile(unittest.TestCase):
# Get an open object for strfile
with
zipfile
.
ZipFile
(
TESTFN2
,
"r"
,
zipfile
.
ZIP_DEFLATED
)
as
zipfp
:
openobj
=
zipfp
.
open
(
"strfile"
)
self
.
assertEqual
(
openobj
.
read
(
1
),
'1'
)
self
.
assertEqual
(
openobj
.
read
(
1
),
'2'
)
with
zipfp
.
open
(
"strfile"
)
as
openobj
:
self
.
assertEqual
(
openobj
.
read
(
1
),
'1'
)
self
.
assertEqual
(
openobj
.
read
(
1
),
'2'
)
def
test_absolute_arcnames
(
self
):
with
zipfile
.
ZipFile
(
TESTFN2
,
"w"
,
zipfile
.
ZIP_STORED
)
as
zipfp
:
...
...
@@ -775,8 +773,8 @@ class OtherTests(unittest.TestCase):
self
.
assertRaises
(
IOError
,
zipfile
.
ZipFile
,
TESTFN
)
def
test_empty_file_raises_BadZipFile
(
self
):
f
=
open
(
TESTFN
,
'w'
)
f
.
close
()
with
open
(
TESTFN
,
'w'
)
as
f
:
pass
self
.
assertRaises
(
zipfile
.
BadZipfile
,
zipfile
.
ZipFile
,
TESTFN
)
with
open
(
TESTFN
,
'w'
)
as
fp
:
...
...
@@ -820,11 +818,11 @@ class OtherTests(unittest.TestCase):
with
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"w"
)
as
zipf
:
zipf
.
writestr
(
"foo.txt"
,
"O, for a Muse of Fire!"
)
# read the data to make sure the file is there
f
=
zipf
.
open
(
"foo.txt"
)
for
i
in
xrange
(
FIXEDTEST_SIZE
):
self
.
assertEqual
(
f
.
read
(
0
),
''
)
with
zipf
.
open
(
"foo.txt"
)
as
f
:
for
i
in
xrange
(
FIXEDTEST_SIZE
):
self
.
assertEqual
(
f
.
read
(
0
),
''
)
self
.
assertEqual
(
f
.
read
(),
"O, for a Muse of Fire!"
)
self
.
assertEqual
(
f
.
read
(),
"O, for a Muse of Fire!"
)
def
test_open_non_existent_item
(
self
):
"""Check that attempting to call open() for an item that doesn't
...
...
@@ -952,15 +950,15 @@ class OtherTests(unittest.TestCase):
def
test_empty_zipfile
(
self
):
# Check that creating a file in 'w' or 'a' mode and closing without
# adding any files to the archives creates a valid empty ZIP file
zipf
=
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"w"
)
zipf
.
close
()
with
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"w"
)
as
zipf
:
pass
try
:
zipf
=
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"r"
)
except
zipfile
.
BadZipfile
:
self
.
fail
(
"Unable to create empty ZIP file in 'w' mode"
)
zipf
=
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"a"
)
zipf
.
close
()
with
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"a"
)
as
zipf
:
pass
try
:
zipf
=
zipfile
.
ZipFile
(
TESTFN
,
mode
=
"r"
)
except
:
...
...
@@ -970,8 +968,8 @@ class OtherTests(unittest.TestCase):
# Issue 1710703: Check that opening a file with less than 22 bytes
# raises a BadZipfile exception (rather than the previously unhelpful
# IOError)
f
=
open
(
TESTFN
,
'w'
)
f
.
close
()
with
open
(
TESTFN
,
'w'
)
as
f
:
pass
self
.
assertRaises
(
zipfile
.
BadZipfile
,
zipfile
.
ZipFile
,
TESTFN
,
'r'
)
def
tearDown
(
self
):
...
...
@@ -1084,20 +1082,20 @@ class TestsWithRandomBinaryFiles(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
,
compression
)
as
zipfp
:
zipdata1
=
[]
zipopen1
=
zipfp
.
open
(
TESTFN
)
while
True
:
read_data
=
zipopen1
.
read
(
256
)
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
with
zipfp
.
open
(
TESTFN
)
as
zipopen1
:
while
True
:
read_data
=
zipopen1
.
read
(
256
)
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
zipdata2
=
[]
zipopen2
=
zipfp
.
open
(
"another.name"
)
while
True
:
read_data
=
zipopen2
.
read
(
256
)
if
not
read_data
:
break
zipdata2
.
append
(
read_data
)
with
zipfp
.
open
(
"another.name"
)
as
zipopen2
:
while
True
:
read_data
=
zipopen2
.
read
(
256
)
if
not
read_data
:
break
zipdata2
.
append
(
read_data
)
testdata1
=
''
.
join
(
zipdata1
)
self
.
assertEqual
(
len
(
testdata1
),
len
(
self
.
data
))
...
...
@@ -1122,12 +1120,12 @@ class TestsWithRandomBinaryFiles(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
,
compression
)
as
zipfp
:
zipdata1
=
[]
zipopen1
=
zipfp
.
open
(
TESTFN
)
while
True
:
read_data
=
zipopen1
.
read
(
randint
(
1
,
1024
))
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
with
zipfp
.
open
(
TESTFN
)
as
zipopen1
:
while
True
:
read_data
=
zipopen1
.
read
(
randint
(
1
,
1024
))
if
not
read_data
:
break
zipdata1
.
append
(
read_data
)
testdata
=
''
.
join
(
zipdata1
)
self
.
assertEqual
(
len
(
testdata
),
len
(
self
.
data
))
...
...
@@ -1167,12 +1165,11 @@ class TestsWithMultipleOpens(unittest.TestCase):
# Verify that (when the ZipFile is in control of creating file objects)
# multiple open() calls can be made without interfering with each other.
with
zipfile
.
ZipFile
(
TESTFN2
,
mode
=
"r"
)
as
zipf
:
zopen1
=
zipf
.
open
(
'ones'
)
zopen2
=
zipf
.
open
(
'twos'
)
data1
=
zopen1
.
read
(
500
)
data2
=
zopen2
.
read
(
500
)
data1
+=
zopen1
.
read
(
500
)
data2
+=
zopen2
.
read
(
500
)
with
zipf
.
open
(
'ones'
)
as
zopen1
,
zipf
.
open
(
'twos'
)
as
zopen2
:
data1
=
zopen1
.
read
(
500
)
data2
=
zopen2
.
read
(
500
)
data1
+=
zopen1
.
read
(
500
)
data2
+=
zopen2
.
read
(
500
)
self
.
assertEqual
(
data1
,
'1'
*
FIXEDTEST_SIZE
)
self
.
assertEqual
(
data2
,
'2'
*
FIXEDTEST_SIZE
)
...
...
@@ -1180,12 +1177,11 @@ class TestsWithMultipleOpens(unittest.TestCase):
# Verify that (when the ZipFile is in control of creating file objects)
# multiple open() calls can be made without interfering with each other.
with
zipfile
.
ZipFile
(
TESTFN2
,
mode
=
"r"
)
as
zipf
:
zopen1
=
zipf
.
open
(
'ones'
)
data1
=
zopen1
.
read
(
500
)
zopen2
=
zipf
.
open
(
'twos'
)
data2
=
zopen2
.
read
(
500
)
data1
+=
zopen1
.
read
(
500
)
data2
+=
zopen2
.
read
(
500
)
with
zipf
.
open
(
'ones'
)
as
zopen1
,
zipf
.
open
(
'twos'
)
as
zopen2
:
data1
=
zopen1
.
read
(
500
)
data2
=
zopen2
.
read
(
500
)
data1
+=
zopen1
.
read
(
500
)
data2
+=
zopen2
.
read
(
500
)
self
.
assertEqual
(
data1
,
'1'
*
FIXEDTEST_SIZE
)
self
.
assertEqual
(
data2
,
'2'
*
FIXEDTEST_SIZE
)
...
...
@@ -1244,7 +1240,8 @@ class UniversalNewlineTests(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
)
as
zipfp
:
for
sep
,
fn
in
self
.
arcfiles
.
items
():
zipdata
=
zipfp
.
open
(
fn
,
"rU"
).
read
()
with
zipfp
.
open
(
fn
,
"rU"
)
as
fp
:
zipdata
=
fp
.
read
()
self
.
assertEqual
(
self
.
arcdata
[
sep
],
zipdata
)
def
readline_read_test
(
self
,
f
,
compression
):
...
...
@@ -1253,18 +1250,18 @@ class UniversalNewlineTests(unittest.TestCase):
# Read the ZIP archive
zipfp
=
zipfile
.
ZipFile
(
f
,
"r"
)
for
sep
,
fn
in
self
.
arcfiles
.
items
():
zipopen
=
zipfp
.
open
(
fn
,
"rU"
)
data
=
''
while
True
:
read
=
zipopen
.
readline
()
if
not
read
:
break
data
+=
read
read
=
zipopen
.
read
(
5
)
if
not
read
:
break
data
+=
read
with
zipfp
.
open
(
fn
,
"rU"
)
as
zipopen
:
data
=
''
while
True
:
read
=
zipopen
.
readline
()
if
not
read
:
break
data
+=
read
read
=
zipopen
.
read
(
5
)
if
not
read
:
break
data
+=
read
self
.
assertEqual
(
data
,
self
.
arcdata
[
'
\
n
'
])
...
...
@@ -1276,10 +1273,10 @@ class UniversalNewlineTests(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
)
as
zipfp
:
for
sep
,
fn
in
self
.
arcfiles
.
items
():
zipopen
=
zipfp
.
open
(
fn
,
"rU"
)
for
line
in
self
.
line_gen
:
linedata
=
zipopen
.
readline
()
self
.
assertEqual
(
linedata
,
line
+
'
\
n
'
)
with
zipfp
.
open
(
fn
,
"rU"
)
as
zipopen
:
for
line
in
self
.
line_gen
:
linedata
=
zipopen
.
readline
()
self
.
assertEqual
(
linedata
,
line
+
'
\
n
'
)
def
readlines_test
(
self
,
f
,
compression
):
self
.
make_test_archive
(
f
,
compression
)
...
...
@@ -1287,7 +1284,8 @@ class UniversalNewlineTests(unittest.TestCase):
# Read the ZIP archive
with
zipfile
.
ZipFile
(
f
,
"r"
)
as
zipfp
:
for
sep
,
fn
in
self
.
arcfiles
.
items
():
ziplines
=
zipfp
.
open
(
fn
,
"rU"
).
readlines
()
with
zipfp
.
open
(
fn
,
"rU"
)
as
fp
:
ziplines
=
fp
.
readlines
()
for
line
,
zipline
in
zip
(
self
.
line_gen
,
ziplines
):
self
.
assertEqual
(
zipline
,
line
+
'
\
n
'
)
...
...
Lib/unittest/case.py
View file @
8f374fd1
...
...
@@ -169,6 +169,10 @@ class TestCase(object):
maxDiff
=
80
*
8
# If a string is longer than _diffThreshold, use normal comparison instead
# of difflib. See #11763.
_diffThreshold
=
2
**
16
# Attribute used by TestSuite for classSetUp
_classSetupFailed
=
False
...
...
@@ -900,6 +904,10 @@ class TestCase(object):
'Second argument is not a string'
)
if
first
!=
second
:
# don't use difflib if the strings are too long
if
(
len
(
first
)
>
self
.
_diffThreshold
or
len
(
second
)
>
self
.
_diffThreshold
):
self
.
_baseAssertEqual
(
first
,
second
,
msg
)
firstlines
=
first
.
splitlines
(
True
)
secondlines
=
second
.
splitlines
(
True
)
if
len
(
firstlines
)
==
1
and
first
.
strip
(
'
\
r
\
n
'
)
==
first
:
...
...
Lib/unittest/test/test_case.py
View file @
8f374fd1
...
...
@@ -667,6 +667,42 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing):
else
:
self
.
fail
(
'assertMultiLineEqual did not fail'
)
def
testAssertEqual_diffThreshold
(
self
):
# check threshold value
self
.
assertEqual
(
self
.
_diffThreshold
,
2
**
16
)
# disable madDiff to get diff markers
self
.
maxDiff
=
None
# set a lower threshold value and add a cleanup to restore it
old_threshold
=
self
.
_diffThreshold
self
.
_diffThreshold
=
2
**
8
self
.
addCleanup
(
lambda
:
setattr
(
self
,
'_diffThreshold'
,
old_threshold
))
# under the threshold: diff marker (^) in error message
s
=
u'x'
*
(
2
**
7
)
with
self
.
assertRaises
(
self
.
failureException
)
as
cm
:
self
.
assertEqual
(
s
+
'a'
,
s
+
'b'
)
self
.
assertIn
(
'^'
,
str
(
cm
.
exception
))
self
.
assertEqual
(
s
+
'a'
,
s
+
'a'
)
# over the threshold: diff not used and marker (^) not in error message
s
=
u'x'
*
(
2
**
9
)
# if the path that uses difflib is taken, _truncateMessage will be
# called -- replace it with explodingTruncation to verify that this
# doesn't happen
def
explodingTruncation
(
message
,
diff
):
raise
SystemError
(
'this should not be raised'
)
old_truncate
=
self
.
_truncateMessage
self
.
_truncateMessage
=
explodingTruncation
self
.
addCleanup
(
lambda
:
setattr
(
self
,
'_truncateMessage'
,
old_truncate
))
s1
,
s2
=
s
+
'a'
,
s
+
'b'
with
self
.
assertRaises
(
self
.
failureException
)
as
cm
:
self
.
assertEqual
(
s1
,
s2
)
self
.
assertNotIn
(
'^'
,
str
(
cm
.
exception
))
self
.
assertEqual
(
str
(
cm
.
exception
),
'%r != %r'
%
(
s1
,
s2
))
self
.
assertEqual
(
s
+
'a'
,
s
+
'a'
)
def
testAssertItemsEqual
(
self
):
a
=
object
()
self
.
assertItemsEqual
([
1
,
2
,
3
],
[
3
,
2
,
1
])
...
...
Misc/ACKS
View file @
8f374fd1
...
...
@@ -60,6 +60,7 @@ Donald Beaudry
David Beazley
Robin Becker
Neal Becker
Torsten Becker
Bill Bedford
Reimer Behrends
Ben Bell
...
...
@@ -410,6 +411,7 @@ Irmen de Jong
Lucas de Jonge
John Jorgensen
Jens B. Jorgensen
Sijin Joseph
Andreas Jung
Tattoo Mabonzo K.
Bob Kahn
...
...
@@ -794,6 +796,7 @@ Steven Taschuk
Monty Taylor
Amy Taylor
Anatoly Techtonik
Mikhail Terekhov
Tobias Thelen
James Thomas
Robin Thomas
...
...
Misc/NEWS
View file @
8f374fd1
...
...
@@ -9,6 +9,13 @@ What's New in Python 2.7.2?
Core and Builtins
-----------------
- Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_*
APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch
by Charles-François Natali.
- Issue #6780: fix starts/endswith error message to mention that tuples are
accepted too.
- Issue #5057: fix a bug in the peepholer that led to non-portable pyc files
between narrow and wide builds while optimizing BINARY_SUBSCR on non-BMP
chars (e.g. u"\U00012345"[0]).
...
...
@@ -43,6 +50,9 @@ Core and Builtins
rather than the Py_IsInitialized flag, avoiding a Fatal Python
error in certain circumstances when an import is done in __del__.
- issue #11828: startswith and endswith don'
t
accept
None
as
slice
index
.
Patch
by
Torsten
Becker
.
-
Issue
#
10674
:
Remove
unused
'dictmaker'
rule
from
grammar
.
-
Issue
#
10596
:
Fix
float
.
__mod__
to
have
the
same
behaviour
as
...
...
@@ -55,9 +65,29 @@ Core and Builtins
Library
-------
-
Issue
#
10761
:
Fix
tarfile
.
extractall
failure
when
symlinked
files
are
present
.
Initial
patch
by
Scott
Leerssen
.
-
Issue
#
11763
:
don
't use difflib in TestCase.assertMultiLineEqual if the
strings are too long.
- Issue #11236: getpass.getpass responds to ctrl-c or ctrl-z on terminal.
- Issue #11768: The signal handler of the signal module only calls
Py_AddPendingCall() for the first signal to fix a deadlock on reentrant or
parallel calls. PyErr_SetInterrupt() writes also into the wake up file.
- Issue #11875: collections.OrderedDict'
s
__reduce__
was
temporarily
mutating
the
object
instead
of
just
working
on
a
copy
.
-
Issue
#
11442
:
Add
a
charset
parameter
to
the
Content
-
type
in
SimpleHTTPServer
to
avoid
XSS
attacks
.
-
Issue
#
11467
:
Fix
urlparse
behavior
when
handling
urls
which
contains
scheme
specific
part
only
digits
.
Patch
by
Santoso
Wijaya
.
-
collections
.
Counter
().
copy
()
now
works
correctly
for
subclasses
.
-
Issue
#
11474
:
Fix
the
bug
with
url2pathname
()
handling
of
'/C|/'
on
Windows
.
Patch
by
Santoso
Wijaya
.
...
...
@@ -358,6 +388,8 @@ IDLE
Tests
-----
-
Fix
test_startfile
to
wait
for
child
process
to
terminate
before
finishing
.
-
Issue
#
11719
:
Fix
message
about
unexpected
test_msilib
skip
on
non
-
Windows
platforms
.
Patch
by
Nadeem
Vawda
.
...
...
Modules/signalmodule.c
View file @
8f374fd1
...
...
@@ -166,6 +166,20 @@ checksignals_witharg(void * unused)
return
PyErr_CheckSignals
();
}
static
void
trip_signal
(
int
sig_num
)
{
Handlers
[
sig_num
].
tripped
=
1
;
if
(
is_tripped
)
return
;
/* Set is_tripped after setting .tripped, as it gets
cleared in PyErr_CheckSignals() before .tripped. */
is_tripped
=
1
;
Py_AddPendingCall
(
checksignals_witharg
,
NULL
);
if
(
wakeup_fd
!=
-
1
)
write
(
wakeup_fd
,
"
\0
"
,
1
);
}
static
void
signal_handler
(
int
sig_num
)
{
...
...
@@ -183,13 +197,7 @@ signal_handler(int sig_num)
if
(
getpid
()
==
main_pid
)
#endif
{
Handlers
[
sig_num
].
tripped
=
1
;
/* Set is_tripped after setting .tripped, as it gets
cleared in PyErr_CheckSignals() before .tripped. */
is_tripped
=
1
;
Py_AddPendingCall
(
checksignals_witharg
,
NULL
);
if
(
wakeup_fd
!=
-
1
)
write
(
wakeup_fd
,
"
\0
"
,
1
);
trip_signal
(
sig_num
);
}
#ifndef HAVE_SIGACTION
...
...
@@ -934,9 +942,7 @@ PyErr_CheckSignals(void)
void
PyErr_SetInterrupt
(
void
)
{
is_tripped
=
1
;
Handlers
[
SIGINT
].
tripped
=
1
;
Py_AddPendingCall
((
int
(
*
)(
void
*
))
PyErr_CheckSignals
,
NULL
);
trip_signal
(
SIGINT
);
}
void
...
...
@@ -970,6 +976,7 @@ void
PyOS_AfterFork
(
void
)
{
#ifdef WITH_THREAD
_PyGILState_Reinit
();
PyEval_ReInitThreads
();
main_thread
=
PyThread_get_thread_ident
();
main_pid
=
getpid
();
...
...
Objects/bytearrayobject.c
View file @
8f374fd1
...
...
@@ -1149,8 +1149,8 @@ bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_ssize_t
res
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:find/rfind/index/rindex"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"find/rfind/index/rindex"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
-
2
;
if
(
_getbuffer
(
subobj
,
&
subbuf
)
<
0
)
return
-
2
;
...
...
@@ -1200,8 +1200,7 @@ bytearray_count(PyByteArrayObject *self, PyObject *args)
Py_buffer
vsub
;
PyObject
*
count_obj
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:count"
,
&
sub_obj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"count"
,
args
,
&
sub_obj
,
&
start
,
&
end
))
return
NULL
;
if
(
_getbuffer
(
sub_obj
,
&
vsub
)
<
0
)
...
...
@@ -1359,8 +1358,7 @@ bytearray_startswith(PyByteArrayObject *self, PyObject *args)
PyObject
*
subobj
;
int
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:startswith"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"startswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
...
...
@@ -1399,8 +1397,7 @@ bytearray_endswith(PyByteArrayObject *self, PyObject *args)
PyObject
*
subobj
;
int
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:endswith"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"endswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
...
...
Objects/stringlib/find.h
View file @
8f374fd1
...
...
@@ -93,32 +93,33 @@ stringlib_contains_obj(PyObject* str, PyObject* sub)
#endif
/* STRINGLIB_WANT_CONTAINS_OBJ */
#if STRINGLIB_IS_UNICODE
/*
This function is a helper for the "find" family (find, rfind, index,
rindex)
of unicodeobject.c file, because they all have the same
behaviour for the arguments.
rindex)
and for count, startswith and endswith, because they all have
the same
behaviour for the arguments.
It does not touch the variables received until it knows everything
is ok.
Note that we receive a pointer to the pointer of the substring object,
so when we create that object in this function we don't DECREF it,
because it continues living in the caller functions (those functions,
after finishing using the substring, must DECREF it).
*/
#define FORMAT_BUFFER_SIZE 50
Py_LOCAL_INLINE
(
int
)
_ParseTupleFinds
(
PyObject
*
args
,
PyObject
**
substring
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
PyObject
*
tmp_substring
;
stringlib_parse_args_finds
(
const
char
*
function_name
,
PyObject
*
args
,
PyObject
**
subobj
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
PyObject
*
tmp_subobj
;
Py_ssize_t
tmp_start
=
0
;
Py_ssize_t
tmp_end
=
PY_SSIZE_T_MAX
;
PyObject
*
obj_start
=
Py_None
,
*
obj_end
=
Py_None
;
char
format
[
FORMAT_BUFFER_SIZE
]
=
"O|OO:"
;
size_t
len
=
strlen
(
format
);
if
(
!
PyArg_ParseTuple
(
args
,
"O|OO:find"
,
&
tmp_substring
,
&
obj_start
,
&
obj_end
))
strncpy
(
format
+
len
,
function_name
,
FORMAT_BUFFER_SIZE
-
len
-
1
);
format
[
FORMAT_BUFFER_SIZE
-
1
]
=
'\0'
;
if
(
!
PyArg_ParseTuple
(
args
,
format
,
&
tmp_subobj
,
&
obj_start
,
&
obj_end
))
return
0
;
/* To support None in "start" and "end" arguments, meaning
...
...
@@ -131,16 +132,44 @@ _ParseTupleFinds (PyObject *args, PyObject **substring,
if
(
!
_PyEval_SliceIndex
(
obj_end
,
&
tmp_end
))
return
0
;
tmp_substring
=
PyUnicode_FromObject
(
tmp_substring
);
if
(
!
tmp_substring
)
return
0
;
*
start
=
tmp_start
;
*
end
=
tmp_end
;
*
sub
string
=
tmp_substring
;
*
sub
obj
=
tmp_subobj
;
return
1
;
}
#undef FORMAT_BUFFER_SIZE
#if STRINGLIB_IS_UNICODE
/*
Wraps stringlib_parse_args_finds() and additionally ensures that the
first argument is a unicode object.
Note that we receive a pointer to the pointer of the substring object,
so when we create that object in this function we don't DECREF it,
because it continues living in the caller functions (those functions,
after finishing using the substring, must DECREF it).
*/
Py_LOCAL_INLINE
(
int
)
stringlib_parse_args_finds_unicode
(
const
char
*
function_name
,
PyObject
*
args
,
PyUnicodeObject
**
substring
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
PyObject
*
tmp_substring
;
if
(
stringlib_parse_args_finds
(
function_name
,
args
,
&
tmp_substring
,
start
,
end
))
{
tmp_substring
=
PyUnicode_FromObject
(
tmp_substring
);
if
(
!
tmp_substring
)
return
0
;
*
substring
=
(
PyUnicodeObject
*
)
tmp_substring
;
return
1
;
}
return
0
;
}
#endif
/* STRINGLIB_IS_UNICODE */
#endif
/* STRINGLIB_FIND_H */
Objects/stringobject.c
View file @
8f374fd1
...
...
@@ -1693,19 +1693,9 @@ string_find_internal(PyStringObject *self, PyObject *args, int dir)
const
char
*
sub
;
Py_ssize_t
sub_len
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
PyObject
*
obj_start
=
Py_None
,
*
obj_end
=
Py_None
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|OO:find/rfind/index/rindex"
,
&
subobj
,
&
obj_start
,
&
obj_end
))
return
-
2
;
/* To support None in "start" and "end" arguments, meaning
the same as if they were not passed.
*/
if
(
obj_start
!=
Py_None
)
if
(
!
_PyEval_SliceIndex
(
obj_start
,
&
start
))
return
-
2
;
if
(
obj_end
!=
Py_None
)
if
(
!
_PyEval_SliceIndex
(
obj_end
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"find/rfind/index/rindex"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
-
2
;
if
(
PyString_Check
(
subobj
))
{
...
...
@@ -2117,8 +2107,7 @@ string_count(PyStringObject *self, PyObject *args)
Py_ssize_t
sub_len
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:count"
,
&
sub_obj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"count"
,
args
,
&
sub_obj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyString_Check
(
sub_obj
))
{
...
...
@@ -2912,8 +2901,7 @@ string_startswith(PyStringObject *self, PyObject *args)
PyObject
*
subobj
;
int
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:startswith"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"startswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
...
...
@@ -2930,8 +2918,12 @@ string_startswith(PyStringObject *self, PyObject *args)
Py_RETURN_FALSE
;
}
result
=
_string_tailmatch
(
self
,
subobj
,
start
,
end
,
-
1
);
if
(
result
==
-
1
)
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"startswith first arg must be str, "
"unicode, or tuple, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
}
...
...
@@ -2953,8 +2945,7 @@ string_endswith(PyStringObject *self, PyObject *args)
PyObject
*
subobj
;
int
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:endswith"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"endswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
...
...
@@ -2971,8 +2962,12 @@ string_endswith(PyStringObject *self, PyObject *args)
Py_RETURN_FALSE
;
}
result
=
_string_tailmatch
(
self
,
subobj
,
start
,
end
,
+
1
);
if
(
result
==
-
1
)
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"endswith first arg must be str, "
"unicode, or tuple, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
}
...
...
Objects/unicodeobject.c
View file @
8f374fd1
...
...
@@ -6308,13 +6308,8 @@ unicode_count(PyUnicodeObject *self, PyObject *args)
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
PyObject
*
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:count"
,
&
substring
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
return
NULL
;
substring
=
(
PyUnicodeObject
*
)
PyUnicode_FromObject
(
(
PyObject
*
)
substring
);
if
(
substring
==
NULL
)
if
(
!
stringlib_parse_args_finds_unicode
(
"count"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
ADJUST_INDICES
(
start
,
end
,
self
->
length
);
...
...
@@ -6504,12 +6499,13 @@ Return -1 on failure.");
static
PyObject
*
unicode_find
(
PyUnicodeObject
*
self
,
PyObject
*
args
)
{
PyObject
*
substring
;
Py
Unicode
Object
*
substring
;
Py_ssize_t
start
;
Py_ssize_t
end
;
Py_ssize_t
result
;
if
(
!
_ParseTupleFinds
(
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
stringlib_parse_args_finds_unicode
(
"find"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
result
=
stringlib_find_slice
(
...
...
@@ -6570,11 +6566,12 @@ static PyObject *
unicode_index
(
PyUnicodeObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
;
PyObject
*
substring
;
Py
Unicode
Object
*
substring
;
Py_ssize_t
start
;
Py_ssize_t
end
;
if
(
!
_ParseTupleFinds
(
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
stringlib_parse_args_finds_unicode
(
"index"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
result
=
stringlib_find_slice
(
...
...
@@ -7237,12 +7234,13 @@ Return -1 on failure.");
static
PyObject
*
unicode_rfind
(
PyUnicodeObject
*
self
,
PyObject
*
args
)
{
PyObject
*
substring
;
Py
Unicode
Object
*
substring
;
Py_ssize_t
start
;
Py_ssize_t
end
;
Py_ssize_t
result
;
if
(
!
_ParseTupleFinds
(
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
stringlib_parse_args_finds_unicode
(
"rfind"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
result
=
stringlib_rfind_slice
(
...
...
@@ -7264,12 +7262,13 @@ Like S.rfind() but raise ValueError when the substring is not found.");
static
PyObject
*
unicode_rindex
(
PyUnicodeObject
*
self
,
PyObject
*
args
)
{
PyObject
*
substring
;
Py
Unicode
Object
*
substring
;
Py_ssize_t
start
;
Py_ssize_t
end
;
Py_ssize_t
result
;
if
(
!
_ParseTupleFinds
(
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
stringlib_parse_args_finds_unicode
(
"rindex"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
result
=
stringlib_rfind_slice
(
...
...
@@ -7648,8 +7647,7 @@ unicode_startswith(PyUnicodeObject *self,
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
int
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:startswith"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"startswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
...
...
@@ -7668,8 +7666,12 @@ unicode_startswith(PyUnicodeObject *self,
Py_RETURN_FALSE
;
}
substring
=
(
PyUnicodeObject
*
)
PyUnicode_FromObject
(
subobj
);
if
(
substring
==
NULL
)
if
(
substring
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"startswith first arg must be str, "
"unicode, or tuple, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
result
=
tailmatch
(
self
,
substring
,
start
,
end
,
-
1
);
Py_DECREF
(
substring
);
return
PyBool_FromLong
(
result
);
...
...
@@ -7694,8 +7696,7 @@ unicode_endswith(PyUnicodeObject *self,
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
int
result
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|O&O&:endswith"
,
&
subobj
,
_PyEval_SliceIndex
,
&
start
,
_PyEval_SliceIndex
,
&
end
))
if
(
!
stringlib_parse_args_finds
(
"endswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
...
...
@@ -7713,9 +7714,12 @@ unicode_endswith(PyUnicodeObject *self,
Py_RETURN_FALSE
;
}
substring
=
(
PyUnicodeObject
*
)
PyUnicode_FromObject
(
subobj
);
if
(
substring
==
NULL
)
if
(
substring
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"endswith first arg must be str, "
"unicode, or tuple, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
result
=
tailmatch
(
self
,
substring
,
start
,
end
,
+
1
);
Py_DECREF
(
substring
);
return
PyBool_FromLong
(
result
);
...
...
Python/pystate.c
View file @
8f374fd1
...
...
@@ -537,6 +537,23 @@ _PyGILState_Fini(void)
autoInterpreterState
=
NULL
;
}
/* Reset the TLS key - called by PyOS_AfterFork.
* This should not be necessary, but some - buggy - pthread implementations
* don't flush TLS on fork, see issue #10517.
*/
void
_PyGILState_Reinit
(
void
)
{
PyThreadState
*
tstate
=
PyGILState_GetThisThreadState
();
PyThread_delete_key
(
autoTLSkey
);
if
((
autoTLSkey
=
PyThread_create_key
())
==
-
1
)
Py_FatalError
(
"Could not allocate TLS entry"
);
/* re-associate the current thread state with the new key */
if
(
PyThread_set_key_value
(
autoTLSkey
,
(
void
*
)
tstate
)
<
0
)
Py_FatalError
(
"Couldn't create autoTLSkey mapping"
);
}
/* When a thread state is created for a thread by some mechanism other than
PyGILState_Ensure, it's important that the GILState machinery knows about
it so it doesn't try to create another thread state for the thread (this is
...
...
Tools/pybench/pybench.py
View file @
8f374fd1
...
...
@@ -278,7 +278,7 @@ class Test:
for
i
in
calibration_loops
:
pass
t
=
timer
()
-
t
prep_times
.
append
(
t
)
prep_times
.
append
(
t
/
CALIBRATION_LOOPS
)
min_prep_time
=
min
(
prep_times
)
if
_debug
:
print
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment