def open_local_or_remote_file(link, session): """ Open local or remote file for reading. :type link: pip._internal.index.Link :type session: requests.Session :raises ValueError: If link points to a local directory. :return: a context manager to the opened file-like object """ if isinstance(link, Link): url = link.url_without_fragment else: url = link if is_file_url(link): # Local URL local_path = url_to_path(url) if os.path.isdir(local_path): raise ValueError("Cannot open directory for read: {}".format(url)) else: with open(local_path, 'rb') as local_file: yield local_file else: # Remote URL headers = {"Accept-Encoding": "identity"} response = session.get(url, headers=headers, stream=True) try: yield response.raw finally: response.close()
def get_checkout_dir(self, src_dir=None): src_dir = os.environ.get('PIP_SRC', None) if not src_dir else src_dir checkout_dir = None if self.is_local: path = self.path if not path: path = url_to_path(self.uri) if path and os.path.exists(path): checkout_dir = os.path.abspath(path) return checkout_dir return os.path.join(create_tracked_tempdir(prefix="requirementslib"), self.name)
def open_file(url, session=None): if url.startswith("file://"): local_path = url_to_path(url) if os.path.isdir(local_path): raise ValueError("Cannot open directory for read: {}".format(url)) else: with open(local_path, "rb") as local_file: yield local_file else: headers = {"Accept-Encoding": "identity"} with session.get(url, headers=headers, stream=True) as resp: try: raw = getattr(resp, "raw", None) result = raw if raw else resp yield result finally: if raw: conn = getattr(raw, "_connection") if conn is not None: conn.close() result.close()
def get_link_from_line(cls, line): """Parse link information from given requirement line. Return a 6-tuple: - `vcs_type` indicates the VCS to use (e.g. "git"), or None. - `prefer` is either "file", "path" or "uri", indicating how the information should be used in later stages. - `relpath` is the relative path to use when recording the dependency, instead of the absolute path/URI used to perform installation. This can be None (to prefer the absolute path or URI). - `path` is the absolute file path to the package. This will always use forward slashes. Can be None if the line is a remote URI. - `uri` is the absolute URI to the package. Can be None if the line is not a URI. - `link` is an instance of :class:`pip._internal.index.Link`, representing a URI parse result based on the value of `uri`. This function is provided to deal with edge cases concerning URIs without a valid netloc. Those URIs are problematic to a straight ``urlsplit` call because they cannot be reliably reconstructed with ``urlunsplit`` due to a bug in the standard library: >>> from urllib.parse import urlsplit, urlunsplit >>> urlunsplit(urlsplit('git+file:///this/breaks')) 'git+file:/this/breaks' >>> urlunsplit(urlsplit('file:///this/works')) 'file:///this/works' See `https://bugs.python.org/issue23505#msg277350`. """ # Git allows `[email protected]...` lines that are not really URIs. # Add "ssh://" so we can parse correctly, and restore afterwards. fixed_line = add_ssh_scheme_to_git_uri(line) added_ssh_scheme = fixed_line != line # We can assume a lot of things if this is a local filesystem path. if "://" not in fixed_line: p = Path(fixed_line).absolute() path = p.as_posix() uri = p.as_uri() link = create_link(uri) try: relpath = get_converted_relative_path(path) except ValueError: relpath = None return LinkInfo(None, "path", relpath, path, uri, link) # This is an URI. We'll need to perform some elaborated parsing. parsed_url = urllib_parse.urlsplit(fixed_line) original_url = parsed_url._replace() if added_ssh_scheme and ':' in parsed_url.netloc: original_netloc, original_path_start = parsed_url.netloc.rsplit( ':', 1) uri_path = '/{0}{1}'.format(original_path_start, parsed_url.path) parsed_url = original_url._replace(netloc=original_netloc, path=uri_path) # Split the VCS part out if needed. original_scheme = parsed_url.scheme if "+" in original_scheme: vcs_type, scheme = original_scheme.split("+", 1) parsed_url = parsed_url._replace(scheme=scheme) prefer = "uri" else: vcs_type = None prefer = "file" if parsed_url.scheme == "file" and parsed_url.path: # This is a "file://" URI. Use url_to_path and path_to_url to # ensure the path is absolute. Also we need to build relpath. path = Path(url_to_path( urllib_parse.urlunsplit(parsed_url))).as_posix() try: relpath = get_converted_relative_path(path) except ValueError: relpath = None uri = path_to_url(path) else: # This is a remote URI. Simply use it. path = None relpath = None # Cut the fragment, but otherwise this is fixed_line. uri = urllib_parse.urlunsplit( parsed_url._replace(scheme=original_scheme, fragment="")) if added_ssh_scheme: original_uri = urllib_parse.urlunsplit( original_url._replace(scheme=original_scheme, fragment="")) uri = strip_ssh_from_git_uri(original_uri) # Re-attach VCS prefix to build a Link. link = create_link( urllib_parse.urlunsplit( parsed_url._replace(scheme=original_scheme))) return LinkInfo(vcs_type, prefer, relpath, path, uri, link)