import dataclasses import hashlib import importlib.util import json from typing import Dict import rope.base.project def get_version_hash_data(project: rope.base.project.Project) -> Dict[str, str]: version_hash_data = dict( version_data=f"{rope.VERSION}", prefs_data=_get_prefs_data(project), schema_file_content=_get_file_content("rope.contrib.autoimport.models"), ) return version_hash_data def calculate_version_hash(project: rope.base.project.Project) -> str: def _merge(hasher, name: str, serialized_data: str): hashed_data = hashlib.sha256(serialized_data.encode("utf-8")).hexdigest() hasher.update(hashed_data.encode("ascii")) hasher = hashlib.sha256() for name, data in get_version_hash_data(project).items(): _merge(hasher, name, data) return hasher.hexdigest() def _get_prefs_data(project) -> str: prefs_data = dict(vars(project.prefs)) del prefs_data["project_opened"] del prefs_data["callbacks"] del prefs_data["dependencies"] return json.dumps( prefs_data, sort_keys=True, indent=2, default=lambda o: o.__dict__ ) def _get_file_content(module_name: str) -> str: models_module = importlib.util.find_spec(module_name) assert models_module and models_module.loader assert isinstance(models_module.loader, importlib.machinery.SourceFileLoader) src = models_module.loader.get_source(module_name) assert src return src