Commit a158967e authored by Stefan Behnel's avatar Stefan Behnel

Escape local variables in generated pickle helper functions to prevent...

Escape local variables in generated pickle helper functions to prevent conflicts with the user defined class name.

Closes #1786.
parent 23b6e66f
...@@ -1671,24 +1671,24 @@ if VALUE is not None: ...@@ -1671,24 +1671,24 @@ if VALUE is not None:
unpickle_func = TreeFragment(u""" unpickle_func = TreeFragment(u"""
def %(unpickle_func_name)s(__pyx_type, long __pyx_checksum, __pyx_state): def %(unpickle_func_name)s(__pyx_type, long __pyx_checksum, __pyx_state):
if __pyx_checksum != %(checksum)s: if __pyx_checksum != %(checksum)s:
from pickle import PickleError from pickle import PickleError as __pyx_PickleError
raise PickleError("Incompatible checksums (%%s vs %(checksum)s = (%(members)s))" %% __pyx_checksum) raise __pyx_PickleError("Incompatible checksums (%%s vs %(checksum)s = (%(members)s))" %% __pyx_checksum)
result = %(class_name)s.__new__(__pyx_type) __pyx_result = %(class_name)s.__new__(__pyx_type)
if __pyx_state is not None: if __pyx_state is not None:
%(unpickle_func_name)s__set_state(<%(class_name)s> result, __pyx_state) %(unpickle_func_name)s__set_state(<%(class_name)s> __pyx_result, __pyx_state)
return result return __pyx_result
cdef %(unpickle_func_name)s__set_state(%(class_name)s result, tuple __pyx_state): cdef %(unpickle_func_name)s__set_state(%(class_name)s __pyx_result, tuple __pyx_state):
%(assignments)s %(assignments)s
if hasattr(result, '__dict__'): if hasattr(__pyx_result, '__dict__'):
result.__dict__.update(__pyx_state[%(num_members)s]) __pyx_result.__dict__.update(__pyx_state[%(num_members)s])
""" % { """ % {
'unpickle_func_name': unpickle_func_name, 'unpickle_func_name': unpickle_func_name,
'checksum': checksum, 'checksum': checksum,
'members': ', '.join(all_members_names), 'members': ', '.join(all_members_names),
'class_name': node.class_name, 'class_name': node.class_name,
'assignments': '; '.join( 'assignments': '; '.join(
'result.%s = __pyx_state[%s]' % (v, ix) '__pyx_result.%s = __pyx_state[%s]' % (v, ix)
for ix, v in enumerate(all_members_names)), for ix, v in enumerate(all_members_names)),
'num_members': len(all_members_names), 'num_members': len(all_members_names),
}, level='module', pipeline=[NormalizeTree(None)]).substitute({}) }, level='module', pipeline=[NormalizeTree(None)]).substitute({})
......
...@@ -271,3 +271,16 @@ cdef class Wrapper(object): ...@@ -271,3 +271,16 @@ cdef class Wrapper(object):
return "Wrapper(...)" return "Wrapper(...)"
else: else:
return "Wrapper(%r)" % self.ref return "Wrapper(%r)" % self.ref
cdef class result:
"""
This used to create a naming conflict.
>>> import pickle
>>> r = result()
>>> r.attr = 5
>>> r2 = pickle.loads(pickle.dumps(r))
>>> r2.attr
5
"""
cdef public attr
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment