Skip to content

Commit

Permalink
Use pip_requirements_parser
Browse files Browse the repository at this point in the history
  • Loading branch information
sbidoul committed May 28, 2023
1 parent bf90ef0 commit c730299
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ repos:
- id: mypy
args: ["--strict"]
exclude: '^(docs|tasks|tests)|setup\.py'
additional_dependencies: ["httpx", "packaging", "typer>=0.3.2"]
additional_dependencies: ["packaging", "typer>=0.3.2"]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.0.270
Expand Down
2 changes: 2 additions & 0 deletions news/107.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Use `pip-requirements-parser <https://pypi.org/project/pip-requirements-parser/>`_
instead of our own copy of pip's parser.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ classifiers = [
]
requires-python = ">=3.7"
dependencies=[
"httpx",
"packaging>=23",
"pip-requirements-parser",
"tomli ; python_version<'3.11'",
"typer[all]>=0.3.2",
"typing-extensions ; python_version<'3.8'", # for Protocol, TypedDict
Expand Down
22 changes: 9 additions & 13 deletions src/pip_deepfreeze/pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from packaging.utils import NormalizedName
from packaging.version import Version
from pip_requirements_parser import RequirementsFile # type: ignore[import]

from .compat import TypedDict, shlex_join
from .installed_dist import (
Expand All @@ -17,11 +18,6 @@
list_installed_depends_by_extra,
)
from .project_name import get_project_name
from .req_file_parser import (
NestedRequirementsLine,
RequirementLine,
parse as parse_req_file,
)
from .req_parser import get_req_name
from .sanity import get_pip_version
from .utils import (
Expand Down Expand Up @@ -73,14 +69,14 @@ def pip_upgrade_project(
"""
# 1. parse constraints
constraint_reqs = {}
for req_line in parse_req_file(
str(constraints_filename), recurse=False, reqs_only=False
):
assert not isinstance(req_line, NestedRequirementsLine)
if isinstance(req_line, RequirementLine):
req_name = get_req_name(req_line.requirement)
assert req_name # XXX user error instead?
constraint_reqs[req_name] = normalize_req_line(req_line.requirement)
parsed_constraints_file = RequirementsFile.from_file(
str(constraints_filename), include_nested=False
)
for constraint_req in parsed_constraints_file.requirements:
assert constraint_req.name # XXX user error instead?
constraint_reqs[constraint_req.name] = normalize_req_line(
constraint_req.requirement_line.line
)
# 2. get installed frozen dependencies of project
installed_reqs = {
get_req_name(req_line): normalize_req_line(req_line)
Expand Down
43 changes: 19 additions & 24 deletions src/pip_deepfreeze/req_merge.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from pathlib import Path
from typing import Iterable, Iterator, Optional

import httpx
from packaging.utils import canonicalize_name
from pip_requirements_parser import RequirementsFile # type: ignore[import]

from .compat import shlex_join
from .req_file_parser import OptionsLine, RequirementLine, parse
from .req_parser import get_req_name
from .utils import log_error

Expand All @@ -28,38 +27,34 @@ def prepare_frozen_reqs_for_upgrade(
frozen_reqs = set()
# 1. emit options from in_filename, collect in_reqs
if in_filename.is_file():
for in_req in parse(
str(in_filename),
recurse=True,
reqs_only=False,
strict=True,
session=httpx.Client(),
):
if isinstance(in_req, OptionsLine):
yield shlex_join(in_req.options)
elif isinstance(in_req, RequirementLine):
req_name = get_req_name(in_req.requirement)
if not req_name:
log_error(f"Ignoring unnamed constraint {in_req.raw_line!r}.")
continue
in_reqs.append((req_name, in_req.requirement))
in_req_file = RequirementsFile.from_file(str(in_filename), include_nested=True)
for in_req_option in in_req_file.options:
yield shlex_join(in_req_option.options)
for in_req in in_req_file.requirements:
req_name = get_req_name(in_req.requirement_line.line)
if not req_name:
log_error(
f"Ignoring unnamed constraint {in_req.requirement_line.line!r}."
)
continue
in_reqs.append((req_name, in_req.requirement))
# 2. emit frozen_reqs unless upgrade_all or it is in to_upgrade
for frozen_filename in frozen_filenames:
if frozen_filename.is_file() and not upgrade_all:
for frozen_req in parse(
str(frozen_filename), recurse=True, reqs_only=True, strict=True
):
assert isinstance(frozen_req, RequirementLine)
req_name = get_req_name(frozen_req.requirement)
for frozen_req in RequirementsFile.from_file(
str(frozen_filename), include_nested=True
).requirements:
req_name = get_req_name(frozen_req.requirement_line.line)
if not req_name:
log_error(
f"Ignoring unnamed frozen requirement {frozen_req.raw_line!r}."
f"Ignoring unnamed frozen requirement "
f"{frozen_req.requirement_line.line!r}."
)
continue
if req_name in to_upgrade_set:
continue
frozen_reqs.add(req_name)
yield frozen_req.requirement
yield frozen_req.requirement_line.line
# 3. emit in_reqs that have not been emitted as frozen reqs
for req_name, in_req_str in in_reqs:
if req_name not in frozen_reqs:
Expand Down
16 changes: 5 additions & 11 deletions src/pip_deepfreeze/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
from pathlib import Path
from typing import Iterator, List, Optional, Sequence

import httpx
import typer
from packaging.utils import NormalizedName
from pip_requirements_parser import RequirementsFile # type: ignore[import]

from .pip import pip_freeze_dependencies_by_extra, pip_uninstall, pip_upgrade_project
from .project_name import get_project_name
from .req_file_parser import OptionsLine, parse as parse_req_file
from .req_merge import prepare_frozen_reqs_for_upgrade
from .req_parser import get_req_names
from .utils import (
Expand Down Expand Up @@ -84,15 +83,10 @@ def sync(
# output pip options in main requirements only
if not extra and requirements_in.exists():
# XXX can we avoid this second parse of requirements.txt.in?
for parsed_req_line in parse_req_file(
str(requirements_in),
reqs_only=False,
recurse=True,
strict=True,
session=httpx.Client(),
):
if isinstance(parsed_req_line, OptionsLine):
print(parsed_req_line.raw_line, file=f)
for option_line in RequirementsFile.from_file(
str(requirements_in), include_nested=True
).options:
print(option_line.requirement_line.line, file=f)
# output frozen dependencies of project
for req_line in frozen_reqs:
print(req_line, file=f)
Expand Down

0 comments on commit c730299

Please sign in to comment.