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
b62ff6eb
Commit
b62ff6eb
authored
Jun 12, 2016
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Plain Diff
Issue #25455: Fixed a crash in repr of recursive functools.partial objects.
parents
c3905442
179f960d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
18 deletions
+61
-18
Lib/test/test_functools.py
Lib/test/test_functools.py
+37
-0
Misc/NEWS
Misc/NEWS
+2
-1
Modules/_functoolsmodule.c
Modules/_functoolsmodule.c
+22
-17
No files found.
Lib/test/test_functools.py
View file @
b62ff6eb
...
...
@@ -217,6 +217,24 @@ class TestPartialC(TestPartial, unittest.TestCase):
[
'{}({!r}, {}, {})'
.
format
(
name
,
capture
,
args_repr
,
kwargs_repr
)
for
kwargs_repr
in
kwargs_reprs
])
def
test_recursive_repr
(
self
):
if
self
.
partial
is
c_functools
.
partial
:
name
=
'functools.partial'
else
:
name
=
self
.
partial
.
__name__
f
=
self
.
partial
(
capture
)
f
.
__setstate__
((
f
,
(),
{},
{}))
self
.
assertEqual
(
repr
(
f
),
'%s(%s(...))'
%
(
name
,
name
))
f
=
self
.
partial
(
capture
)
f
.
__setstate__
((
capture
,
(
f
,),
{},
{}))
self
.
assertEqual
(
repr
(
f
),
'%s(%r, %s(...))'
%
(
name
,
capture
,
name
))
f
=
self
.
partial
(
capture
)
f
.
__setstate__
((
capture
,
(),
{
'a'
:
f
},
{}))
self
.
assertEqual
(
repr
(
f
),
'%s(%r, a=%s(...))'
%
(
name
,
capture
,
name
))
def
test_pickle
(
self
):
f
=
self
.
partial
(
signature
,
[
'asdf'
],
bar
=
[
True
])
f
.
attr
=
[]
...
...
@@ -297,6 +315,25 @@ class TestPartialC(TestPartial, unittest.TestCase):
self
.
assertEqual
(
r
,
((
1
,
2
),
{}))
self
.
assertIs
(
type
(
r
[
0
]),
tuple
)
def
test_recursive_pickle
(
self
):
f
=
self
.
partial
(
capture
)
f
.
__setstate__
((
f
,
(),
{},
{}))
for
proto
in
range
(
pickle
.
HIGHEST_PROTOCOL
+
1
):
with
self
.
assertRaises
(
RecursionError
):
pickle
.
dumps
(
f
,
proto
)
f
=
self
.
partial
(
capture
)
f
.
__setstate__
((
capture
,
(
f
,),
{},
{}))
for
proto
in
range
(
pickle
.
HIGHEST_PROTOCOL
+
1
):
f_copy
=
pickle
.
loads
(
pickle
.
dumps
(
f
,
proto
))
self
.
assertIs
(
f_copy
.
args
[
0
],
f_copy
)
f
=
self
.
partial
(
capture
)
f
.
__setstate__
((
capture
,
(),
{
'a'
:
f
},
{}))
for
proto
in
range
(
pickle
.
HIGHEST_PROTOCOL
+
1
):
f_copy
=
pickle
.
loads
(
pickle
.
dumps
(
f
,
proto
))
self
.
assertIs
(
f_copy
.
keywords
[
'a'
],
f_copy
)
# Issue 6083: Reference counting bug
def
test_setstate_refcount
(
self
):
class
BadSequence
:
...
...
Misc/NEWS
View file @
b62ff6eb
...
...
@@ -44,7 +44,8 @@ Core and Builtins
Library
-------
- Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag.
- Issue #25455: Fixed crashes in repr of recursive ElementTree.Element and
functools.partial objects.
- Issue #27294: Improved repr for Tkinter event objects.
...
...
Modules/_functoolsmodule.c
View file @
b62ff6eb
...
...
@@ -203,40 +203,45 @@ static PyGetSetDef partial_getsetlist[] = {
static
PyObject
*
partial_repr
(
partialobject
*
pto
)
{
PyObject
*
result
;
PyObject
*
result
=
NULL
;
PyObject
*
arglist
;
PyObject
*
tmp
;
Py_ssize_t
i
,
n
;
PyObject
*
key
,
*
value
;
int
status
;
arglist
=
PyUnicode_FromString
(
""
);
if
(
arglist
==
NULL
)
{
return
NULL
;
status
=
Py_ReprEnter
((
PyObject
*
)
pto
);
if
(
status
!=
0
)
{
if
(
status
<
0
)
return
NULL
;
return
PyUnicode_FromFormat
(
"%s(...)"
,
Py_TYPE
(
pto
)
->
tp_name
);
}
arglist
=
PyUnicode_FromString
(
""
);
if
(
arglist
==
NULL
)
goto
done
;
/* Pack positional arguments */
assert
(
PyTuple_Check
(
pto
->
args
));
n
=
PyTuple_GET_SIZE
(
pto
->
args
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tmp
=
PyUnicode_FromFormat
(
"%U, %R"
,
arglist
,
PyTuple_GET_ITEM
(
pto
->
args
,
i
));
Py_DECREF
(
arglist
);
if
(
tmp
==
NULL
)
return
NULL
;
arglist
=
tmp
;
Py_SETREF
(
arglist
,
PyUnicode_FromFormat
(
"%U, %R"
,
arglist
,
PyTuple_GET_ITEM
(
pto
->
args
,
i
)));
if
(
arglist
==
NULL
)
goto
done
;
}
/* Pack keyword arguments */
assert
(
PyDict_Check
(
pto
->
kw
));
for
(
i
=
0
;
PyDict_Next
(
pto
->
kw
,
&
i
,
&
key
,
&
value
);)
{
tmp
=
PyUnicode_FromFormat
(
"%U, %U=%R"
,
arglist
,
key
,
value
);
Py_DECREF
(
arglist
);
if
(
tmp
==
NULL
)
return
NULL
;
arglist
=
tmp
;
Py_SETREF
(
arglist
,
PyUnicode_FromFormat
(
"%U, %U=%R"
,
arglist
,
key
,
value
));
if
(
arglist
==
NULL
)
goto
done
;
}
result
=
PyUnicode_FromFormat
(
"%s(%R%U)"
,
Py_TYPE
(
pto
)
->
tp_name
,
pto
->
fn
,
arglist
);
Py_DECREF
(
arglist
);
done:
Py_ReprLeave
((
PyObject
*
)
pto
);
return
result
;
}
...
...
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