def _convert_req(name: str, req_dict: RequirementDict) -> str: if not getattr(req_dict, "items", None): assert isinstance(req_dict, str) return Requirement.from_req_dict( name, _convert_specifier(req_dict)).as_line() assert isinstance(req_dict, dict) req_dict = dict(req_dict) req_dict.pop("optional", None) # Ignore the 'optional' key if "version" in req_dict: req_dict["version"] = _convert_specifier(str(req_dict["version"])) markers: list[Marker] = [] if "markers" in req_dict: markers.append(Marker(req_dict.pop("markers"))) # type: ignore if "python" in req_dict: markers.append( Marker( _convert_python(str( req_dict.pop("python"))).as_marker_string())) if markers: req_dict["marker"] = str(functools.reduce(operator.and_, markers)).replace('"', "'") if "rev" in req_dict or "branch" in req_dict or "tag" in req_dict: req_dict["ref"] = req_dict.pop( "rev", req_dict.pop("tag", req_dict.pop("branch", None)) # type: ignore ) return Requirement.from_req_dict(name, req_dict).as_line()
def convert_pipfile_requirement(req): markers = [] if "markers" in req: markers.append(Marker(req["markers"])) for key in MARKER_KEYS: if key in req: marker = Marker(f"{key}{req[key]}") markers.append(marker) del req[key] if markers: marker = functools.reduce(operator.and_, markers) req["marker"] = str(marker).replace('"', "'") return req
def convert_pipfile_requirement(name: str, req: RequirementDict) -> str: markers = [] if "markers" in req: markers.append(Marker(req["markers"])) for key in MARKER_KEYS: if key in req: marker = Marker(f"{key}{req[key]}") markers.append(marker) del req[key] if markers: marker = functools.reduce(operator.and_, markers) req["marker"] = str(marker).replace('"', "'") return Requirement.from_req_dict(name, req).as_line()
def get_requirements_from_dist(dist: EggInfoDistribution, extras: Sequence[str]) -> List[str]: """Get requirements of a distribution, with given extras.""" extras_in_metadata = [] result = [] dep_map = dist._build_dep_map() for extra, reqs in dep_map.items(): reqs = [Requirement.from_pkg_requirement(r) for r in reqs] if not extra: # requirements without extras are always required. result.extend(r.as_line() for r in reqs) else: new_extra, _, marker = extra.partition(":") extras_in_metadata.append(new_extra.strip()) # Only include requirements that match one of extras. if not new_extra.strip() or safe_extra( new_extra.strip()) in extras: marker = Marker(marker) if marker else None for r in reqs: r.marker = marker result.append(r.as_line()) extras_not_found = [e for e in extras if e not in extras_in_metadata] if extras_not_found: warnings.warn(ExtrasError(extras_not_found)) return result
def ireq_as_line(ireq): """Formats an `InstallRequirement` instance as a PEP 508 dependency string. Generic formatter for pretty printing InstallRequirements to the terminal in a less verbose way than using its `__str__` method. :param :class:`InstallRequirement` ireq: A pip **InstallRequirement** instance. :return: A formatted string for prettyprinting :rtype: str """ if ireq.editable: line = "-e {}".format(ireq.link) else: line = _requirement_to_str_lowercase_name(ireq.req) if str(ireq.req.marker) != str(ireq.markers): if not ireq.req.marker: line = "{}; {}".format(line, ireq.markers) else: name, markers = line.split(";", 1) markers = Marker(markers) & ireq.markers line = "{}; {}".format(name, markers) return line
def filter_requirements_with_extras( project_name: str, requirement_lines: list[str], extras: Sequence[str], include_default: bool = False, ) -> list[str]: """Filter the requirements with extras. If extras are given, return those with matching extra markers. Otherwise, return those without extra markers. """ result: list[str] = [] extras_in_meta: set[str] = set() for req in requirement_lines: _r = parse_requirement(req) if _r.marker: req_extras, rest = split_marker_extras(str(_r.marker)) if req_extras: extras_in_meta.update(req_extras) _r.marker = Marker(rest) if rest else None else: req_extras = set() if (req_extras and not req_extras.isdisjoint(extras) or not req_extras and (include_default or not extras)): result.append(_r.as_line()) extras_not_found = [e for e in extras if e not in extras_in_meta] if extras_not_found: warnings.warn(ExtrasWarning(project_name, extras_not_found)) return result
def filter_requirements_with_extras( requirement_lines: list[str | dict[str, str | list[str]]], extras: Sequence[str], ) -> list[str]: result: list[str] = [] extras_in_meta = [] for req in requirement_lines: if isinstance(req, dict): if req.get("extra"): extras_in_meta.append(req["extra"]) if not req.get("extra") or req.get("extra") in extras: marker = f"; {req['environment']}" if req.get( "environment") else "" result.extend(f"{line}{marker}" for line in req.get("requires", [])) else: _r = parse_requirement(req) if not _r.marker: result.append(req) else: elements, rest = split_marker_extras(_r.marker) extras_in_meta.extend(elements) _r.marker = Marker(str(rest)) if rest else None if not elements or set(extras) & set(elements): result.append(_r.as_line()) extras_not_found = [e for e in extras if e not in extras_in_meta] if extras_not_found: warnings.warn(ExtrasError(extras_not_found)) return result
def as_marker(self) -> Optional[Marker]: marker, pyspec = self.marker_no_python, self.requires_python py_marker = pyspec.as_marker_string() or None py_marker = Marker(py_marker) if py_marker else None try: return marker & py_marker except TypeError: return None
def _convert_req(req_dict): if not getattr(req_dict, "items", None): return _convert_specifier(req_dict) req_dict = dict(req_dict) if "version" in req_dict: req_dict["version"] = _convert_specifier(req_dict["version"]) markers = [] if "markers" in req_dict: markers.append(Marker(req_dict.pop("markers"))) if "python" in req_dict: markers.append( Marker(_convert_python(req_dict.pop("python")).as_marker_string())) if markers: req_dict["marker"] = str(functools.reduce(operator.and_, markers)).replace('"', "'") if "rev" in req_dict or "branch" in req_dict or "tag" in req_dict: req_dict["ref"] = req_dict.pop( "rev", req_dict.pop("tag", req_dict.pop("branch", None))) return req_dict
def requires_extra(self) -> Dict[str, List[str]]: if not self._extras: return {} result = {} for extra in self._extras: current = result[extra] = [] for r in self.project.get_dependencies(extra).values(): r.marker = Marker(f"extra == {extra!r}") & r.marker current.append(r.as_line()) return result
def requires(self) -> list[str] | None: result = self._data.install_requires for extra, reqs in self._data.extras_require.items(): extra_marker = f"extra == '{extra}'" for req in reqs: parsed = parse_requirement(req) old_marker = str(parsed.marker) if parsed.marker else None if old_marker: if " or " in old_marker: new_marker = f"({old_marker}) and {extra_marker}" else: new_marker = f"{old_marker} and {extra_marker}" else: new_marker = extra_marker parsed.marker = Marker(new_marker) result.append(parsed.as_line()) return result
def filter_requirements_with_extras( requirement_lines: list[str], extras: Sequence[str], ) -> list[str]: result: list[str] = [] extras_in_meta: list[str] = [] for req in requirement_lines: _r = parse_requirement(req) if not _r.marker: result.append(req) else: elements, rest = split_marker_extras(_r.marker) extras_in_meta.extend(elements) _r.marker = Marker(str(rest)) if rest else None if not elements or set(extras) & set(elements): result.append(_r.as_line()) extras_not_found = [e for e in extras if e not in extras_in_meta] if extras_not_found: warnings.warn(ExtrasError(extras_not_found)) return result
import pytest from pdm.models.markers import Marker @pytest.mark.parametrize( "expression,expected", [ (Marker('os_name=="nt"') & None, 'os_name == "nt"'), (None & Marker('os_name=="nt"'), 'os_name == "nt"'), ( Marker('os_name=="nt"') & Marker('python_version ~= "2.7"'), 'os_name == "nt" and python_version ~= "2.7"', ), ( Marker('os_name == "nt" and python_version ~= "2.7"') & Marker('sys_platform == "win32"'), 'os_name == "nt" and python_version ~= "2.7" and sys_platform == "win32"', ), ( Marker('os_name == "nt" or sys_platform == "win32"') & Marker('python_version ~= "2.7"'), '(os_name == "nt" or sys_platform == "win32") and python_version ~= "2.7"', ), (Marker('os_name == "nt"') | None, "None"), (None | Marker('os_name == "nt"'), "None"), ( Marker('os_name == "nt"') | Marker('python_version ~= "2.7"'), 'os_name == "nt" or python_version ~= "2.7"', ), (
def test_split_marker_extras(original, extras, rest): result = split_marker_extras(Marker(original)) assert result == (extras, Marker(rest) if rest else None)