mirror of
				https://github.com/explosion/spaCy.git
				synced 2025-10-31 16:07:41 +03:00 
			
		
		
		
	Use more sophisticated version parsing logic
This commit is contained in:
		
							parent
							
								
									bed62991ad
								
							
						
					
					
						commit
						e47e5a4b10
					
				|  | @ -5,7 +5,7 @@ import sys | |||
| from wasabi import msg | ||||
| 
 | ||||
| from .. import about | ||||
| from ..util import is_package | ||||
| from ..util import is_package, get_base_version | ||||
| 
 | ||||
| 
 | ||||
| def download( | ||||
|  | @ -63,8 +63,7 @@ def get_json(url, desc): | |||
| 
 | ||||
| 
 | ||||
| def get_compatibility(): | ||||
|     version = about.__version__ | ||||
|     version = version.rsplit(".dev", 1)[0] | ||||
|     version = get_base_version(about.__version__) | ||||
|     comp_table = get_json(about.__compatibility__, "compatibility table") | ||||
|     comp = comp_table["spacy"] | ||||
|     if version not in comp: | ||||
|  | @ -73,7 +72,7 @@ def get_compatibility(): | |||
| 
 | ||||
| 
 | ||||
| def get_version(model, comp): | ||||
|     model = model.rsplit(".dev", 1)[0] | ||||
|     model = get_base_version(model) | ||||
|     if model not in comp: | ||||
|         msg.fail( | ||||
|             f"No compatible model found for '{model}' (spaCy v{about.__version__})", | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ def generate_meta(model_path, existing_meta, msg): | |||
|         ("license", "License", meta.get("license", "MIT")), | ||||
|     ] | ||||
|     nlp = util.load_model_from_path(Path(model_path)) | ||||
|     meta["spacy_version"] = about.__version__ | ||||
|     meta["spacy_version"] = util.get_model_version_range(about.__version__) | ||||
|     meta["pipeline"] = nlp.pipe_names | ||||
|     meta["vectors"] = { | ||||
|         "width": nlp.vocab.vectors_length, | ||||
|  | @ -138,7 +138,7 @@ def list_files(data_dir): | |||
| 
 | ||||
| def list_requirements(meta): | ||||
|     parent_package = meta.get('parent_package', 'spacy') | ||||
|     requirements = [parent_package + '>=' + meta['spacy_version']] | ||||
|     requirements = [parent_package + meta['spacy_version']] | ||||
|     if 'setup_requires' in meta: | ||||
|         requirements += meta['setup_requires'] | ||||
|     if 'requirements' in meta: | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ import requests | |||
| from wasabi import msg | ||||
| 
 | ||||
| from .. import about | ||||
| from ..util import get_package_version, get_installed_models, split_version | ||||
| from ..util import get_package_version, get_installed_models, get_base_version | ||||
| from ..util import get_package_path, get_model_meta, is_compatible_model | ||||
| 
 | ||||
| 
 | ||||
|  | @ -14,7 +14,7 @@ def validate(): | |||
|     with the installed models. Should be run after `pip install -U spacy`. | ||||
|     """ | ||||
|     model_pkgs, compat = get_model_pkgs() | ||||
|     spacy_version = about.__version__.rsplit(".dev", 1)[0] | ||||
|     spacy_version = get_base_version(about.__version__) | ||||
|     current_compat = compat.get(spacy_version, {}) | ||||
|     if not current_compat: | ||||
|         msg.warn(f"No compatible models found for v{spacy_version} of spaCy") | ||||
|  | @ -78,13 +78,12 @@ def get_model_pkgs(): | |||
|         version = get_package_version(pkg_name) | ||||
|         if package in compat: | ||||
|             is_compat = version in compat[package] | ||||
|             v_maj, v_min = split_version(about.__version__) | ||||
|             spacy_version = f"{v_maj}.{v_min}" | ||||
|             spacy_version = about.__version__ | ||||
|         else: | ||||
|             model_path = get_package_path(package) | ||||
|             model_meta = get_model_meta(model_path) | ||||
|             is_compat = is_compatible_model(model_meta) | ||||
|             spacy_version = model_meta.get("spacy_version", "n/a") | ||||
|             is_compat = is_compatible_model(spacy_version) | ||||
|         pkgs[pkg_name] = { | ||||
|             "name": package, | ||||
|             "version": version, | ||||
|  |  | |||
|  | @ -191,13 +191,14 @@ class Language(object): | |||
| 
 | ||||
|     @property | ||||
|     def meta(self): | ||||
|         spacy_version = util.get_model_version_range(about.__version__) | ||||
|         if self.vocab.lang: | ||||
|             self._meta.setdefault("lang", self.vocab.lang) | ||||
|         else: | ||||
|             self._meta.setdefault("lang", self.lang) | ||||
|         self._meta.setdefault("name", "model") | ||||
|         self._meta.setdefault("version", "0.0.0") | ||||
|         self._meta.setdefault("spacy_version", about.__version__) | ||||
|         self._meta.setdefault("spacy_version", spacy_version) | ||||
|         self._meta.setdefault("description", "") | ||||
|         self._meta.setdefault("author", "") | ||||
|         self._meta.setdefault("email", "") | ||||
|  |  | |||
|  | @ -95,7 +95,15 @@ def test_ascii_filenames(): | |||
| 
 | ||||
| @pytest.mark.parametrize( | ||||
|     "version,compatible", | ||||
|     [(spacy_version, True), ("2.0.0", False), (">=1.2.3,<4.5.6", False)], | ||||
|     [ | ||||
|         (spacy_version, True), | ||||
|         (f">={spacy_version}", True), | ||||
|         ("2.0.0", False), | ||||
|         (">=2.0.0", True), | ||||
|         (">=1.0.0,<2.1.1", False), | ||||
|         (">=1.2.3,<4.5.6", True), | ||||
|         ("n/a", None), | ||||
|     ], | ||||
| ) | ||||
| def test_is_compatible_model(version, compatible): | ||||
|     assert util.is_compatible_model({"spacy_version": version}) is compatible | ||||
|     assert util.is_compatible_model(version) is compatible | ||||
|  |  | |||
|  | @ -14,6 +14,8 @@ import srsly | |||
| import catalogue | ||||
| import sys | ||||
| import warnings | ||||
| from packaging.specifiers import SpecifierSet, InvalidSpecifier | ||||
| from packaging.version import Version, InvalidVersion | ||||
| 
 | ||||
| 
 | ||||
| try: | ||||
|  | @ -236,42 +238,31 @@ def get_package_version(name): | |||
|         return None | ||||
| 
 | ||||
| 
 | ||||
| def split_version(version): | ||||
|     """RETURNS (tuple): Two integers, the major and minor spaCy version.""" | ||||
|     pieces = version.split(".", 3) | ||||
|     return int(pieces[0]), int(pieces[1]) | ||||
| 
 | ||||
| 
 | ||||
| def is_compatible_model(meta): | ||||
|     """Check if a model is compatible with the current version of spaCy, based | ||||
|     on its meta.json. We compare the version of spaCy the model was created with | ||||
|     with the current version. If the minor version is different, it's considered | ||||
|     incompatible. | ||||
| 
 | ||||
|     meta (dict): The model's meta. | ||||
|     RETURNS (bool / None): Whether the model is compatible with the current | ||||
|         spaCy or None if we don't have enough info. | ||||
|     """ | ||||
|     cur_v = about.__version__ | ||||
|     pkg_v = meta.get("spacy_version") | ||||
|     if not pkg_v or not isinstance(pkg_v, str): | ||||
| def is_compatible_model(constraint): | ||||
|     version = Version(about.__version__) | ||||
|     if constraint[0].isdigit(): | ||||
|         # Handle cases where exact version is provided as constraint | ||||
|         constraint = f"=={constraint}" | ||||
|     try: | ||||
|         spec = SpecifierSet(constraint) | ||||
|     except InvalidSpecifier: | ||||
|         return None | ||||
|     # Handle spacy_version values like >=x,<y, just in case | ||||
|     pkg_v = re.sub(r"[^0-9.]", "", pkg_v.split(",")[0]) | ||||
|     cur_major, cur_minor = split_version(cur_v) | ||||
|     pkg_major, pkg_minor = split_version(pkg_v) | ||||
|     if cur_major != pkg_major or cur_minor != pkg_minor: | ||||
|         return False | ||||
|     return True | ||||
|     # Allow prereleases and dev versions | ||||
|     spec.prereleases = True | ||||
|     return version in spec | ||||
| 
 | ||||
| 
 | ||||
| def get_model_version_range(version): | ||||
| def get_model_version_range(spacy_version): | ||||
|     """Generate a version range like >=1.2.3,<1.3.0 based on a given spaCy | ||||
|     version. Models are always compatible across patch versions but not | ||||
|     across minor or major versions. | ||||
|     """ | ||||
|     major, minor = split_version(version) | ||||
|     return f">={version},<{major}.{minor + 1}.0" | ||||
|     release = Version(spacy_version).release | ||||
|     return f">={spacy_version},<{release[0]}.{release[1] + 1}.0" | ||||
| 
 | ||||
| 
 | ||||
| def get_base_version(version): | ||||
|     return Version(version).base_version | ||||
| 
 | ||||
| 
 | ||||
| def load_config(path, create_objects=False): | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user