diff --git a/sisyphus/global_settings.py b/sisyphus/global_settings.py index 19ae820..adf18f3 100644 --- a/sisyphus/global_settings.py +++ b/sisyphus/global_settings.py @@ -163,6 +163,10 @@ def file_caching(path): #: Default function to hash jobs and objects SIS_HASH = sisyphus.hash.short_hash +#: Use the sis hash to compare Paths and to compute __hash__. The original behavior was not based on sis_hash +#: which might lead to Paths with the same sis_hash to not be considered equal. +USE_SIS_HASH_FOR_PATH_COMPARISON = False + #: List of paths searched for loading config and recipe files. The module name should be part of the path e.g.: #: adding 'config' will cause Sisyphus to the current directory for a folder named config to load modules starting #: with config, other python files in the current directory will be ignored. diff --git a/sisyphus/job_path.py b/sisyphus/job_path.py index e155f74..4de6d70 100644 --- a/sisyphus/job_path.py +++ b/sisyphus/job_path.py @@ -192,6 +192,9 @@ def __lt__(self, other): if not isinstance(other, AbstractPath): assert False, "Cannot compare path to none path" + if gs.USE_SIS_HASH_FOR_PATH_COMPARISON: + return self._sis_hash() < other._sis_hash() + def creator_to_str(c): if isinstance(c, str): return c @@ -214,14 +217,22 @@ def __eq__(self, other): if len(self.__dict__) == len(other.__dict__) == 0: return True + if gs.USE_SIS_HASH_FOR_PATH_COMPARISON: + return self._sis_hash() == other._sis_hash() + creator_equal = self.creator == other.creator path_equal = self.path == other.path return creator_equal and path_equal def __hash__(self): - # TODO Check how uninitialized object should behave here - return hash((self.__dict__.get('creator'), - self.__dict__.get('path'))) + if gs.USE_SIS_HASH_FOR_PATH_COMPARISON: + if hasattr(self, 'creator'): # uninitialized object have no creator and calling sis_hash would fail + # Add prefix to avoid collision with sis_hash string + return hash(b'HASH # ' + self._sis_hash()) + else: + return super().__hash__() + else: + return hash((self.__dict__.get('creator'), self.__dict__.get('path'))) def __getstate__(self): """ Skips exporting users