def test_specifiers_identity(self, version, spec, expected): spec = Specifier(spec) if expected: # Identity comparisons only support the plain string form assert spec.contains(version) else: # Identity comparisons only support the plain string form assert not spec.contains(version)
def test_specifiers_prereleases(self, specifier, version, expected): spec = Specifier(specifier) if expected: assert spec.contains(version) spec.prereleases = False assert not spec.contains(version) else: assert not spec.contains(version) spec.prereleases = True assert spec.contains(version)
def test_specifiers(self, version, spec, expected): spec = Specifier(spec, prereleases=True) if expected: # Test that the plain string form works assert spec.contains(version) # Test that the version instance form works assert spec.contains(Version(version)) else: # Test that the plain string form works assert not spec.contains(version) # Test that the version instance form works assert not spec.contains(Version(version))
def update_version_macos(self, spec: Specifier) -> ConfigMacOS: if self.arch != "64": raise RuntimeError("Other archs not supported yet on macOS") releases = [ r for r in self.releases if spec.contains(r["python_version"]) ] releases = sorted(releases, key=lambda r: r["pypy_version"]) if not releases: raise RuntimeError(f"PyPy macOS {self.arch} not found for {spec}!") release = releases[-1] version = release["python_version"] identifier = f"pp{version.major}{version.minor}-macosx_x86_64" (url, ) = [ rf["download_url"] for rf in release["files"] if "" in rf["platform"] == "darwin" and rf["arch"] == "x64" ] return ConfigMacOS( identifier=identifier, version=f"{version.major}.{version.minor}", url=url, )
def update_version_windows(self, spec: Specifier) -> ConfigWinCP: if self.arch != "32": raise RuntimeError("64 bit releases not supported yet on Windows") releases = [ r for r in self.releases if spec.contains(r["python_version"]) ] releases = sorted(releases, key=lambda r: r["pypy_version"]) if not releases: raise RuntimeError( f"PyPy Win {self.arch} not found for {spec}! {self.releases}") release = releases[-1] version = release["python_version"] identifier = f"pp{version.major}{version.minor}-win32" (url, ) = [ rf["download_url"] for rf in release["files"] if "" in rf["platform"] == "win32" ] return ConfigWinPP( identifier=identifier, version=f"{version.major}.{version.minor}", arch="32", url=url, )
def update_version_macos(self, identifier: str, version: Version, spec: Specifier) -> ConfigMacOS | None: sorted_versions = sorted(v for v in self.versions_dict if spec.contains(v)) if version <= Version("3.8.9999"): file_ident = "macosx10.9.pkg" else: file_ident = "macos11.pkg" for new_version in reversed(sorted_versions): # Find the first patch version that contains the requested file uri = self.versions_dict[new_version] response = requests.get( f"https://www.python.org/api/v2/downloads/release_file/?release={uri}" ) response.raise_for_status() file_info = response.json() urls = [rf["url"] for rf in file_info if file_ident in rf["url"]] if urls: return ConfigMacOS( identifier=identifier, version=f"{new_version.major}.{new_version.minor}", url=urls[0], ) return None
def update_version_windows(self, spec: Specifier) -> ConfigWinCP: releases = [ r for r in self.releases if spec.contains(r["python_version"]) ] releases = sorted( releases, key=lambda r: r["pypy_version"]) # type: ignore[no-any-return] releases = [r for r in releases if self.get_arch_file(r)] if not releases: raise RuntimeError( f"PyPy Win {self.arch} not found for {spec}! {self.releases}") version_arch = "win32" if self.arch == "32" else "win_amd64" release = releases[-1] version = release["python_version"] identifier = f"pp{version.major}{version.minor}-{version_arch}" url = self.get_arch_file(release) return ConfigWinPP( identifier=identifier, version=f"{version.major}.{version.minor}", arch=self.arch, url=url, )
def update_version_macos(self, spec: Specifier) -> Optional[ConfigMacOS]: sorted_versions = sorted(v for v in self.versions_dict if spec.contains(v)) for version in reversed(sorted_versions): # Find the first patch version that contains the requested file uri = self.versions_dict[version] response = requests.get( f"https://www.python.org/api/v2/downloads/release_file/?release={uri}" ) response.raise_for_status() file_info = response.json() urls = [ rf["url"] for rf in file_info if self.file_ident in rf["url"] ] if urls: return ConfigMacOS( identifier= f"cp{version.major}{version.minor}-{self.plat_arch}", version=f"{version.major}.{version.minor}", url=urls[0], ) return None
def matches_version(self, other): """ returns true of self.version fits within the specification given by other.version """ if not isinstance(other, Package): other = Package(other) if other.version is None or other.version == '*': return True elif other.delimiter == '=': other_delim = '==' else: other_delim = other.delimiter if (other_delim in ('==', '!=') and (other.minor_version is None or other.patch_version is None) and not other.version.endswith('.*')): other_version = f'{other.version}.*' elif other_delim not in ('==', '!=') and other.version.endswith('.*'): other_version = other.version.split('.*')[0] else: other_version = other.version other_spec = Specifier(f'{other_delim}{other_version}') return other_spec.contains(self.version)
def _versions_match(required, installed): if required is None: return True try: req = Specifier(required) except InvalidSpecifier: req = LegacySpecifier(required) contains = req.contains(installed[2:]) return contains
def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None: versions = sorted(v for v in self.versions if spec.contains(v)) if not all(v.is_prerelease for v in versions): versions = [v for v in versions if not v.is_prerelease] log.debug(f"Windows {self.arch} {spec} has {', '.join(str(v) for v in versions)}") if not versions: return None version = versions[-1] identifier = f"cp{version.major}{version.minor}-{self.arch}" return ConfigWinCP( identifier=identifier, version=str(version), arch=self.arch_str, )
class VersionConstraintSieve(Sieve): """Filter out packages based on version constraints if they occur in the stack.""" CONFIGURATION_DEFAULT = {"package_name": None, "version_specifier": None} CONFIGURATION_SCHEMA = Schema({ Required("package_name"): str, Required("version_specifier"): str }) _specifier = attr.ib(type=Optional[Specifier], default=None, init=False) @classmethod def should_include( cls, builder_context: "PipelineBuilderContext" ) -> Generator[Dict[str, Any], None, None]: """Include this sieve only if user explicitly asks for it.""" yield from () return None def pre_run(self) -> None: """Parse and initialize specifier used.""" self._specifier = Specifier(self.configuration["version_specifier"]) super().pre_run() def run( self, package_versions: Generator[PackageVersion, None, None] ) -> Generator[PackageVersion, None, None]: """Filter out packages based on build time/installation issues..""" if self._specifier is None: return for package_version in package_versions: if package_version.name == self.configuration[ "package_name"] and not self._specifier.contains( package_version.locked_version): _LOGGER.debug( "Removing package %r based on configured version specifier %r", self.configuration["package_name"], self.configuration["version_specifier"], ) continue yield package_version
def test_specifier_prereleases_explicit(self): spec = Specifier() assert not spec.prereleases assert not spec.contains("1.0.dev1") spec.prereleases = True assert spec.prereleases assert spec.contains("1.0.dev1") spec = Specifier(prereleases=True) assert spec.prereleases assert spec.contains("1.0.dev1") spec.prereleases = False assert not spec.prereleases assert not spec.contains("1.0.dev1") spec = Specifier(prereleases=True) assert spec.prereleases assert spec.contains("1.0.dev1") spec.prereleases = None assert not spec.prereleases assert not spec.contains("1.0.dev1")
def test_empty_specifier(self, version): spec = Specifier(prereleases=True) assert spec.contains(version)
def test_specifier_regex_no_match(specifier: str, version: str) -> None: specifier_ = Specifier(specifier) version_ = Version(version) assert not specifier_.contains(version_, prereleases=True) assert re.match(SPECIFIER_GOOD[specifier], str(Version(version))) is None assert re.match(SPECIFIER_GOOD[specifier], version) is None