Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 558be28

Browse files
committed
Make sure the objects returned by __getinitargs__() are kept alive (in
the memo) to avoid a certain kind of nasty crash. (Not easily reproducable because it requires a later call to __getinitargs__() to return a tuple that happens to be allocated at the same address.)
1 parent 86c052e commit 558be28

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

Lib/copy.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,36 @@ def _deepcopy_dict(x, memo):
195195
return y
196196
d[types.DictionaryType] = _deepcopy_dict
197197

198+
def _keep_alive(x, memo):
199+
"""Keeps a reference to the object x in the memo.
200+
201+
Because we remember objects by their id, we have
202+
to assure that possibly temporary objects are kept
203+
alive by referencing them.
204+
We store a reference at the id of the memo, which should
205+
normally not be used unless someone tries to deepcopy
206+
the memo itself...
207+
"""
208+
try:
209+
memo[id(memo)].append(x)
210+
except KeyError:
211+
# aha, this is the first one :-)
212+
memo[id(memo)]=[x]
213+
198214
def _deepcopy_inst(x, memo):
199215
if hasattr(x, '__deepcopy__'):
200216
return x.__deepcopy__()
201217
if hasattr(x, '__getinitargs__'):
202218
args = x.__getinitargs__()
219+
_keep_alive(args, memo)
203220
args = deepcopy(args, memo)
204221
else:
205222
args = ()
206223
y = apply(x.__class__, args)
207224
memo[id(x)] = y
208225
if hasattr(x, '__getstate__'):
209226
state = x.__getstate__()
227+
_keep_alive(state, memo)
210228
else:
211229
state = x.__dict__
212230
state = deepcopy(state, memo)

0 commit comments

Comments
 (0)