Example #1
0
 def test_evaluate_link(
     self,
     py_version_info,
     ignore_requires_python,
     expected,
 ):
     target_python = TargetPython(py_version_info=py_version_info)
     evaluator = LinkEvaluator(
         project_name='twine',
         canonical_name='twine',
         formats={'source'},
         target_python=target_python,
         allow_yanked=True,
         ignore_requires_python=ignore_requires_python,
     )
     link = Link(
         'https://example.com/#egg=twine-1.12',
         requires_python='== 3.6.5',
     )
     actual = evaluator.evaluate_link(link)
     assert actual == expected
Example #2
0
def test_unpack_http_url_bad_downloaded_checksum(mock_unpack_file):
    """
    If already-downloaded file has bad checksum, re-download.
    """
    base_url = 'http://www.example.com/somepackage.tgz'
    contents = b'downloaded'
    download_hash = hashlib.new('sha1', contents)
    link = Link(base_url + '#sha1=' + download_hash.hexdigest())

    session = Mock()
    session.get = Mock()
    response = session.get.return_value = MockResponse(contents)
    response.headers = {'content-type': 'application/x-tar'}
    response.url = base_url

    download_dir = mkdtemp()
    try:
        downloaded_file = os.path.join(download_dir, 'somepackage.tgz')
        create_file(downloaded_file, 'some contents')

        unpack_http_url(
            link,
            'location',
            download_dir=download_dir,
            session=session,
            hashes=Hashes({'sha1': [download_hash.hexdigest()]})
        )

        # despite existence of downloaded file with bad hash, downloaded again
        session.get.assert_called_once_with(
            'http://www.example.com/somepackage.tgz',
            headers={"Accept-Encoding": "identity"},
            stream=True,
        )
        # cached file is replaced with newly downloaded file
        with open(downloaded_file) as fh:
            assert fh.read() == 'downloaded'

    finally:
        rmtree(download_dir)
Example #3
0
 def test_evaluate_link(
     self,
     py_version_info,
     ignore_requires_python,
     expected,
 ):
     link = Link(
         'https://example.com/#egg=twine-1.12',
         requires_python='== 3.6.5',
     )
     search = Search(
         supplied='twine',
         canonical='twine',
         formats=['source'],
     )
     evaluator = CandidateEvaluator(
         [],
         py_version_info=py_version_info,
         ignore_requires_python=ignore_requires_python,
     )
     actual = evaluator.evaluate_link(link, search=search)
     assert actual == expected
Example #4
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(
         allow_yanked=True,
         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
Example #5
0
def pip_download_link(resconfig, url: str, destdir: str) -> Dict:
    link = Link(url)
    tmpdir = tempfile.mkdtemp(prefix='.tmp-')
    with redirect_stdout(sys.stderr):

        netloc = urlsplit(resconfig['source']['repository']['index_url'])[1]
        hostname = netloc.split(':')[0]
        with PipSession(retries=RETRIES, insecure_hosts=[
                hostname,
        ]) as session:
            session.timeout = TIMEOUT
            session.auth.prompting = False
            session.auth.passwords[netloc] = (
                resconfig['source']['repository'].get('username', None),
                resconfig['source']['repository'].get('password', None))

            unpack_url(link,
                       tmpdir,
                       destdir,
                       only_download=True,
                       session=session)

    shutil.rmtree(tmpdir)
    def from_editable(
        cls,
        editable_req,
        comes_from=None,
        isolated=False,
        options=None,
        wheel_cache=None,
        constraint=False,
    ):
        from pip._internal.index import Link

        name, url, extras_override = parse_editable(editable_req)
        if url.startswith("file:"):
            source_dir = url_to_path(url)
        else:
            source_dir = None

        if name is not None:
            try:
                req = Requirement(name)
            except InvalidRequirement:
                raise InstallationError("Invalid requirement: '%s'" % name)
        else:
            req = None
        return cls(
            req,
            comes_from,
            source_dir=source_dir,
            editable=True,
            link=Link(url),
            constraint=constraint,
            isolated=isolated,
            options=options if options else {},
            wheel_cache=wheel_cache,
            extras=extras_override or (),
        )
Example #7
0
 def test_ext_fragment(self):
     assert '.whl' == Link('http://yo/wheel.whl#frag').ext
Example #8
0
 def test_ext(self):
     assert '.whl' == Link('http://yo/wheel.whl').ext
Example #9
0
 def test_no_ext(self):
     assert '' == Link('http://yo/wheel').ext
Example #10
0
 def test_filename(self, url, expected):
     assert Link(url).filename == expected
Example #11
0
 def test_file_link(self, cwd, tmpdir):
     os.chdir(str(tmpdir))
     assert link_to_nix(Link('file://{}'.format(tmpdir))) == './.'
def parse_editable(editable_req):
    """Parses an editable requirement into:
        - a requirement name
        - an URL
        - extras
        - editable options
    Accepted requirements:
        svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir
        .[some_extra]
    """

    from pip._internal.index import Link

    url = editable_req

    # If a file path is specified with extras, strip off the extras.
    url_no_extras, extras = _strip_extras(url)

    if os.path.isdir(url_no_extras):
        if not os.path.exists(os.path.join(url_no_extras, 'setup.py')):
            raise InstallationError(
                "Directory %r is not installable. File 'setup.py' not found." %
                url_no_extras
            )
        # Treating it as code that has already been checked out
        url_no_extras = path_to_url(url_no_extras)

    if url_no_extras.lower().startswith('file:'):
        package_name = Link(url_no_extras).egg_fragment
        if extras:
            return (
                package_name,
                url_no_extras,
                Requirement("placeholder" + extras.lower()).extras,
            )
        else:
            return package_name, url_no_extras, None

    for version_control in vcs:
        if url.lower().startswith('%s:' % version_control):
            url = '%s+%s' % (version_control, url)
            break

    if '+' not in url:
        raise InstallationError(
            '%s should either be a path to a local project or a VCS url '
            'beginning with svn+, git+, hg+, or bzr+' %
            editable_req
        )

    vc_type = url.split('+', 1)[0].lower()

    if not vcs.get_backend(vc_type):
        error_message = 'For --editable=%s only ' % editable_req + \
                        ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \
                        ' is currently supported'
        raise InstallationError(error_message)

    package_name = Link(url).egg_fragment
    if not package_name:
        raise InstallationError(
            "Could not detect requirement name for '%s', please specify one "
            "with #egg=your_package_name" % editable_req
        )
    return _strip_postfix(package_name), url, None
Example #13
0
 def test_is_wheel_false(self):
     assert not Link('http://yo/not_a_wheel').is_wheel
Example #14
0
 def test_evaluate_link__match(self, url, expected_version):
     """Test that 'pytest' archives match for 'pytest'"""
     link = Link(url)
     evaluator = self.make_test_link_evaluator(formats=['source', 'binary'])
     actual = evaluator.evaluate_link(link)
     assert actual == (True, expected_version)
Example #15
0
    def make_mock_candidate(self, version, yanked_reason=None):
        url = 'https://example.com/pkg-{}.tar.gz'.format(version)
        link = Link(url, yanked_reason=yanked_reason)
        candidate = InstallationCandidate('mypackage', version, link)

        return candidate
Example #16
0
 def test_ext_query(self):
     assert '.whl' == Link('http://yo/wheel.whl?a=b').ext
Example #17
0
 def test_is_wheel(self):
     assert Link('http://yo/wheel.whl').is_wheel
Example #18
0
 def test_evaluate_link__substring_fails(self, url, expected_msg):
     """Test that 'pytest<something> archives won't match for 'pytest'."""
     link = Link(url)
     evaluator = self.make_test_link_evaluator(formats=['source', 'binary'])
     actual = evaluator.evaluate_link(link)
     assert actual == (False, expected_msg)
Example #19
0
    def __init__(self,
                 req,
                 comes_from,
                 source_dir=None,
                 editable=False,
                 link=None,
                 update=True,
                 markers=None,
                 isolated=False,
                 options=None,
                 wheel_cache=None,
                 constraint=False,
                 extras=()):
        assert req is None or isinstance(req, Requirement), req
        self.req = req
        self.comes_from = comes_from
        self.constraint = constraint
        if source_dir is not None:
            self.source_dir = os.path.normpath(os.path.abspath(source_dir))
        else:
            self.source_dir = None
        self.editable = editable

        self._wheel_cache = wheel_cache
        if link is not None:
            self.link = self.original_link = link
        else:
            from pip._internal.index import Link
            self.link = self.original_link = req and req.url and Link(req.url)

        if extras:
            self.extras = extras
        elif req:
            self.extras = {
                pkg_resources.safe_extra(extra)
                for extra in req.extras
            }
        else:
            self.extras = set()
        if markers is not None:
            self.markers = markers
        else:
            self.markers = req and req.marker
        self._egg_info_path = None
        # This holds the pkg_resources.Distribution object if this requirement
        # is already available:
        self.satisfied_by = None
        # This hold the pkg_resources.Distribution object if this requirement
        # conflicts with another installed distribution:
        self.conflicts_with = None
        # Temporary build location
        self._temp_build_dir = TempDirectory(kind="req-build")
        # Used to store the global directory where the _temp_build_dir should
        # have been created. Cf _correct_build_location method.
        self._ideal_build_dir = None
        # True if the editable should be updated:
        self.update = update
        # Set to True after successful installation
        self.install_succeeded = None
        # UninstallPathSet of uninstalled distribution (for possible rollback)
        self.uninstalled_pathset = None
        self.options = options if options else {}
        # Set to True after successful preparation of this requirement
        self.prepared = False
        self.is_direct = False

        self.isolated = isolated
        self.build_env = BuildEnvironment(no_clean=True)
Example #20
0
def test_check_link_requires_python(requires_python, expected):
    version_info = (3, 6, 5)
    link = Link('https://example.com', requires_python=requires_python)
    actual = _check_link_requires_python(link, version_info)
    assert actual == expected
    def from_line(
            cls, name, comes_from=None, isolated=False, options=None,
            wheel_cache=None, constraint=False):
        """Creates an InstallRequirement from a name, which might be a
        requirement, directory containing 'setup.py', filename, or URL.
        """
        from pip._internal.index import Link

        if is_url(name):
            marker_sep = '; '
        else:
            marker_sep = ';'
        if marker_sep in name:
            name, markers = name.split(marker_sep, 1)
            markers = markers.strip()
            if not markers:
                markers = None
            else:
                markers = Marker(markers)
        else:
            markers = None
        name = name.strip()
        req = None
        path = os.path.normpath(os.path.abspath(name))
        link = None
        extras = None

        if is_url(name):
            link = Link(name)
        else:
            p, extras = _strip_extras(path)
            looks_like_dir = os.path.isdir(p) and (
                    os.path.sep in name or
                    (os.path.altsep is not None and os.path.altsep in name) or
                    name.startswith('.')
            )
            if looks_like_dir:
                if not is_installable_dir(p):
                    raise InstallationError(
                        "Directory %r is not installable. File 'setup.py' "
                        "not found." % name
                    )
                link = Link(path_to_url(p))
            elif is_archive_file(p):
                if not os.path.isfile(p):
                    logger.warning(
                        'Requirement %r looks like a filename, but the '
                        'file does not exist',
                        name
                    )
                link = Link(path_to_url(p))

        # it's a local file, dir, or url
        if link:
            # Handle relative file URLs
            if link.scheme == 'file' and re.search(r'\.\./', link.url):
                link = Link(
                    path_to_url(os.path.normpath(os.path.abspath(link.path))))
            # wheel file
            if link.is_wheel:
                wheel = Wheel(link.filename)  # can raise InvalidWheelFilename
                req = "%s==%s" % (wheel.name, wheel.version)
            else:
                # set the req to the egg fragment.  when it's not there, this
                # will become an 'unnamed' requirement
                req = link.egg_fragment

        # a requirement specifier
        else:
            req = name

        if extras:
            extras = Requirement("placeholder" + extras.lower()).extras
        else:
            extras = ()
        if req is not None:
            try:
                req = Requirement(req)
            except InvalidRequirement:
                if os.path.sep in req:
                    add_msg = "It looks like a path."
                    add_msg += deduce_helpful_msg(req)
                elif '=' in req and not any(op in req for op in operators):
                    add_msg = "= is not a valid operator. Did you mean == ?"
                else:
                    add_msg = traceback.format_exc()
                raise InstallationError(
                    "Invalid requirement: '%s'\n%s" % (req, add_msg))
        return cls(
            req, comes_from, link=link, markers=markers,
            isolated=isolated,
            options=options if options else {},
            wheel_cache=wheel_cache,
            constraint=constraint,
            extras=extras,
        )
Example #22
0
 def test_splitext(self):
     assert ('wheel', '.whl') == Link('http://yo/wheel.whl').splitext()