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
0e7df431
Commit
0e7df431
authored
Apr 06, 2013
by
Benjamin Peterson
Browse files
Options
Browse Files
Download
Plain Diff
merge heads
parents
89e2aed9
bb84565c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
207 additions
and
14 deletions
+207
-14
Doc/howto/argparse.rst
Doc/howto/argparse.rst
+2
-2
Lib/test/test_itertools.py
Lib/test/test_itertools.py
+134
-1
Misc/NEWS
Misc/NEWS
+3
-1
Modules/itertoolsmodule.c
Modules/itertoolsmodule.c
+65
-10
Objects/abstract.c
Objects/abstract.c
+3
-0
No files found.
Doc/howto/argparse.rst
View file @
0e7df431
...
...
@@ -668,8 +668,8 @@ Conflicting options
So far, we have been working with two methods of an
:class:`argparse.ArgumentParser` instance. Let's introduce a third one,
:meth:`add_mutually_exclusive_group`. It allows for us to specify options that
conflict with each other. Let's also change the rest of the program
to make the
new functionality makes more sense:
conflict with each other. Let's also change the rest of the program
so that
the
new functionality makes more sense:
we'll introduce the ``--quiet`` option,
which will be the opposite of the ``--verbose`` one::
...
...
Lib/test/test_itertools.py
View file @
0e7df431
...
...
@@ -1413,6 +1413,139 @@ class SubclassWithKwargsTest(unittest.TestCase):
self
.
assertNotIn
(
"does not take keyword arguments"
,
err
.
args
[
0
])
class
TestRecursionLimit
(
unittest
.
TestCase
):
# Issue #14010
recursionlimit
=
sys
.
getrecursionlimit
()
def
test_chain
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
chain
(
it
,
())
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_compress
(
self
):
data
=
(
0
,
1
)
selectors
=
(
True
,
True
)
it
=
data
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
compress
(
it
,
selectors
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
it
=
selectors
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
compress
(
data
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_cycle
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
cycle
(
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
range
(
3
):
next
(
it
)
del
it
def
test_dropwhile
(
self
):
it
=
(
0
,
1
,
0
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
dropwhile
(
bool
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_ifilter
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
ifilter
(
bool
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_ifilterfalse
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
ifilterfalse
(
bool
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_groupby
(
self
):
key
=
operator
.
itemgetter
(
0
)
it
=
((
0
,
[]),
(
1
,
[]))
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
groupby
(
it
,
key
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_imap
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
imap
(
int
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_islice
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
islice
(
it
,
2
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_starmap
(
self
):
it
=
'ab'
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
starmap
(
tuple
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_takewhile
(
self
):
it
=
(
1
,
0
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
takewhile
(
bool
,
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_izip
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
izip
(
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
def
test_izip_longest
(
self
):
it
=
(
0
,
1
)
for
_
in
xrange
(
self
.
recursionlimit
):
it
=
izip_longest
(
it
)
with
self
.
assertRaises
(
RuntimeError
):
for
_
in
it
:
pass
del
it
libreftest
=
""" Doctest for examples in the library reference: libitertools.tex
...
...
@@ -1645,7 +1778,7 @@ __test__ = {'libreftest' : libreftest}
def
test_main
(
verbose
=
None
):
test_classes
=
(
TestBasicOps
,
TestVariousIteratorArgs
,
TestGC
,
RegressionTests
,
LengthTransparency
,
SubclassWithKwargsTest
,
TestExamples
)
SubclassWithKwargsTest
,
TestExamples
,
TestRecursionLimit
)
test_support
.
run_unittest
(
*
test_classes
)
# verify reference counting
...
...
Misc/NEWS
View file @
0e7df431
...
...
@@ -11,6 +11,8 @@ Core and Builtins
Library
-------
- Issue #14010: Fix a crash when iterating or deleting deeply nested filters
in itertools module (i.e. itertools.izip(), itertools.chain(), etc).
- Issue #13163: Rename operands in smtplib.SMTP._get_socket to correct names;
fixes otherwise misleading output in tracebacks and when when debug is on.
...
...
@@ -288,7 +290,7 @@ Library
- Issue #12718: Fix interaction with winpdb overriding __import__ by setting
importer attribute on BaseConfigurator instance.
- Issue #17521: Corrected non-enabling of logger following two calls to
fileConfig().
...
...
Modules/itertoolsmodule.c
View file @
0e7df431
...
...
@@ -54,12 +54,14 @@ static void
groupby_dealloc
(
groupbyobject
*
gbo
)
{
PyObject_GC_UnTrack
(
gbo
);
Py_TRASHCAN_SAFE_BEGIN
(
gbo
)
Py_XDECREF
(
gbo
->
it
);
Py_XDECREF
(
gbo
->
keyfunc
);
Py_XDECREF
(
gbo
->
tgtkey
);
Py_XDECREF
(
gbo
->
currkey
);
Py_XDECREF
(
gbo
->
currvalue
);
Py_TYPE
(
gbo
)
->
tp_free
(
gbo
);
Py_TRASHCAN_SAFE_END
(
gbo
)
}
static
int
...
...
@@ -741,9 +743,11 @@ static void
cycle_dealloc
(
cycleobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
saved
);
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -886,9 +890,11 @@ static void
dropwhile_dealloc
(
dropwhileobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
func
);
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -909,7 +915,10 @@ dropwhile_next(dropwhileobject *lz)
iternext
=
*
Py_TYPE
(
it
)
->
tp_iternext
;
for
(;;)
{
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
item
=
iternext
(
it
);
Py_LeaveRecursiveCall
();
if
(
item
==
NULL
)
return
NULL
;
if
(
lz
->
start
==
1
)
...
...
@@ -1030,9 +1039,11 @@ static void
takewhile_dealloc
(
takewhileobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
func
);
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -1053,7 +1064,10 @@ takewhile_next(takewhileobject *lz)
if
(
lz
->
stop
==
1
)
return
NULL
;
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
Py_LeaveRecursiveCall
();
if
(
item
==
NULL
)
return
NULL
;
...
...
@@ -1221,8 +1235,10 @@ static void
islice_dealloc
(
isliceobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -1243,7 +1259,10 @@ islice_next(isliceobject *lz)
iternext
=
*
Py_TYPE
(
it
)
->
tp_iternext
;
while
(
lz
->
cnt
<
lz
->
next
)
{
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
item
=
iternext
(
it
);
Py_LeaveRecursiveCall
();
if
(
item
==
NULL
)
return
NULL
;
Py_DECREF
(
item
);
...
...
@@ -1251,7 +1270,10 @@ islice_next(isliceobject *lz)
}
if
(
stop
!=
-
1
&&
lz
->
cnt
>=
stop
)
return
NULL
;
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
item
=
iternext
(
it
);
Py_LeaveRecursiveCall
();
if
(
item
==
NULL
)
return
NULL
;
lz
->
cnt
++
;
...
...
@@ -1364,9 +1386,11 @@ static void
starmap_dealloc
(
starmapobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
func
);
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -1384,7 +1408,10 @@ starmap_next(starmapobject *lz)
PyObject
*
result
;
PyObject
*
it
=
lz
->
it
;
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
args
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
Py_LeaveRecursiveCall
();
if
(
args
==
NULL
)
return
NULL
;
if
(
!
PyTuple_CheckExact
(
args
))
{
...
...
@@ -1509,9 +1536,11 @@ static void
imap_dealloc
(
imapobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
iters
);
Py_XDECREF
(
lz
->
func
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -1686,9 +1715,11 @@ static void
chain_dealloc
(
chainobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
active
);
Py_XDECREF
(
lz
->
source
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -2837,9 +2868,11 @@ static void
compress_dealloc
(
compressobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
data
);
Py_XDECREF
(
lz
->
selectors
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -2866,11 +2899,16 @@ compress_next(compressobject *lz)
exception first).
*/
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
datum
=
datanext
(
data
);
if
(
datum
==
NULL
)
if
(
datum
==
NULL
)
{
Py_LeaveRecursiveCall
();
return
NULL
;
}
selector
=
selectornext
(
selectors
);
Py_LeaveRecursiveCall
();
if
(
selector
==
NULL
)
{
Py_DECREF
(
datum
);
return
NULL
;
...
...
@@ -2983,9 +3021,11 @@ static void
ifilter_dealloc
(
ifilterobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
func
);
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -3006,7 +3046,10 @@ ifilter_next(ifilterobject *lz)
iternext
=
*
Py_TYPE
(
it
)
->
tp_iternext
;
for
(;;)
{
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
item
=
iternext
(
it
);
Py_LeaveRecursiveCall
();
if
(
item
==
NULL
)
return
NULL
;
...
...
@@ -3128,9 +3171,11 @@ static void
ifilterfalse_dealloc
(
ifilterfalseobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
func
);
Py_XDECREF
(
lz
->
it
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -3151,7 +3196,10 @@ ifilterfalse_next(ifilterfalseobject *lz)
iternext
=
*
Py_TYPE
(
it
)
->
tp_iternext
;
for
(;;)
{
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
item
=
iternext
(
it
);
Py_LeaveRecursiveCall
();
if
(
item
==
NULL
)
return
NULL
;
...
...
@@ -3551,9 +3599,11 @@ static void
izip_dealloc
(
izipobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
ittuple
);
Py_XDECREF
(
lz
->
result
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
@@ -3576,15 +3626,15 @@ izip_next(izipobject *lz)
if
(
tuplesize
==
0
)
return
NULL
;
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
if
(
Py_REFCNT
(
result
)
==
1
)
{
Py_INCREF
(
result
);
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
i
);
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
if
(
item
==
NULL
)
goto
error
;
olditem
=
PyTuple_GET_ITEM
(
result
,
i
);
PyTuple_SET_ITEM
(
result
,
i
,
item
);
Py_DECREF
(
olditem
);
...
...
@@ -3592,18 +3642,21 @@ izip_next(izipobject *lz)
}
else
{
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
return
NULL
;
goto
error
;
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
i
);
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
if
(
item
==
NULL
)
goto
error
;
PyTuple_SET_ITEM
(
result
,
i
,
item
);
}
}
Py_LeaveRecursiveCall
();
return
result
;
error:
Py_XDECREF
(
result
);
Py_LeaveRecursiveCall
();
return
NULL
;
}
PyDoc_STRVAR
(
izip_doc
,
...
...
@@ -3892,10 +3945,12 @@ static void
izip_longest_dealloc
(
iziplongestobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_TRASHCAN_SAFE_BEGIN
(
lz
)
Py_XDECREF
(
lz
->
ittuple
);
Py_XDECREF
(
lz
->
result
);
Py_XDECREF
(
lz
->
fillvalue
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
Py_TRASHCAN_SAFE_END
(
lz
)
}
static
int
...
...
Objects/abstract.c
View file @
0e7df431
...
...
@@ -3104,7 +3104,10 @@ PyObject *
PyIter_Next
(
PyObject
*
iter
)
{
PyObject
*
result
;
if
(
Py_EnterRecursiveCall
(
" while iterating"
))
return
NULL
;
result
=
(
*
iter
->
ob_type
->
tp_iternext
)(
iter
);
Py_LeaveRecursiveCall
();
if
(
result
==
NULL
&&
PyErr_Occurred
()
&&
PyErr_ExceptionMatches
(
PyExc_StopIteration
))
...
...
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