Source code for schrodinger.application.desmond.picklejar
"""
Facilities for pickling objects that are otherwise uneasy to pickle, e.g.,
class attributes.
Copyright Schrodinger, LLC. All rights reserved.
"""
# Contributors: Yujie Wu
import pickle
_BASE_PATH = 'schrodinger.application.desmond.'
_STAGE_PATH = _BASE_PATH + 'stage'
_relative_unpickle_map = {
'restraint.restraint_stage': 'stage.prepare.forcefield',
'fragment_linking.stage': 'stage.app.fragment_linking.stage',
'mxmd.mxmd_stage': 'stage.app.mxmd',
'absolute_binding.stage': 'stage.app.absolute_binding.stage'
}
_absolute_unpickle_map = {
_BASE_PATH + k: _BASE_PATH + v for (k, v) in _relative_unpickle_map.items()
}
# We need a user defined object in order to be able to set attributes when
# unpickling
class _UserDefinedObject:
def __setstate__(self, _):
# Fix "UnpicklingError: state is not a dictionary"
pass
_unpickle_deprecated_names = {
'Trajectory', 'GCMC', 'SolvatePocketBase', 'Minimize', 'McproStageBase',
'McproSystemBuilder', 'McproSimulate', 'FepAnalysis2', 'WaterMap',
'RetryTimer', 'BindingPoseFepPrimer'
}
_unpickle_deprecated_modules = {
'schrodinger.application.desmond.stage.app.binding_pose'
}
[docs]class CustomUnpickler(pickle.Unpickler):
[docs] def find_class(self, module, name):
remapped_module = _absolute_unpickle_map.get(module, module)
try:
return super().find_class(remapped_module, name)
except AttributeError:
# check this after trying super in case someone defines a new
# class with an old name
if name in _unpickle_deprecated_names:
return _UserDefinedObject
raise
except ModuleNotFoundError:
if remapped_module in _unpickle_deprecated_modules:
return _UserDefinedObject
raise
[docs]class PickleJar(object):
"""
"""
jar = {}
@staticmethod
def _update_data():
"""
"""
jar = PickleJar.jar
for k in jar:
for dn in jar[k]:
jar[k][dn] = k.__dict__[dn]
[docs] @staticmethod
def serialize(fh):
"""
"""
PickleJar._update_data()
pickle.dump(PickleJar.jar, fh)
[docs] @staticmethod
def deserialize(fh):
"""
"""
unpickler = CustomUnpickler(fh)
jar = unpickler.load()
for k in jar:
for dn in jar[k]:
setattr(k, dn, jar[k][dn])
[docs]class Picklable(object, metaclass=PicklableMetaClass):
pass
[docs]class PickleState(object):
pass