Skip to content

Add pylock parser and validator #13369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
378fa93
Add pylock parser and validator
sbidoul May 1, 2025
910cee3
pylock: use Version type instead of str
sbidoul May 1, 2025
0d32f8b
pylock: support package.marker
sbidoul May 1, 2025
72936fe
pylock: support requires-python
sbidoul May 1, 2025
bbf16bc
pylock: parse environments
sbidoul May 1, 2025
dd6b915
pylock: parse package size
sbidoul May 1, 2025
2d0fa1d
pylock: refine validation of package sources
sbidoul May 1, 2025
1fe4d40
pylock: packages list is requried
sbidoul May 1, 2025
561ecbe
pylock: remove unused argument
sbidoul May 2, 2025
938c150
pylock: improve getters
sbidoul May 2, 2025
9778ac7
pylock: test file name validator
sbidoul May 2, 2025
fbc7a98
pylock: don't import typing_extensions at runtime
sbidoul May 2, 2025
e91e8ba
pylock: type-fu
sbidoul May 3, 2025
f40e1f8
pylock: refine and test some validation erros
sbidoul May 3, 2025
d1ade91
pylock: refactor
sbidoul May 3, 2025
f51ba7e
pylock: remove unused attribute
sbidoul May 3, 2025
a1a962e
pylock: factor out _get_list
sbidoul May 3, 2025
f3400ab
pylock: read extras, dependency_groups, default_groups
sbidoul May 3, 2025
ce4a2dd
pylock: read tool sections
sbidoul May 3, 2025
71e1738
pylock: read upload_time
sbidoul May 3, 2025
424e574
pylock: read dependencies field
sbidoul May 3, 2025
c291de2
pylock: read attestation-identities field
sbidoul May 3, 2025
75b0e1c
pylock: move toml export function to utils
sbidoul May 3, 2025
679b559
pylock: read index field
sbidoul May 3, 2025
367d558
pylock: validate hashes
sbidoul May 3, 2025
0bf4617
pylock: factorize path/url validation
sbidoul May 3, 2025
4598342
pylock: declare exported names
sbidoul May 3, 2025
a648002
pylock: rename is_valid_pylock_file_name
sbidoul May 3, 2025
ad033f7
pylock: tune dataclasses
sbidoul May 3, 2025
92b3b88
pylock: handwoven constructors
sbidoul May 3, 2025
11ad4c1
pylock: add is_direct property
sbidoul May 3, 2025
d5bc7c7
pylock: use abstract classes
sbidoul May 4, 2025
a895ec2
pylock: sdist/wheel name is optional
sbidoul May 4, 2025
11143fd
pylock: validate package name normalization
sbidoul May 4, 2025
9114668
pylock: preserve distinction between absent and empty extras and depd…
sbidoul May 4, 2025
669e28f
pylock: algorithms_guaranteed is a SHOULD
sbidoul May 4, 2025
c3eceab
pylock: new style type annotations
sbidoul May 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/pip/_internal/commands/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
with_cleanup,
)
from pip._internal.cli.status_codes import SUCCESS
from pip._internal.models.pylock import Pylock, is_valid_pylock_file_name
from pip._internal.models.pylock import is_valid_pylock_path
from pip._internal.operations.build.build_tracker import get_build_tracker
from pip._internal.req.req_install import (
check_legacy_setup_py_options,
Expand All @@ -18,6 +18,7 @@
from pip._internal.utils.misc import (
get_pip_version,
)
from pip._internal.utils.pylock import pylock_from_install_requirements, pylock_to_toml
from pip._internal.utils.temp_dir import TempDirectory

logger = getLogger(__name__)
Expand Down Expand Up @@ -153,15 +154,16 @@ def run(self, options: Values, args: list[str]) -> int:
base_dir = Path.cwd()
else:
output_file_path = Path(options.output_file)
if not is_valid_pylock_file_name(output_file_path):
if not is_valid_pylock_path(output_file_path):
logger.warning(
"%s is not a valid lock file name.",
output_file_path,
)
base_dir = output_file_path.parent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m thinking, in many situations it might not actually be desirable to use a relative path. Not sure if there’s a good way to tell which way the user wants each package to be. Since outputting to stdout always generates an absolute path, maybe it’s less confusing if absolute path is the default when you output to a file too, and you need to somehow tell pip to use a relative path explicitly. Something similar to how we have --only-binary for install? I don’t know.

Copy link
Member Author

@sbidoul sbidoul May 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure either. I'd say relative paths below the pylock.toml location is a good default. And it gives a nice result for the common pip lock -e ..

Anyway, I'm going to remove this change from this PR and handle that separately.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel as though when you generate a pylock file, it makes sense for the paths to be relative to the location of the file. But when you generate to stdout (which has no location), it makes sense for paths to be absolute. As you say, though, maybe we don't want relative paths that go up in the filesystem hierarchy.

I'd go with:

  1. When writing to stdout, absolute.
  2. When writing to pylock, if the target is alongside (or below) the lockfile, then relative, ohterwise absolute.

But it's debatable enough that I think doing it as a separate PR is sensible.

pylock_toml = Pylock.from_install_requirements(
pylock = pylock_from_install_requirements(
requirement_set.requirements.values(), base_dir=base_dir
).as_toml()
)
pylock_toml = pylock_to_toml(pylock)
if options.output_file == "-":
sys.stdout.write(pylock_toml)
else:
Expand Down
Loading