Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ test = "pytest -vvs"

[pipenv]
allow_prereleases = true
use_pylock = true
6 changes: 5 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ credentials
shell
docker
scripts
pylock
advanced
diagnose
changelog
Expand Down
169 changes: 169 additions & 0 deletions docs/pylock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# PEP 751 pylock.toml Support

Pipenv supports [PEP 751](https://peps.python.org/pep-0751/) pylock.toml files, which provide a standardized format for recording Python dependencies to enable installation reproducibility.

## What is pylock.toml?

The pylock.toml file is a standardized lock file format introduced in PEP 751. It is designed to be:

- Human-readable and machine-generated
- Secure by default (includes file hashes)
- Able to support both single-use and multi-use lock files
- Compatible across different Python packaging tools

## Using pylock.toml with Pipenv

Pipenv can automatically detect and use pylock.toml files in your project. When both a Pipfile.lock and a pylock.toml file exist, Pipenv will prioritize the pylock.toml file.

### Reading pylock.toml Files

When you run commands like `pipenv install` or `pipenv sync`, Pipenv will check for a pylock.toml file in your project directory. If found, it will use the dependencies specified in the pylock.toml file instead of Pipfile.lock.

Pipenv looks for pylock.toml files in the following order:
1. A file named `pylock.toml` in the project directory
2. A file matching the pattern `pylock.*.toml` in the project directory

### Example pylock.toml File

Here's a simplified example of a pylock.toml file:

```toml
lock-version = '1.0'
environments = ["sys_platform == 'win32'", "sys_platform == 'linux'", "sys_platform == 'darwin'"]
requires-python = '>=3.8'
extras = []
dependency-groups = ['dev']
default-groups = ['default']
created-by = 'pipenv'

[[packages]]
name = 'requests'
version = '2.28.1'
requires-python = '>=3.7'
index = 'https://pypi.org/simple/'

[[packages.wheels]]
name = 'requests-2.28.1-py3-none-any.whl'
upload-time = '2022-07-13T14:00:00Z'
url = 'https://files.pythonhosted.org/packages/ca/91/6d9b8ccacd0412c08820f72cebaa4f0c61441f4AE7b7338a82051330d70/requests-2.28.1-py3-none-any.whl'
size = 61805
hashes = {sha256 = 'b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7'}

[[packages]]
name = 'pytest'
version = '7.0.0'
marker = "'dev' in dependency_groups"
index = 'https://pypi.org/simple/'
```

## Benefits of Using pylock.toml

- **Standardization**: pylock.toml is a standardized format that can be used by multiple Python packaging tools.
- **Security**: pylock.toml includes file hashes by default, making it more secure against supply chain attacks.
- **Flexibility**: pylock.toml supports extras and dependency groups for multi-use lock files.
- **Interoperability**: pylock.toml can be used by different tools, reducing vendor lock-in.
- **Auditability**: Packages include their index URL for SBOM generation.

## Writing pylock.toml Files

Pipenv can generate pylock.toml files alongside Pipfile.lock files. To enable this feature, add the following to your Pipfile:

```toml
[pipenv]
use_pylock = true
```

With this setting, whenever Pipenv updates the Pipfile.lock file (e.g., when running `pipenv lock`), it will also generate a pylock.toml file in the same directory.

You can also specify a custom name for the pylock.toml file:

```toml
[pipenv]
use_pylock = true
pylock_name = "dev" # This will generate pylock.dev.toml
```

## CLI Commands

Pipenv provides a `pylock` command for managing pylock.toml files:

### Generate pylock.toml from Pipfile.lock

```bash
pipenv pylock --generate
```

### Generate pylock.toml from pyproject.toml

Create a pylock.toml skeleton from your pyproject.toml dependencies (PEP 621/735):

```bash
pipenv pylock --from-pyproject
```

**Note:** This creates a skeleton file with declared dependencies. Package versions and hashes need to be resolved by running `pipenv lock`.

### Validate pylock.toml

```bash
pipenv pylock --validate
```

### Custom Output Path

```bash
pipenv pylock --generate --output /path/to/pylock.toml
```

### Custom Dependency Groups

Specify which dependency groups should be used for develop packages:

```bash
pipenv pylock --generate --dev-groups "dev,test,docs"
```

## pyproject.toml Support

Pipenv can read dependencies from `pyproject.toml` files following PEP 621 and PEP 735:

- `[project.dependencies]` - Main project dependencies
- `[project.optional-dependencies]` - Optional dependencies (extras)
- `[dependency-groups]` - Dependency groups (PEP 735)

This allows you to use `pyproject.toml` as your primary dependency specification while generating standardized pylock.toml files.

## Marker Evaluation

Pipenv supports PEP 751 marker syntax for extras and dependency groups:

- `'name' in extras` - Include package when extra is enabled
- `'name' in dependency_groups` - Include package when dependency group is enabled

Example:

```toml
[[packages]]
name = 'pytest'
version = '7.0.0'
marker = "'dev' in dependency_groups"
```

## Features

### Implemented

- ✅ Core pylock.toml format (read/write)
- ✅ Bidirectional conversion with Pipfile.lock
- ✅ Package index tracking (`packages.index`)
- ✅ Extras and dependency groups
- ✅ Marker evaluation for filtering packages
- ✅ CLI commands for generation and validation
- ✅ pyproject.toml dependency reading

### Future Enhancements

- VCS package support (`packages.vcs`)
- Local directory support (`packages.directory`)
- Direct archive support (`packages.archive`)
- Attestation identities support
21 changes: 21 additions & 0 deletions examples/Pipfile.with_pylock
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
requests = "*"

[dev-packages]
pytest = "*"

[requires]
python_version = "3.8"

[pipenv]
# Enable pylock.toml generation
use_pylock = true

# Optional: Specify a custom name for the pylock file
# This will generate pylock.dev.toml instead of pylock.toml
# pylock_name = "dev"
83 changes: 83 additions & 0 deletions examples/pylock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Example pylock.toml file for PEP 751
# This demonstrates the pylock.toml format supported by Pipenv

lock-version = '1.0'
environments = ["sys_platform == 'win32'", "sys_platform == 'linux'", "sys_platform == 'darwin'"]
requires-python = '>=3.8'
extras = ['crypto']
dependency-groups = ['dev', 'test']
default-groups = ['default']
created-by = 'pipenv'

# Main dependencies (always installed)
[[packages]]
name = 'requests'
version = '2.28.1'
requires-python = '>=3.7'
index = 'https://pypi.org/simple/'

[[packages.wheels]]
name = 'requests-2.28.1-py3-none-any.whl'
upload-time = '2022-07-13T14:00:00Z'
url = 'https://files.pythonhosted.org/packages/ca/91/6d9b8ccacd0412c08820f72cebaa4f0c61441f4AE7b7338a82051330d70/requests-2.28.1-py3-none-any.whl'
size = 61805
hashes = {sha256 = 'b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7'}

[[packages]]
name = 'urllib3'
version = '1.26.12'
requires-python = '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4'
index = 'https://pypi.org/simple/'

[[packages.wheels]]
name = 'urllib3-1.26.12-py2.py3-none-any.whl'
upload-time = '2022-09-08T14:30:00Z'
url = 'https://files.pythonhosted.org/packages/6f/de/5be2e3eed8426f871b170663333a0f627fc2924cc386cd41a2d2d3f1699/urllib3-1.26.12-py2.py3-none-any.whl'
size = 141862
hashes = {sha256 = 'b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997'}

[[packages]]
name = 'certifi'
version = '2022.9.24'
index = 'https://pypi.org/simple/'

[[packages.wheels]]
name = 'certifi-2022.9.24-py3-none-any.whl'
upload-time = '2022-09-24T18:00:00Z'
url = 'https://files.pythonhosted.org/packages/1d/38/fa96a426e0c0e68aabc68e896584b83ad1eec779265a028e156ce509630/certifi-2022.9.24-py3-none-any.whl'
size = 161915
hashes = {sha256 = '0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14'}

# Development dependency (only when 'dev' group is enabled)
[[packages]]
name = 'pytest'
version = '7.2.0'
requires-python = '>=3.7'
marker = "'dev' in dependency_groups or 'test' in dependency_groups"
index = 'https://pypi.org/simple/'

[[packages.wheels]]
name = 'pytest-7.2.0-py3-none-any.whl'
upload-time = '2022-11-12T10:00:00Z'
url = 'https://files.pythonhosted.org/packages/ab/cd/pytest-7.2.0-py3-none-any.whl'
size = 312500
hashes = {sha256 = '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'}

# Optional dependency for 'crypto' extra
[[packages]]
name = 'cryptography'
version = '40.0.0'
requires-python = '>=3.7'
marker = "'crypto' in extras"
index = 'https://pypi.org/simple/'

[[packages.wheels]]
name = 'cryptography-40.0.0-py3-none-any.whl'
upload-time = '2023-03-20T08:00:00Z'
url = 'https://files.pythonhosted.org/packages/ef/gh/cryptography-40.0.0-py3-none-any.whl'
size = 654321
hashes = {sha256 = 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890'}

[tool.pipenv]
generated_from = "Pipfile.lock"
generation_date = "2025-04-25T04:20:00Z"
5 changes: 5 additions & 0 deletions news/6391.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Added support for PEP 751 pylock.toml files:

- Reading: When both a Pipfile.lock and a pylock.toml file exist, Pipenv will prioritize the pylock.toml file.
- Writing: Add ``use_pylock = true`` to the ``[pipenv]`` section of your Pipfile to generate pylock.toml files alongside Pipfile.lock.
- Customization: Use ``pylock_name = "name"`` in the ``[pipenv]`` section to generate named pylock files (e.g., pylock.name.toml).
Loading
Loading