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'
}
[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  
[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