예제 #1
0
파일: __init__.py 프로젝트: Leryan/pyrrot
    def is_old(latest, specifiers):
        """
        :param latest Version:
        :param required SpecifierSet:
        """

        if not isinstance(latest, Version):
            raise TypeError('latest is not of type Version')

        if not isinstance(specifiers, SpecifierSet):
            raise TypeError('specifiers is not of type SpecifierSet')

        old = False

        for spec in specifiers:
            if spec.operator in ['>', '>=']:
                continue

            latest_op = '<'
            if spec.operator in ['<']:
                latest_op = '<='

            latest_spec = Specifier('{}{}'.format(latest_op, str(latest)))

            if list(latest_spec.filter([spec.version])):
                old = True

        return old
예제 #2
0
파일: markers.py 프로젝트: xRAFPx/pipenv
def get_specset(marker_list):
    # type: (List) -> Optional[SpecifierSet]
    specset = set()
    _last_str = "and"
    for marker_parts in marker_list:
        if isinstance(marker_parts, tuple):
            variable, op, value = marker_parts
            if variable.value != "python_version":
                continue
            if op.value == "in":
                values = [v.strip() for v in value.value.split(",")]
                specset.update(Specifier("=={0}".format(v)) for v in values)
            elif op.value == "not in":
                values = [v.strip() for v in value.value.split(",")]
                bad_versions = ["3.0", "3.1", "3.2", "3.3"]
                if len(values) >= 2 and any(v in values for v in bad_versions):
                    values = bad_versions
                specset.update(
                    Specifier("!={0}".format(v.strip())) for v in sorted(bad_versions)
                )
            else:
                specset.add(Specifier("{0}{1}".format(op.value, value.value)))
        elif isinstance(marker_parts, list):
            parts = get_specset(marker_parts)
            if parts:
                specset.update(parts)
        elif isinstance(marker_parts, str):
            _last_str = marker_parts
    specifiers = SpecifierSet()
    specifiers._specs = frozenset(specset)
    return specifiers
예제 #3
0
파일: markers.py 프로젝트: xRAFPx/pipenv
def _format_pyspec(specifier):
    # type: (Union[STRING_TYPE, Specifier]) -> Specifier
    if isinstance(specifier, str):
        if not any(op in specifier for op in Specifier._operators.keys()):
            specifier = "=={0}".format(specifier)
        specifier = Specifier(specifier)
    version = getattr(specifier, "version", specifier).rstrip()
    if version and version.endswith("*"):
        if version.endswith(".*"):
            version = version.rstrip(".*")
        else:
            version = version.rstrip("*")
        specifier = Specifier("{0}{1}".format(specifier.operator, version))
    try:
        op = REPLACE_RANGES[specifier.operator]
    except KeyError:
        return specifier
    curr_tuple = _tuplize_version(version)
    try:
        next_tuple = (curr_tuple[0], curr_tuple[1] + 1)
    except IndexError:
        next_tuple = (curr_tuple[0], 1)
    if not next_tuple[1] <= MAX_VERSIONS[next_tuple[0]]:
        if specifier.operator == "<" and curr_tuple[1] <= MAX_VERSIONS[next_tuple[0]]:
            op = "<="
            next_tuple = (next_tuple[0], curr_tuple[1])
        else:
            return specifier
    specifier = Specifier("{0}{1}".format(op, _format_version(next_tuple)))
    return specifier
    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)
예제 #5
0
    def test_specifier_filter(self, specifier, prereleases, input, expected):
        spec = Specifier(specifier)

        kwargs = ({
            "prereleases": prereleases
        } if prereleases is not None else {})

        assert list(spec.filter(input, **kwargs)) == expected
예제 #6
0
    def test_specifier_filter(self, specifier, prereleases, input, expected):
        spec = Specifier(specifier)

        kwargs = (
            {"prereleases": prereleases} if prereleases is not None else {}
        )

        assert list(spec.filter(input, **kwargs)) == expected
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
파일: main.py 프로젝트: svrana/pipsqueak
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
예제 #10
0
    def test_specifiers_prereleases(self, specifier, version, expected):
        spec = Specifier(specifier)

        if expected:
            assert version in spec
            spec.prereleases = False
            assert version not in spec
        else:
            assert version not in spec
            spec.prereleases = True
            assert version in spec
예제 #11
0
    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 _get_specifiers_from_markers(marker_item):
    """
    Given a marker item, get specifiers from the version marker

    :param :class:`~packaging.markers.Marker` marker_sequence: A marker describing a version constraint
    :return: A set of specifiers corresponding to the marker constraint
    :rtype: Set[Specifier]
    """
    specifiers = set()
    if isinstance(marker_item, tuple):
        variable, op, value = marker_item
        if variable.value != "python_version":
            return specifiers
        if op.value == "in":
            specifiers.update(_split_specifierset_str(value.value,
                                                      prefix="=="))
        elif op.value == "not in":
            specifiers.update(_split_specifierset_str(value.value,
                                                      prefix="!="))
        else:
            specifiers.add(Specifier("{0}{1}".format(op.value, value.value)))
    elif isinstance(marker_item, list):
        parts = get_specset(marker_item)
        if parts:
            specifiers.update(parts)
    return specifiers
    def update_config(self, config: Dict[str, str]) -> None:
        identifier = config["identifier"]
        version = Version(config["version"])
        spec = Specifier(f"=={version.major}.{version.minor}.*")
        log.info(f"Reading in '{identifier}' -> {spec} @ {version}")
        orig_config = copy.copy(config)
        config_update: Optional[AnyConfig]

        # We need to use ** in update due to MyPy (probably a bug)
        if "macosx_x86_64" in identifier:
            if identifier.startswith("pp"):
                config_update = self.macos_pypy.update_version_macos(spec)
            else:
                config_update = self.macos_9.update_version_macos(
                    spec) or self.macos_6.update_version_macos(spec)
            assert config_update is not None, f"MacOS {spec} not found!"
            config.update(**config_update)
        elif "win32" in identifier:
            if identifier.startswith("pp"):
                config.update(**self.windows_pypy.update_version_windows(spec))
            else:
                config_update = self.windows_32.update_version_windows(spec)
                if config_update:
                    config.update(**config_update)
        elif "win_amd64" in identifier:
            config_update = self.windows_64.update_version_windows(spec)
            if config_update:
                config.update(**config_update)

        if config != orig_config:
            log.info(f"  Updated {orig_config} to {config}")
    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 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,
        )
예제 #17
0
def update_req(req):
    """Updates a given req object with the latest version."""

    if not req.name:
        return req, None

    info = get_package_info(req.name)

    if info['info'].get('_pypi_hidden'):
        print('{} is hidden on PyPI and will not be updated.'.format(req))
        return req, None

    if _is_pinned(req) and _is_version_range(req):
        print('{} is pinned to a range and will not be updated.'.format(req))
        return req, None

    newest_version = _get_newest_version(info)
    current_spec = next(iter(req.specifier)) if req.specifier else None
    current_version = current_spec.version if current_spec else None
    new_spec = Specifier(u'=={}'.format(newest_version))
    if not current_spec or current_spec._spec != new_spec._spec:
        req.specifier = new_spec
        update_info = (req.name, current_version, newest_version)
        return req, update_info
    return req, None
예제 #18
0
    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,
        )
예제 #19
0
    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
예제 #20
0
    def update_config(self, config: dict[str, str]) -> None:
        identifier = config["identifier"]
        version = Version(config["version"])
        spec = Specifier(f"=={version.major}.{version.minor}.*")
        log.info(f"Reading in '{identifier}' -> {spec} @ {version}")
        orig_config = copy.copy(config)
        config_update: AnyConfig | None = None

        # We need to use ** in update due to MyPy (probably a bug)
        if "macos" in identifier:
            if identifier.startswith("cp"):
                config_update = self.macos_cpython.update_version_macos(
                    identifier, version, spec)
            elif identifier.startswith("pp"):
                config_update = self.macos_pypy.update_version_macos(spec)
        elif "win32" in identifier:
            if identifier.startswith("cp"):
                config_update = self.windows_32.update_version_windows(spec)
        elif "win_amd64" in identifier:
            if identifier.startswith("cp"):
                config_update = self.windows_64.update_version_windows(spec)
            elif identifier.startswith("pp"):
                config_update = self.windows_pypy_64.update_version_windows(
                    spec)
        elif "win_arm64" in identifier:
            if identifier.startswith("cp"):
                config_update = self.windows_arm64.update_version_windows(spec)

        assert config_update is not None, f"{identifier} not found!"
        config.update(**config_update)

        if config != orig_config:
            log.info(f"  Updated {orig_config} to {config}")
예제 #21
0
 def __init__(self, specifiers=''):
     specifiers = [s.strip() for s in specifiers.split(',') if s.strip()]
     parsed = set()
     for specifier in specifiers:
         parsed.add(Specifier(specifier))
     self._specs = frozenset(parsed)
     self._prereleases = None
예제 #22
0
def pyspec_from_markers(marker):
    if marker._markers[0][0] != 'python_version':
        return
    op = marker._markers[0][1].value
    version = marker._markers[0][2].value
    specset = set()
    if op == "in":
        specset.update(
            Specifier("=={0}".format(v.strip())) for v in version.split(","))
    elif op == "not in":
        specset.update(
            Specifier("!={0}".format(v.strip())) for v in version.split(","))
    else:
        specset.add(Specifier("".join([op, version])))
    if specset:
        return specset
    return None
예제 #23
0
    def test_specifiers_normalized(self, version):
        if "+" not in version:
            ops = ["~=", "==", "!=", "<=", ">=", "<", ">"]
        else:
            ops = ["==", "!="]

        for op in ops:
            Specifier(op + version)
예제 #24
0
    def pre_run(self) -> None:
        """Parse and initialize specifier used."""
        if self.configuration["package_name"] is None:
            raise SieveError(f"Package name for {self.__class__.__name__!r} is not set")

        if self.configuration["version_specifier"] is None:
            raise SieveError(f"Package version specifier for {self.__class__.__name__!r} is not set")

        self._specifier = Specifier(self.configuration["version_specifier"])
예제 #25
0
    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)
예제 #26
0
def _format_pyspec(specifier):
    if isinstance(specifier, str):
        if not any(op in specifier for op in Specifier._operators.keys()):
            specifier = "=={0}".format(specifier)
        specifier = Specifier(specifier)
    if specifier.operator == "==" and specifier.version.endswith(".*"):
        specifier = Specifier("=={0}".format(specifier.version[:-2]))
    try:
        op = REPLACE_RANGES[specifier.operator]
    except KeyError:
        return specifier
    version = specifier.version.replace(".*", "")
    curr_tuple = _tuplize_version(version)
    try:
        next_tuple = (curr_tuple[0], curr_tuple[1] + 1)
    except IndexError:
        next_tuple = (curr_tuple[0], 1)
    specifier = Specifier("{0}{1}".format(op, _format_version(next_tuple)))
    return specifier
예제 #27
0
def verify_mininum(mininum_package, required_package_name, required_mininum_version,
                   operator='==', required_extra=None):
    assert mininum_package.name == required_package_name
    assert mininum_package.specifier == Specifier(operator + required_mininum_version)
    if required_extra:
        assert mininum_package.extras == {required_extra}
    else:
        assert mininum_package.extras == set()
        extra_chars = ['[', ']']
        not any([x in mininum_package.name for x in extra_chars])
        assert not any([x in required_package_name for x in extra_chars])
예제 #28
0
    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)
예제 #29
0
def _handle_compatibility_operator(
    all_specifiers: List[Specifier],
    operator_to_specifiers: Dict[str, Set[Specifier]],
    specifier: Specifier,
) -> None:
    """
    Handle a specifier with operator '~='.

    Split specifier of the form "~=<major.minor>" in two specifiers:
    - >= <major.minor>
    - < <major+1>
    Also handle micro-numbers, i.e. "~=<major.minor.micro>"
    (see last examples of https://www.python.org/dev/peps/pep-0440/#compatible-release)

    :param all_specifiers: the list of all specifiers (to be populated).
    :param operator_to_specifiers: a mapping from operator to specifiers (to be populated).
    :param specifier: the specifier to process.
    :return: None
    """
    spec_version = Version(specifier.version)
    base_version = spec_version.base_version
    parts = base_version.split(".")
    index_to_update = -2
    if (spec_version.is_prerelease or spec_version.is_devrelease
            or spec_version.is_postrelease):
        # if it is a pre-release, ignore the suffix.
        index_to_update += 1
        parts = parts[:-1]
    # bump second-to-last part
    parts[index_to_update] = str(int(parts[index_to_update]) + 1)
    upper_version = Version(".".join(parts))
    spec_1 = Specifier(">=" + str(spec_version))
    spec_2 = Specifier("<" + str(upper_version))
    all_specifiers.extend([spec_1, spec_2])
    operator_to_specifiers[spec_1.operator].add(spec_1)
    operator_to_specifiers[spec_2.operator].add(spec_2)
예제 #30
0
    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,
        )
예제 #31
0
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
예제 #32
0
def _split_specifierset_str(specset_str, prefix="=="):
    # type: (str, str) -> Set[Specifier]
    """Take a specifierset string and split it into a list to join for
    specifier sets.

    :param str specset_str: A string containing python versions, often comma separated
    :param str prefix: A prefix to use when generating the specifier set
    :return: A list of :class:`Specifier` instances generated with the provided prefix
    :rtype: Set[Specifier]
    """
    specifiers = set()
    if "," not in specset_str and " " in specset_str:
        values = [v.strip() for v in specset_str.split()]
    else:
        values = [v.strip() for v in specset_str.split(",")]
    if prefix == "!=" and any(v in values for v in DEPRECATED_VERSIONS):
        values += DEPRECATED_VERSIONS[:]
    for value in sorted(values):
        specifiers.add(Specifier("{0}{1}".format(prefix, value)))
    return specifiers
예제 #33
0
    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))
예제 #34
0
    def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None:

        # Specifier.filter selects all non pre-releases that match the spec,
        # unless there are only pre-releases, then it selects pre-releases
        # instead (like pip)
        unsorted_versions = spec.filter(self.version_dict)
        versions = sorted(unsorted_versions, reverse=True)

        log.debug(
            f"Windows {self.arch} {spec} has {', '.join(str(v) for v in versions)}"
        )

        if not versions:
            return None

        version = versions[0]
        identifier = f"cp{version.major}{version.minor}-{self.arch}"
        return ConfigWinCP(
            identifier=identifier,
            version=self.version_dict[version],
            arch=self.arch_str,
        )
예제 #35
0
    def test_empty_specifier(self, version):
        spec = Specifier(prereleases=True)

        assert spec.contains(version)
예제 #36
0
    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")