Пример #1
0
 def test_create(self, allow_all_prereleases: bool, prefer_binary: bool) -> None:
     target_python = TargetPython()
     target_python._valid_tags = [Tag("py36", "none", "any")]
     specifier = SpecifierSet()
     evaluator = CandidateEvaluator.create(
         project_name="my-project",
         target_python=target_python,
         allow_all_prereleases=allow_all_prereleases,
         prefer_binary=prefer_binary,
         specifier=specifier,
     )
     assert evaluator._allow_all_prereleases == allow_all_prereleases
     assert evaluator._prefer_binary == prefer_binary
     assert evaluator._specifier is specifier
     assert evaluator._supported_tags == [Tag("py36", "none", "any")]
Пример #2
0
 def test_create(self, allow_all_prereleases, prefer_binary):
     target_python = TargetPython()
     target_python._valid_tags = [('py36', 'none', 'any')]
     specifier = SpecifierSet()
     evaluator = CandidateEvaluator.create(
         project_name='my-project',
         target_python=target_python,
         allow_all_prereleases=allow_all_prereleases,
         prefer_binary=prefer_binary,
         specifier=specifier,
     )
     assert evaluator._allow_all_prereleases == allow_all_prereleases
     assert evaluator._prefer_binary == prefer_binary
     assert evaluator._specifier is specifier
     assert evaluator._supported_tags == [('py36', 'none', 'any')]
Пример #3
0
    def test_not_find_wheel_not_supported(self, data, monkeypatch):
        """
        Test not finding an unsupported wheel.
        """
        req = install_req_from_line("simple.dist")
        target_python = TargetPython()
        # Make sure no tags will match.
        target_python._valid_tags = []
        finder = make_test_finder(
            find_links=[data.find_links],
            target_python=target_python,
        )

        with pytest.raises(DistributionNotFound):
            finder.find_requirement(req, True)
    def run(self, options, args):
        options.timeout = TIMEOUT
        options.retries = RETRIES
        options.ignore_installed = True
        options.editables = []

        with self._build_session(options) as session:
            finder = self._build_package_finder(
                options=options,
                session=session,
                target_python=TargetPython(
                    platform=options.platform,
                    py_version_info=options.python_version,
                    abi=options.abi,
                    implementation=options.implementation,
                ),
            )

            requirement_set = self.get_requirements(
                args,
                options,
                finder,
                session,
            )

            candidates = []
            for req in requirement_set:
                # extract from finder.find_requirement
                all_candidates = finder.find_all_candidates(req.name)
                candidates.extend(all_candidates)

        self.candidates = candidates
        return SUCCESS
Пример #5
0
    def __init__(
            self,
            target_python=None,  # type: Optional[TargetPython]
            prefer_binary=False,  # type: bool
            allow_all_prereleases=False,  # type: bool
            ignore_requires_python=None,  # type: Optional[bool]
    ):
        # type: (...) -> None
        """
        :param target_python: The target Python interpreter to use to check
            both the Python version embedded in the filename and the package's
            "Requires-Python" metadata. If None (the default), then a
            TargetPython object will be constructed from the running Python.
        :param allow_all_prereleases: Whether to allow all pre-releases.
        :param ignore_requires_python: Whether to ignore incompatible
            "Requires-Python" values in links. Defaults to False.
        """
        if target_python is None:
            target_python = TargetPython()
        if ignore_requires_python is None:
            ignore_requires_python = False

        self._ignore_requires_python = ignore_requires_python
        self._prefer_binary = prefer_binary
        self._target_python = target_python

        # We compile the regex here instead of as a class attribute so as
        # not to impact pip start-up time.  This is also okay because
        # CandidateEvaluator is generally instantiated only once per pip
        # invocation (when PackageFinder is instantiated).
        self._py_version_re = re.compile(r'-py([123]\.?[0-9]?)$')

        self.allow_all_prereleases = allow_all_prereleases
Пример #6
0
    def test_make_link_evaluator(
        self,
        allow_yanked,
        ignore_requires_python,
        only_binary,
        expected_formats,
    ):
        # Create a test TargetPython that we can check for.
        target_python = TargetPython(py_version_info=(3, 7))
        format_control = FormatControl(set(), only_binary)
        finder = PackageFinder(
            search_scope=SearchScope([], []),
            session=PipSession(),
            target_python=target_python,
            allow_yanked=allow_yanked,
            format_control=format_control,
            ignore_requires_python=ignore_requires_python,
        )

        # Pass a project_name that will be different from canonical_name.
        link_evaluator = finder.make_link_evaluator('Twine')

        assert link_evaluator.project_name == 'Twine'
        assert link_evaluator._canonical_name == 'twine'
        assert link_evaluator._allow_yanked == allow_yanked
        assert link_evaluator._ignore_requires_python == ignore_requires_python
        assert link_evaluator._formats == expected_formats

        # Test the _target_python attribute.
        actual_target_python = link_evaluator._target_python
        # The target_python attribute should be set as is.
        assert actual_target_python is target_python
        # For good measure, check that the attributes weren't reset.
        assert actual_target_python._given_py_version_info == (3, 7)
        assert actual_target_python.py_version_info == (3, 7, 0)
Пример #7
0
    def _get_finder():
        try:
            return PackageFinder(find_links=[],
                                 index_urls=[],
                                 session=PipSession())
        except TypeError:
            pass

        # pip 19.3
        from pip._internal.models.search_scope import SearchScope
        from pip._internal.models.selection_prefs import SelectionPreferences
        try:
            return PackageFinder.create(
                search_scope=SearchScope(find_links=[], index_urls=[]),
                selection_prefs=SelectionPreferences(allow_yanked=False),
                session=PipSession(),
            )
        except TypeError:
            pass

        from pip._internal.models.target_python import TargetPython
        try:
            # pip 19.3.1
            from pip._internal.collector import LinkCollector
        except ImportError:
            from pip._internal.index.collector import LinkCollector
        return PackageFinder.create(
            link_collector=LinkCollector(
                search_scope=SearchScope(find_links=[], index_urls=[]),
                session=PipSession(),
            ),
            selection_prefs=SelectionPreferences(allow_yanked=False),
            target_python=TargetPython(),
        )
Пример #8
0
    def create(
            cls,
            link_collector,  # type: LinkCollector
            selection_prefs,  # type: SelectionPreferences
            target_python=None,  # type: Optional[TargetPython]
    ):
        # type: (...) -> PackageFinder
        """Create a PackageFinder.

        :param selection_prefs: The candidate selection preferences, as a
            SelectionPreferences object.
        :param target_python: The target Python interpreter to use when
            checking compatibility. If None (the default), a TargetPython
            object will be constructed from the running Python.
        """
        if target_python is None:
            target_python = TargetPython()

        candidate_prefs = CandidatePreferences(
            prefer_binary=selection_prefs.prefer_binary,
            allow_all_prereleases=selection_prefs.allow_all_prereleases,
        )

        return cls(
            candidate_prefs=candidate_prefs,
            link_collector=link_collector,
            target_python=target_python,
            allow_yanked=selection_prefs.allow_yanked,
            format_control=selection_prefs.format_control,
            ignore_requires_python=selection_prefs.ignore_requires_python,
        )
Пример #9
0
    def create(
        cls,
        project_name: str,
        target_python: Optional[TargetPython] = None,
        prefer_binary: bool = False,
        allow_all_prereleases: bool = False,
        specifier: Optional[specifiers.BaseSpecifier] = None,
        hashes: Optional[Hashes] = None,
    ) -> "CandidateEvaluator":
        """Create a CandidateEvaluator object.

        :param target_python: The target Python interpreter to use when
            checking compatibility. If None (the default), a TargetPython
            object will be constructed from the running Python.
        :param specifier: An optional object implementing `filter`
            (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable
            versions.
        :param hashes: An optional collection of allowed hashes.
        """
        if target_python is None:
            target_python = TargetPython()
        if specifier is None:
            specifier = specifiers.SpecifierSet()

        supported_tags = target_python.get_tags()

        return cls(
            project_name=project_name,
            supported_tags=supported_tags,
            specifier=specifier,
            prefer_binary=prefer_binary,
            allow_all_prereleases=allow_all_prereleases,
            hashes=hashes,
        )
Пример #10
0
 def test_init__target_python(self):
     """
     Test the target_python argument.
     """
     target_python = TargetPython(py_version_info=(3, 7, 3))
     evaluator = CandidateEvaluator(target_python=target_python)
     # The target_python attribute should be set as is.
     assert evaluator._target_python is target_python
Пример #11
0
    def test_get_tags(
        self,
        mock_get_supported,
        py_version_info,
        expected_version,
    ):
        mock_get_supported.return_value = ['tag-1', 'tag-2']

        target_python = TargetPython(py_version_info=py_version_info)
        actual = target_python.get_tags()
        assert actual == ['tag-1', 'tag-2']

        actual = mock_get_supported.call_args[1]['version']
        assert actual == expected_version

        # Check that the value was cached.
        assert target_python._valid_tags == ['tag-1', 'tag-2']
Пример #12
0
def make_target_python(options):
    # type: (Values) -> TargetPython
    target_python = TargetPython(
        platform=options.platform,
        py_version_info=options.python_version,
        abi=options.abi,
        implementation=options.implementation,
    )
Пример #13
0
    def test_get_tags(
        self,
        mock_get_supported: mock.Mock,
        py_version_info: Optional[Tuple[int, ...]],
        expected_version: Optional[str],
    ) -> None:
        mock_get_supported.return_value = ["tag-1", "tag-2"]

        target_python = TargetPython(py_version_info=py_version_info)
        actual = target_python.get_tags()
        assert actual == ["tag-1", "tag-2"]

        actual = mock_get_supported.call_args[1]["version"]
        assert actual == expected_version

        # Check that the value was cached.
        assert target_python._valid_tags == ["tag-1", "tag-2"]
Пример #14
0
def make_target_python(options: Values) -> TargetPython:
    target_python = TargetPython(
        platforms=options.platforms,
        py_version_info=options.python_version,
        abis=options.abis,
        implementation=options.implementation,
    )

    return target_python
Пример #15
0
 def make_test_link_evaluator(self, formats):
     target_python = TargetPython()
     return LinkEvaluator(
         project_name='pytest',
         canonical_name='pytest',
         formats=formats,
         target_python=target_python,
         allow_yanked=True,
     )
Пример #16
0
 def make_test_link_evaluator(self, formats: Iterable[str]) -> LinkEvaluator:
     target_python = TargetPython()
     return LinkEvaluator(
         project_name="pytest",
         canonical_name="pytest",
         formats=frozenset(formats),
         target_python=target_python,
         allow_yanked=True,
     )
Пример #17
0
    def create(
            cls,
            search_scope,  # type: SearchScope
            selection_prefs,  # type: SelectionPreferences
            trusted_hosts=None,  # type: Optional[List[str]]
            session=None,  # type: Optional[PipSession]
            target_python=None,  # type: Optional[TargetPython]
    ):
        # type: (...) -> PackageFinder
        """Create a PackageFinder.

        :param selection_prefs: The candidate selection preferences, as a
            SelectionPreferences object.
        :param trusted_hosts: Domains not to emit warnings for when not using
            HTTPS.
        :param session: The Session to use to make requests.
        :param target_python: The target Python interpreter to use when
            checking compatibility. If None (the default), a TargetPython
            object will be constructed from the running Python.
        """
        if session is None:
            raise TypeError(
                "PackageFinder.create() missing 1 required keyword argument: "
                "'session'")
        if target_python is None:
            target_python = TargetPython()

        supported_tags = target_python.get_tags()
        candidate_evaluator = CandidateEvaluator(
            supported_tags=supported_tags,
            prefer_binary=selection_prefs.prefer_binary,
            allow_all_prereleases=selection_prefs.allow_all_prereleases,
        )

        return cls(
            candidate_evaluator=candidate_evaluator,
            search_scope=search_scope,
            session=session,
            target_python=target_python,
            allow_yanked=selection_prefs.allow_yanked,
            format_control=selection_prefs.format_control,
            trusted_hosts=trusted_hosts,
            ignore_requires_python=selection_prefs.ignore_requires_python,
        )
Пример #18
0
    def test_init__py_version_info_none(self):
        """
        Test passing py_version_info=None.
        """
        target_python = TargetPython(py_version_info=None)

        assert target_python._given_py_version_info is None

        assert target_python.py_version_info == CURRENT_PY_VERSION_INFO
        assert target_python.py_version == pyversion
Пример #19
0
 def test_evaluate_link__incompatible_wheel(self):
     """
     Test an incompatible wheel.
     """
     target_python = TargetPython(py_version_info=(3, 6, 4))
     # Set the valid tags to an empty list to make sure nothing matches.
     target_python._valid_tags = []
     evaluator = CandidateEvaluator(target_python=target_python)
     link = Link('https://example.com/sample-1.0-py2.py3-none-any.whl')
     search = Search(
         supplied='sample',
         canonical='sample',
         formats=['binary'],
     )
     actual = evaluator.evaluate_link(link, search=search)
     expected = (
         False,
         "none of the wheel's tags match: py2-none-any, py3-none-any")
     assert actual == expected
Пример #20
0
    def test_link_sorting(self):
        """
        Test link sorting
        """
        links = [
            InstallationCandidate("simple", "2.0", Link('simple-2.0.tar.gz')),
            InstallationCandidate(
                "simple",
                "1.0",
                Link('simple-1.0-pyT-none-TEST.whl'),
            ),
            InstallationCandidate(
                "simple",
                '1.0',
                Link('simple-1.0-pyT-TEST-any.whl'),
            ),
            InstallationCandidate(
                "simple",
                '1.0',
                Link('simple-1.0-pyT-none-any.whl'),
            ),
            InstallationCandidate(
                "simple",
                '1.0',
                Link('simple-1.0.tar.gz'),
            ),
        ]
        valid_tags = [
            ('pyT', 'none', 'TEST'),
            ('pyT', 'TEST', 'any'),
            ('pyT', 'none', 'any'),
        ]
        target_python = TargetPython()
        target_python._valid_tags = valid_tags
        evaluator = CandidateEvaluator(
            allow_yanked=True,
            target_python=target_python,
        )
        sort_key = evaluator._sort_key
        results = sorted(links, key=sort_key, reverse=True)
        results2 = sorted(reversed(links), key=sort_key, reverse=True)

        assert links == results == results2, results2
Пример #21
0
 def test_evaluate_link__incompatible_wheel(self):
     """
     Test an incompatible wheel.
     """
     target_python = TargetPython(py_version_info=(3, 6, 4))
     # Set the valid tags to an empty list to make sure nothing matches.
     target_python._valid_tags = []
     evaluator = LinkEvaluator(
         project_name='sample',
         canonical_name='sample',
         formats={'binary'},
         target_python=target_python,
         allow_yanked=True,
     )
     link = Link('https://example.com/sample-1.0-py2.py3-none-any.whl')
     actual = evaluator.evaluate_link(link)
     expected = (
         False,
         "none of the wheel's tags match: py2-none-any, py3-none-any")
     assert actual == expected
Пример #22
0
    def __init__(
            self,
            supported_tags=None,  # type: Optional[List[Pep425Tag]]
            prefer_binary=False,  # type: bool
            allow_all_prereleases=False,  # type: bool
    ):
        # type: (...) -> None
        """
        :param supported_tags: The PEP 425 tags supported by the target
            Python in order of preference (most preferred first). If None,
            then the list will be generated from the running Python.
        :param allow_all_prereleases: Whether to allow all pre-releases.
        """
        if supported_tags is None:
            target_python = TargetPython()
            supported_tags = target_python.get_tags()

        self._prefer_binary = prefer_binary
        self._supported_tags = supported_tags

        self.allow_all_prereleases = allow_all_prereleases
Пример #23
0
    def test_make_candidate_evaluator(
        self, allow_all_prereleases, prefer_binary,
    ):
        target_python = TargetPython()
        target_python._valid_tags = [('py36', 'none', 'any')]
        candidate_prefs = CandidatePreferences(
            prefer_binary=prefer_binary,
            allow_all_prereleases=allow_all_prereleases,
        )
        finder = PackageFinder(
            search_scope=SearchScope([], []),
            session=PipSession(),
            target_python=target_python,
            allow_yanked=True,
            candidate_prefs=candidate_prefs,
        )

        evaluator = finder.make_candidate_evaluator()
        assert evaluator._allow_all_prereleases == allow_all_prereleases
        assert evaluator._prefer_binary == prefer_binary
        assert evaluator._supported_tags == [('py36', 'none', 'any')]
Пример #24
0
    def test_init__py_version_info(self, py_version_info, expected):
        """
        Test passing the py_version_info argument.
        """
        expected_py_version_info, expected_py_version = expected

        target_python = TargetPython(py_version_info=py_version_info)

        # The _given_py_version_info attribute should be set as is.
        assert target_python._given_py_version_info == py_version_info

        assert target_python.py_version_info == expected_py_version_info
        assert target_python.py_version == expected_py_version
Пример #25
0
 def test_evaluate_link__incompatible_wheel(self) -> None:
     """
     Test an incompatible wheel.
     """
     target_python = TargetPython(py_version_info=(3, 6, 4))
     # Set the valid tags to an empty list to make sure nothing matches.
     target_python._valid_tags = []
     evaluator = LinkEvaluator(
         project_name="sample",
         canonical_name="sample",
         formats=frozenset(["binary"]),
         target_python=target_python,
         allow_yanked=True,
     )
     link = Link("https://example.com/sample-1.0-py2.py3-none-any.whl")
     actual = evaluator.evaluate_link(link)
     expected = (
         False,
         "none of the wheel's tags (py2-none-any, py3-none-any) are compatible "
         "(run pip debug --verbose to show compatible tags)",
     )
     assert actual == expected
Пример #26
0
    def test_init__py_version_info_none(self):
        """
        Test passing py_version_info=None.
        """
        # Get the index of the second dot.
        index = sys.version.find('.', 2)
        current_major_minor = sys.version[:index]  # e.g. "3.6"

        target_python = TargetPython(py_version_info=None)

        assert target_python._given_py_version_info is None

        assert target_python.py_version_info == CURRENT_PY_VERSION_INFO
        assert target_python.py_version == current_major_minor
Пример #27
0
 def test_create__candidate_evaluator(
     self, allow_all_prereleases, prefer_binary,
 ):
     """
     Test that the candidate_evaluator attribute is set correctly.
     """
     selection_prefs = SelectionPreferences(
         allow_yanked=True,
         allow_all_prereleases=allow_all_prereleases,
         prefer_binary=prefer_binary,
     )
     target_python = TargetPython(py_version_info=(3, 7, 3))
     target_python._valid_tags = ['tag1', 'tag2']
     finder = PackageFinder.create(
         search_scope=SearchScope([], []),
         selection_prefs=selection_prefs,
         session=PipSession(),
         target_python=target_python,
     )
     evaluator = finder.candidate_evaluator
     assert evaluator.allow_all_prereleases == allow_all_prereleases
     assert evaluator._prefer_binary == prefer_binary
     assert evaluator._supported_tags == ['tag1', 'tag2']
Пример #28
0
    def test_make_candidate_evaluator(
        self,
        allow_all_prereleases: bool,
        prefer_binary: bool,
    ) -> None:
        target_python = TargetPython()
        target_python._valid_tags = [Tag("py36", "none", "any")]
        candidate_prefs = CandidatePreferences(
            prefer_binary=prefer_binary,
            allow_all_prereleases=allow_all_prereleases,
        )
        link_collector = LinkCollector(
            session=PipSession(),
            search_scope=SearchScope([], []),
        )
        finder = PackageFinder(
            link_collector=link_collector,
            target_python=target_python,
            allow_yanked=True,
            candidate_prefs=candidate_prefs,
            use_deprecated_html5lib=False,
        )

        specifier = SpecifierSet()
        # Pass hashes to check that _hashes is set.
        hashes = Hashes({"sha256": [64 * "a"]})
        evaluator = finder.make_candidate_evaluator(
            "my-project",
            specifier=specifier,
            hashes=hashes,
        )
        assert evaluator._allow_all_prereleases == allow_all_prereleases
        assert evaluator._hashes == hashes
        assert evaluator._prefer_binary == prefer_binary
        assert evaluator._project_name == "my-project"
        assert evaluator._specifier is specifier
        assert evaluator._supported_tags == [Tag("py36", "none", "any")]
Пример #29
0
    def test_make_candidate_evaluator(
        self,
        allow_all_prereleases,
        prefer_binary,
    ):
        target_python = TargetPython()
        target_python._valid_tags = [('py36', 'none', 'any')]
        candidate_prefs = CandidatePreferences(
            prefer_binary=prefer_binary,
            allow_all_prereleases=allow_all_prereleases,
        )
        link_collector = LinkCollector(
            session=PipSession(),
            search_scope=SearchScope([], []),
        )
        finder = PackageFinder(
            link_collector=link_collector,
            target_python=target_python,
            allow_yanked=True,
            candidate_prefs=candidate_prefs,
        )

        specifier = SpecifierSet()
        # Pass hashes to check that _hashes is set.
        hashes = Hashes({'sha256': [64 * 'a']})
        evaluator = finder.make_candidate_evaluator(
            'my-project',
            specifier=specifier,
            hashes=hashes,
        )
        assert evaluator._allow_all_prereleases == allow_all_prereleases
        assert evaluator._hashes == hashes
        assert evaluator._prefer_binary == prefer_binary
        assert evaluator._project_name == 'my-project'
        assert evaluator._specifier is specifier
        assert evaluator._supported_tags == [('py36', 'none', 'any')]
Пример #30
0
 def test_create__target_python(self):
     """
     Test that target_python is passed to CandidateEvaluator as is.
     """
     target_python = TargetPython(py_version_info=(3, 7, 3))
     finder = PackageFinder.create(
         [],
         [],
         session=object(),
         target_python=target_python,
     )
     evaluator = finder.candidate_evaluator
     actual_target_python = evaluator._target_python
     assert actual_target_python is target_python
     assert actual_target_python.py_version_info == (3, 7, 3)