Exemplo n.º 1
0
 def from_pipfile(cls, name, pipfile):
     creation_args = {}
     pipfile_keys = [
         k for k in ("ref", "vcs", "subdirectory", "path", "editable",
                     "file", "uri", "extras") + VCS_LIST if k in pipfile
     ]
     for key in pipfile_keys:
         if key == "extras":
             extras = pipfile.get(key, None)
             if extras:
                 pipfile[key] = sorted(
                     dedup([extra.lower() for extra in extras]))
         if key in VCS_LIST:
             creation_args["vcs"] = key
             target = pipfile.get(key)
             drive, path = os.path.splitdrive(target)
             if not drive and not os.path.exists(target) and (
                     is_valid_url(target) or is_file_url(target)
                     or target.startswith('git@')):
                 creation_args["uri"] = target
             else:
                 creation_args["path"] = target
                 if os.path.isabs(target):
                     creation_args["uri"] = path_to_url(target)
         else:
             creation_args[key] = pipfile.get(key)
     creation_args["name"] = name
     return cls(**creation_args)
Exemplo n.º 2
0
 def from_pipfile(cls, name, pipfile):
     creation_args = {}
     pipfile_keys = [
         k for k in ("ref", "vcs", "subdirectory", "path", "editable",
                     "file", "uri", "extras") + VCS_LIST if k in pipfile
     ]
     for key in pipfile_keys:
         if key == "extras":
             extras = pipfile.get(key, None)
             if extras:
                 pipfile[key] = sorted(
                     dedup([extra.lower() for extra in extras]))
         if key in VCS_LIST:
             creation_args["vcs"] = key
             composed_uri = add_ssh_scheme_to_git_uri("{0}+{1}".format(
                 key, pipfile.get(key))).split("+", 1)[1]
             url_keys = [pipfile.get(key), composed_uri]
             is_url = any(
                 validity_fn(url_key) for url_key in url_keys
                 for validity_fn in [is_valid_url, is_file_url])
             target_key = "uri" if is_url else "path"
             creation_args[target_key] = pipfile.get(key)
         else:
             creation_args[key] = pipfile.get(key)
     creation_args["name"] = name
     return cls(**creation_args)
Exemplo n.º 3
0
def parse_extras(extras_str):
    # type: (AnyStr) -> List[AnyStr]
    """
    Turn a string of extras into a parsed extras list
    """

    from pkg_resources import Requirement

    extras = Requirement.parse("fakepkg{0}".format(
        extras_to_string(extras_str))).extras
    return sorted(dedup([extra.lower() for extra in extras]))
Exemplo n.º 4
0
def _sources_as_lines(sources):
    source_lines = list(
        dedup(
            itertools.chain(
                itertools.chain.from_iterable(
                    _single_source_as_line(source, False)
                    for source in sources[:1]),
                itertools.chain.from_iterable(
                    _single_source_as_line(source, True)
                    for source in sources[1:]),
            )))
    return source_lines
Exemplo n.º 5
0
def cleanup_pyspecs(specs, joiner="or"):
    if isinstance(specs, six.string_types):
        specs = set([_format_pyspec(specs)])
    else:
        specs = {_format_pyspec(spec) for spec in specs}
    # for != operator we want to group by version
    # if all are consecutive, join as a list
    results = set()
    for op, versions in _group_by_op(tuple(specs)):
        versions = [version[1] for version in versions]
        versions = sorted(dedup(versions))
        # if we are doing an or operation, we need to use the min for >=
        # this way OR(>=2.6, >=2.7, >=3.6) picks >=2.6
        # if we do an AND operation we need to use MAX to be more selective
        if op in (">", ">="):
            if joiner == "or":
                results.add((op, _format_version(min(versions))))
            else:
                results.add((op, _format_version(max(versions))))
        # we use inverse logic here so we will take the max value if we are
        # using OR but the min value if we are using AND
        elif op in ("<=", "<"):
            if joiner == "or":
                results.add((op, _format_version(max(versions))))
            else:
                results.add((op, _format_version(min(versions))))
        # leave these the same no matter what operator we use
        elif op in ("!=", "==", "~="):
            version_list = sorted(
                "{0}".format(_format_version(version)) for version in versions
            )
            version = ", ".join(version_list)
            if len(version_list) == 1:
                results.add((op, version))
            elif op == "!=":
                results.add(("not in", version))
            elif op == "==":
                results.add(("in", version))
            else:
                specifier = SpecifierSet(
                    ",".join(sorted("{0}{1}".format(op, v) for v in version_list))
                )._specs
                for s in specifier:
                    results.add((s._spec[0], s._spec[1]))
        else:
            if len(version) == 1:
                results.add((op, version))
            else:
                specifier = SpecifierSet("{0}".format(version))._specs
                for s in specifier:
                    results.add((s._spec[0], s._spec[1]))
    return sorted(results, key=operator.itemgetter(1))
def cleanup_pyspecs(specs, joiner="or"):
    specs = normalize_specifier_set(specs)
    # for != operator we want to group by version
    # if all are consecutive, join as a list
    results = {}
    translation_map = {
        # if we are doing an or operation, we need to use the min for >=
        # this way OR(>=2.6, >=2.7, >=3.6) picks >=2.6
        # if we do an AND operation we need to use MAX to be more selective
        (">", ">="): {
            "or": lambda x: _format_version(min(x)),
            "and": lambda x: _format_version(max(x)),
        },
        # we use inverse logic here so we will take the max value if we are
        # using OR but the min value if we are using AND
        ("<", "<="): {
            "or": lambda x: _format_version(max(x)),
            "and": lambda x: _format_version(min(x)),
        },
        # leave these the same no matter what operator we use
        ("!=", "==", "~=", "==="): {
            "or": get_sorted_version_string,
            "and": get_sorted_version_string,
        },
    }
    op_translations = {
        "!=": lambda x: "not in" if len(x) > 1 else "!=",
        "==": lambda x: "in" if len(x) > 1 else "==",
    }
    translation_keys = list(translation_map.keys())
    for op_and_version_type, versions in _group_by_op(tuple(specs)):
        op = op_and_version_type[0]
        versions = [version[1] for version in versions]
        versions = sorted(dedup(versions))
        op_key = next(iter(k for k in translation_keys if op in k), None)
        version_value = versions
        if op_key is not None:
            version_value = translation_map[op_key][joiner](versions)
        if op in op_translations:
            op = op_translations[op](versions)
        results[(op, op_and_version_type[1])] = version_value
    return sorted([(k[0], v) for k, v in results.items()],
                  key=operator.itemgetter(1))
Exemplo n.º 7
0
    def from_pipfile(cls, name, pipfile):
        from .markers import PipenvMarkers

        _pipfile = {}
        if hasattr(pipfile, "keys"):
            _pipfile = dict(pipfile).copy()
        _pipfile["version"] = get_version(pipfile)
        vcs = first([vcs for vcs in VCS_LIST if vcs in _pipfile])
        if vcs:
            _pipfile["vcs"] = vcs
            r = VCSRequirement.from_pipfile(name, pipfile)
        elif any(key in _pipfile for key in ["path", "file", "uri"]):
            r = FileRequirement.from_pipfile(name, pipfile)
        else:
            r = NamedRequirement.from_pipfile(name, pipfile)
        markers = PipenvMarkers.from_pipfile(name, _pipfile)
        req_markers = None
        if markers:
            markers = str(markers)
            req_markers = PackagingRequirement("fakepkg; {0}".format(markers))
        r.req.marker = getattr(req_markers, "marker", None)
        r.req.specifier = SpecifierSet(_pipfile["version"])
        extras = _pipfile.get("extras")
        r.req.extras = (sorted(dedup([extra.lower()
                                      for extra in extras])) if extras else [])
        args = {
            "name": r.name,
            "vcs": vcs,
            "req": r,
            "markers": markers,
            "extras": _pipfile.get("extras"),
            "editable": _pipfile.get("editable", False),
            "index": _pipfile.get("index"),
        }
        if any(key in _pipfile for key in ["hash", "hashes"]):
            args["hashes"] = _pipfile.get("hashes", [pipfile.get("hash")])
        cls_inst = cls(**args)
        if cls_inst.is_named:
            cls_inst.req.req.line = cls_inst.as_line()
        return cls_inst
Exemplo n.º 8
0
def _convert(file_instance, sources, section_names, hashes=False):
    """
    :param file_instance: pipfile or lockfile instance
    :param hashes: bool
    :return: list
    """
    sources_lines = _sources_as_lines(sources)

    requirements = [
        Requirement.from_pipfile(key, entry._data)
        for key, entry in itertools.chain.from_iterable(
            file_instance.get(name, {}).items() for name in section_names)
    ]

    if hashes:
        hashes = all(r.is_named for r in requirements)

    requirement_lines = sorted(
        dedup(
            _requirement_as_line(requirement, hashes)
            for requirement in requirements))
    return sources_lines + [''] + requirement_lines
Exemplo n.º 9
0
 def from_line(cls, line):
     from pip_shims import InstallRequirement
     if isinstance(line, InstallRequirement):
         line = format_requirement(line)
     hashes = None
     if "--hash=" in line:
         hashes = line.split(" --hash=")
         line, hashes = hashes[0], hashes[1:]
     editable = line.startswith("-e ")
     line = line.split(" ", 1)[1] if editable else line
     line, markers = split_markers_from_line(line)
     line, extras = _strip_extras(line)
     specifiers = ''
     if extras:
         extras = parse_extras(extras)
     line = line.strip('"').strip("'").strip()
     line_with_prefix = "-e {0}".format(line) if editable else line
     vcs = None
     # Installable local files and installable non-vcs urls are handled
     # as files, generally speaking
     line_is_vcs = is_vcs(line)
     if is_installable_file(line) or (
         (is_file_url(line) or is_valid_url(line)) and not line_is_vcs):
         r = FileRequirement.from_line(line_with_prefix)
     elif line_is_vcs:
         r = VCSRequirement.from_line(line_with_prefix, extras=extras)
         vcs = r.vcs
     elif line == "." and not is_installable_file(line):
         raise RequirementError(
             "Error parsing requirement %s -- are you sure it is installable?"
             % line)
     else:
         specs = "!=<>~"
         spec_matches = set(specs) & set(line)
         version = None
         name = line
         if spec_matches:
             spec_idx = min((line.index(match) for match in spec_matches))
             name = line[:spec_idx]
             version = line[spec_idx:]
             specifiers = version
         if not extras:
             name, extras = _strip_extras(name)
             if extras:
                 extras = parse_extras(extras)
         if version:
             name = "{0}{1}".format(name, version)
         r = NamedRequirement.from_line(line)
     req_markers = None
     if markers:
         req_markers = PackagingRequirement("fakepkg; {0}".format(markers))
     r.req.marker = getattr(req_markers, "marker", None)
     r.req.local_file = getattr(r.req, "local_file", False)
     name = getattr(r.req, "name", None)
     if not name:
         name = getattr(r.req, "project_name", None)
         r.req.name = name
     if not name:
         name = getattr(r.req, "key", None)
         if name:
             r.req.name = name
     args = {
         "name": r.name,
         "vcs": vcs,
         "req": r,
         "markers": markers,
         "editable": editable,
     }
     if extras:
         extras = sorted(dedup([extra.lower() for extra in extras]))
         args["extras"] = extras
         r.req.extras = extras
         r.extras = extras
     elif r.extras:
         args["extras"] = sorted(
             dedup([extra.lower() for extra in r.extras]))
     if hashes:
         args["hashes"] = hashes
     return cls(**args)
 def _run_setup(self):
     # type: () -> "SystemPath"
     if not self.__class__ == SystemPath:
         return self
     new_instance = self
     path_order = new_instance.path_order[:]
     path_entries = self.paths.copy()
     if self.global_search and "PATH" in os.environ:
         path_order = path_order + os.environ["PATH"].split(os.pathsep)
     path_order = list(dedup(path_order))
     path_instances = [
         ensure_path(p.strip('"')) for p in path_order if not any(
             is_in_path(normalize_path(str(p)), normalize_path(shim))
             for shim in SHIM_PATHS)
     ]
     path_entries.update({
         p.as_posix(): PathEntry.create(path=p.absolute(),
                                        is_root=True,
                                        only_python=self.only_python)
         for p in path_instances
     })
     new_instance = attr.evolve(
         new_instance,
         path_order=[p.as_posix() for p in path_instances],
         paths=path_entries,
     )
     if os.name == "nt" and "windows" not in self.finders:
         new_instance = new_instance._setup_windows()
     #: slice in pyenv
     if self.check_for_pyenv() and "pyenv" not in self.finders:
         new_instance = new_instance._setup_pyenv()
     #: slice in asdf
     if self.check_for_asdf() and "asdf" not in self.finders:
         new_instance = new_instance._setup_asdf()
     venv = os.environ.get("VIRTUAL_ENV")
     if os.name == "nt":
         bin_dir = "Scripts"
     else:
         bin_dir = "bin"
     if venv and (new_instance.system or new_instance.global_search):
         p = ensure_path(venv)
         path_order = [(p / bin_dir).as_posix()] + new_instance.path_order
         new_instance = attr.evolve(new_instance, path_order=path_order)
         paths = new_instance.paths.copy()
         paths[p] = new_instance.get_path(p.joinpath(bin_dir))
         new_instance = attr.evolve(new_instance, paths=paths)
     if new_instance.system:
         syspath = Path(sys.executable)
         syspath_bin = syspath.parent
         if syspath_bin.name != bin_dir and syspath_bin.joinpath(
                 bin_dir).exists():
             syspath_bin = syspath_bin / bin_dir
         path_order = [syspath_bin.as_posix()] + new_instance.path_order
         paths = new_instance.paths.copy()
         paths[syspath_bin] = PathEntry.create(path=syspath_bin,
                                               is_root=True,
                                               only_python=False)
         new_instance = attr.evolve(new_instance,
                                    path_order=path_order,
                                    paths=paths)
     return new_instance
Exemplo n.º 11
0
def parse_extras(extras_str):
    """Turn a string of extras into a parsed extras list"""
    extras = Requirement.parse("fakepkg{0}".format(
        extras_to_string(extras_str))).extras
    return sorted(dedup([extra.lower() for extra in extras]))