def __init__(self, pip_string): # type: (str) -> None if pip_string == "_root_": req = parse_req(".") req.key = "_root_" else: req = parse_req(pip_string) self._name = req.key self._req = req
def add( self, name, version, deps=None ): # type: (str, str, Optional[Dict[str, str]]) -> None version = Version.parse(version) if name not in self._packages: self._packages[name] = {} # if already added without deps, assume now called with discovered deps and overwrite if version in self._packages[name] and not ( deps is None or self._packages[name][version] is None ): raise ValueError("{} ({}) already exists".format(name, version)) # not existing and deps undiscovered if deps is None: self._packages[name][version] = None return dependencies = [] for dep in deps: req = parse_req(dep) constraint = ",".join(["".join(tup) for tup in req.specs]) dependencies.append(Dependency(req.key, constraint, req.__str__())) self._packages[name][version] = dependencies
def _versions_for( self, package, constraint=None ): # type: (Hashable, Any) -> List[Hashable] """Search for the specifications that match the given constraint. Called by BasePackageSource.versions_for """ extras = package.req.extras version_specifier = str(constraint).replace("||", "|").replace(" ", "") if version_specifier and version_specifier[0].isdigit(): version_specifier = "==" + version_specifier req = parse_req(str(package) + version_specifier, extras) if package not in self._packages or extras not in self._packages[package]: self.discover_and_add(req.__str__()) if package not in self._packages: return [] versions = [] for version in self._packages[package][extras].keys(): if not constraint or constraint.allows_any( Range(version, version, True, True) ): versions.append(version) return sorted(versions, reverse=True)
def discover_and_add(self, package): # type: (str, str) -> None # converting from semver constraint to pkg_resources string req = parse_req(package) to_create = discover_dependencies_and_versions( package, self.index_url, self.extra_index_url, self.cache_dir, self.pre ) for version in to_create["available"]: self.add(req.key, version) self.add( req.key, to_create["version"], deps=to_create["requires"], ) if req.key not in self._packages_metadata: self._packages_metadata[req.key] = {} self._packages_metadata[req.key][to_create["version"]] = { "pip_string": req.__str__(), "requires": to_create["requires"], "available": to_create["available"], }
def intersect(self, other): # type: (Term) -> Term """ Returns a Term that represents the packages allowed by both this term and another """ if self.package != other.package: raise ValueError("{} should refer to {}".format( other, self.package)) if self.is_compatible_with(other): if self.is_positive() != other.is_positive(): # foo ^1.0.0 ∩ not foo ^1.5.0 → foo >=1.0.0 <1.5.0 positive = self if self.is_positive() else other negative = other if self.is_positive() else self to_return = self._non_empty_term( positive.constraint.difference(negative.constraint), True) elif self.is_positive(): # foo ^1.0.0 ∩ foo >=1.5.0 <3.0.0 → foo ^1.5.0 to_return = self._non_empty_term( self.constraint.intersect(other.constraint), True) else: # not foo ^1.0.0 ∩ not foo >=1.5.0 <3.0.0 → not foo >=1.0.0 <3.0.0 to_return = self._non_empty_term( self.constraint.union(other.constraint), False) if to_return is not None: to_return._constraint._package._req = parse_req( to_return.constraint.package.req.__str__(), extras=self.constraint.package.req.extras | other.constraint.package.req.extras, ) to_return._package = self.constraint.package elif self.is_positive() != other.is_positive(): to_return = self if self.is_positive() else other else: to_return = Term(Constraint(self.package, EmptyRange())) return to_return
def root_dep(self, package): # type: (str, str) -> None req = parse_req(package) constraint = ",".join(["".join(tup) for tup in req.specs]) self._root_dependencies.append(Dependency(req.key, constraint, req.__str__())) self.discover_and_add(req.__str__())