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
4918b47c
Commit
4918b47c
authored
Jan 19, 2016
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Plain Diff
Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
parents
31a858cb
d205d014
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
29 additions
and
13 deletions
+29
-13
Lib/test/test_ordered_dict.py
Lib/test/test_ordered_dict.py
+13
-0
Misc/NEWS
Misc/NEWS
+2
-0
Objects/odictobject.c
Objects/odictobject.c
+14
-13
No files found.
Lib/test/test_ordered_dict.py
View file @
4918b47c
import
contextlib
import
copy
import
gc
import
pickle
from
random
import
randrange
,
shuffle
import
struct
import
sys
import
unittest
import
weakref
from
collections.abc
import
MutableMapping
from
test
import
mapping_tests
,
support
...
...
@@ -593,6 +595,17 @@ class OrderedDictTests:
dict
.
update
(
od
,
[(
'spam'
,
1
)])
self
.
assertNotIn
(
'NULL'
,
repr
(
od
))
def
test_reference_loop
(
self
):
# Issue 25935
OrderedDict
=
self
.
OrderedDict
class
A
:
od
=
OrderedDict
()
A
.
od
[
A
]
=
None
r
=
weakref
.
ref
(
A
)
del
A
gc
.
collect
()
self
.
assertIsNone
(
r
())
class
PurePythonOrderedDictTests
(
OrderedDictTests
,
unittest
.
TestCase
):
...
...
Misc/NEWS
View file @
4918b47c
...
...
@@ -133,6 +133,8 @@ Core and Builtins
Library
-------
- Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
- Issue #16620: Fixed AttributeError in msilib.Directory.glob().
- Issue #26013: Added compatibility with broken protocol 2 pickles created
...
...
Objects/odictobject.c
View file @
4918b47c
...
...
@@ -772,19 +772,17 @@ _odict_clear_nodes(PyODictObject *od)
{
_ODictNode
*
node
,
*
next
;
if
(
!
_odict_EMPTY
(
od
))
{
node
=
_odict_FIRST
(
od
);
while
(
node
!=
NULL
)
{
next
=
_odictnode_NEXT
(
node
);
_odictnode_DEALLOC
(
node
);
node
=
next
;
}
_odict_FIRST
(
od
)
=
NULL
;
_odict_LAST
(
od
)
=
NULL
;
}
_odict_free_fast_nodes
(
od
);
od
->
od_fast_nodes
=
NULL
;
node
=
_odict_FIRST
(
od
);
_odict_FIRST
(
od
)
=
NULL
;
_odict_LAST
(
od
)
=
NULL
;
while
(
node
!=
NULL
)
{
next
=
_odictnode_NEXT
(
node
);
_odictnode_DEALLOC
(
node
);
node
=
next
;
}
}
/* There isn't any memory management of nodes past this point. */
...
...
@@ -1233,8 +1231,6 @@ odict_clear(register PyODictObject *od)
{
PyDict_Clear
((
PyObject
*
)
od
);
_odict_clear_nodes
(
od
);
_odict_FIRST
(
od
)
=
NULL
;
_odict_LAST
(
od
)
=
NULL
;
if
(
_odict_resize
(
od
)
<
0
)
return
NULL
;
Py_RETURN_NONE
;
...
...
@@ -1556,8 +1552,13 @@ PyDoc_STRVAR(odict_doc,
static
int
odict_traverse
(
PyODictObject
*
od
,
visitproc
visit
,
void
*
arg
)
{
_ODictNode
*
node
;
Py_VISIT
(
od
->
od_inst_dict
);
Py_VISIT
(
od
->
od_weakreflist
);
_odict_FOREACH
(
od
,
node
)
{
Py_VISIT
(
_odictnode_KEY
(
node
));
}
return
PyDict_Type
.
tp_traverse
((
PyObject
*
)
od
,
visit
,
arg
);
}
...
...
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