misc: add dedicated methods for copy and deepcopy (#24033)

copy and deepcopy are recycling __getstate__ originally defined for
pickling objects; however we have a custom __getstate__ method for
formdefs because we want to save fields in a different pickle chunk.

But while removing fields in __getstate__ during pickling wouldn't
affect a "live" object, copy/deepcopy are supposed to create usable
objects, and a formdef with its fields attribute reduced to None
doesn't qualify.

Practically this could cause all sorts of malfunctions including a
not-so-subtle removal of all fields (if the copied formdef was stored
on disk).
This commit is contained in:
Frédéric Péters 2018-05-23 17:14:28 +02:00
parent 0f30572297
commit 832a34c032
1 changed files with 15 additions and 0 deletions

View File

@ -1328,6 +1328,21 @@ class FormDef(StorableObject):
if changed:
formdef.store()
class _EmptyClass(object): # helper for instance creation without calling __init__
pass
def __copy__(self, memo=None, deepcopy=False):
formdef_copy = self._EmptyClass()
formdef_copy.__class__ = self.__class__
if deepcopy:
formdef_copy.__dict__ = copy.deepcopy(self.__dict__, memo=memo)
else:
formdef_copy.__dict__ = copy.copy(self.__dict__)
return formdef_copy
def __deepcopy__(self, memo=None):
return self.__copy__(memo=memo, deepcopy=True)
# don't pickle computed attributes
def __getstate__(self):
odict = copy.copy(self.__dict__)