Skip to content

[Versioning] Better usage of pyproject.toml #3089

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
38 changes: 30 additions & 8 deletions .github/workflows/nightly_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,21 @@ jobs:
run: |
export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
python3 -mpip install --pre torch --index-url https://download.pytorch.org/whl/nightly/${{ matrix.cuda_support[1] }}
- name: Prepare nightly build
env:
TORCHRL_NIGHTLY: 1
run: |
export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
python3 packaging/prepare_nightly_build.py
- name: Build TorchRL Nightly
env:
TORCHRL_NIGHTLY: 1
run: |
rm -r dist || true
export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
python3 -mpip install wheel
python3 setup.py bdist_wheel \
--package_name torchrl-nightly \
--python-tag=${{ matrix.python-tag }}
find dist -name '*whl' -exec bash -c ' mv $0 ${0/linux/manylinux1}' {} \;
python3 setup.py bdist_wheel
find dist -name '*whl' -exec bash -c ' mv $0 ${0/linux/manylinux1}' {} \;
# pytorch/pytorch binaries are also manylinux_2_17 compliant but they
# pretend that they're manylinux1 compliant so we do the same.
- name: Upload wheel for the test-wheel job
Expand Down Expand Up @@ -141,6 +147,11 @@ jobs:
rm -rf torchrl/
export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
python3 -c "import torchrl; print(torchrl.__version__)"
- name: Verify nightly version format
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
run: |
export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
python3 scripts/verify_nightly_version.py
- name: Run tests
run: |
set -e
Expand Down Expand Up @@ -213,7 +224,7 @@ jobs:
]
steps:
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version[1] }}
- name: Checkout torchrl
Expand All @@ -222,14 +233,20 @@ jobs:
shell: bash
run: |
python3 -mpip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu -U
- name: Prepare nightly build
env:
TORCHRL_NIGHTLY: 1
shell: bash
run: |
python3 packaging/prepare_nightly_build.py
- name: Build TorchRL nightly
env:
TORCHRL_NIGHTLY: 1
shell: bash
run: |
rm -r dist || true
python3 -mpip install wheel
python3 setup.py bdist_wheel \
--package_name torchrl-nightly \
--python-tag=${{ matrix.python-tag }}
python3 setup.py bdist_wheel
- name: Upload wheel for the test-wheel job
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -297,6 +314,11 @@ jobs:
# Avoid ambiguity of "import torchrl" by deleting the source files.
rm -rf torchrl/
python3 -c "import torchrl; print(torchrl.__version__)"
- name: Verify nightly version format
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
shell: bash
run: |
python3 scripts/verify_nightly_version.py
- name: Run tests
shell: bash
run: |
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include torchrl/version.py
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,8 @@ such as `apt`, `apt-get`, `conda` or `yum` but NOT `pip`, as well as `pip instal

One can also build the wheels to distribute to co-workers using
```bash
python setup.py bdist_wheel
pip install build
python -m build --wheel
```
Your wheels will be stored there `./dist/torchrl<name>.whl` and installable via
```bash
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/test_compressed_storage_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

import pytest
import torch

try:
from safetensors.torch import save
except ImportError:
save = None

from torchrl.data import CompressedListStorage


class TestCompressedStorageBenchmark:
Expand Down Expand Up @@ -142,4 +142,4 @@ def serialize_with_torch(data: torch.Tensor) -> bytes:
data = self.make_compressible_mock_data(1).get("observations")

# Run the actual benchmark
benchmark(serialize_fn, data)
benchmark(serialize_fn, data)
7 changes: 3 additions & 4 deletions packaging/build_wheels.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
export BUILD_TYPE=wheel
setup_env
setup_wheel_python
pip_install numpy pyyaml future ninja "pybind11[global]"
pip_install numpy pyyaml future ninja "pybind11[global]" build
pip_install --upgrade setuptools
setup_pip_pytorch_version
python setup.py clean

# Copy binaries to be included in the wheel distribution
if [[ "$(uname)" == Darwin || "$OSTYPE" == "msys" ]]; then
Expand All @@ -29,9 +28,9 @@ else
fi

if [[ "$OSTYPE" == "msys" ]]; then
IS_WHEEL=1 "$script_dir/windows/internal/vc_env_helper.bat" python setup.py bdist_wheel
IS_WHEEL=1 "$script_dir/windows/internal/vc_env_helper.bat" python -m build --wheel
else
python setup.py bdist_wheel
python -m build --wheel
if [[ "$(uname)" != Darwin ]]; then
rename "linux_x86_64" "manylinux1_x86_64" dist/*.whl
fi
Expand Down
38 changes: 38 additions & 0 deletions packaging/prepare_nightly_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
import os
from pathlib import Path


def prepare_nightly_build():
"""Prepare pyproject.toml for nightly builds by modifying dependencies."""
is_nightly = os.getenv("TORCHRL_NIGHTLY") == "1"

if not is_nightly:
print("Not a nightly build, skipping pyproject.toml modification")
return

pyproject_path = Path("pyproject.toml")
if not pyproject_path.exists():
print("pyproject.toml not found")
return

# Read the current pyproject.toml
with open(pyproject_path) as f:
content = f.read()

# Replace tensordict dependency with tensordict-nightly
if "tensordict>=0.9.0,<0.10.0" in content:
content = content.replace("tensordict>=0.9.0,<0.10.0", "tensordict-nightly")
print("✓ Replaced tensordict with tensordict-nightly in pyproject.toml")
else:
print("⚠ tensordict dependency not found in pyproject.toml")

# Write the modified content back
with open(pyproject_path, "w") as f:
f.write(content)

print("✓ pyproject.toml prepared for nightly build")


if __name__ == "__main__":
prepare_nightly_build()
66 changes: 66 additions & 0 deletions packaging/verify_nightly_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
import re
import sys
from datetime import date

# Try to import torchrl with better error handling
try:
import torchrl

print(f"Successfully imported torchrl from: {torchrl.__file__}")
except ImportError as e:
print(f"Failed to import torchrl: {e}")
sys.exit(1)

# Check if __version__ attribute exists
if not hasattr(torchrl, "__version__"):
print(
f'Available attributes in torchrl: {[attr for attr in dir(torchrl) if not attr.startswith("_")]}'
)
raise AttributeError("torchrl module has no __version__ attribute")

version = torchrl.__version__
print(f"Checking version: {version}")

# Check that version is not the major version (0.9.0)
if re.match(r"^\d+\.\d+\.\d+$", version):
raise ValueError(f"Version should not be the major version: {version}")

# Check that version matches date format (YYYY.M.D)
date_pattern = r"^\d{4}\.\d{1,2}\.\d{1,2}$"
if not re.match(date_pattern, version):
raise ValueError(f"Version should match date format YYYY.M.D, got: {version}")

# Verify it's today's date
today = date.today()
expected_version = f"{today.year}.{today.month}.{today.day}"
if version != expected_version:
raise ValueError(f"Version should be today date {expected_version}, got: {version}")

print(f"✓ Version {version} is correctly formatted as nightly date")

# Check that tensordict-nightly is installed (not stable tensordict)
try:
import tensordict

# Check if it's the nightly version by looking at the version
tensordict_version = tensordict.__version__
print(f"Checking tensordict version: {tensordict_version}")

# Check if it's a nightly version (either date format or contains 'd' followed by date)
if re.match(date_pattern, tensordict_version) or "d2025" in tensordict_version:
print(f"✓ tensordict version {tensordict_version} appears to be nightly")
else:
# Check if it's a stable version that should not be used in nightly builds
if tensordict_version.startswith("0.9."):
raise ValueError(
f"tensordict should be nightly, not stable version: {tensordict_version}"
)
print(
f"⚠ tensordict version {tensordict_version} - please verify this is nightly"
)

except ImportError:
raise ValueError(
"tensordict is not installed - nightly builds should include tensordict-nightly"
)
116 changes: 113 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,115 @@
[tool.usort]
first_party_detection = false

[build-system]
requires = ["setuptools", "wheel", "torch", "ninja"]
build-backend = "setuptools.build_meta"

[project]
name = "torchrl" # This will be overridden by setup.py for nightly builds
dynamic = ["version"]
description = "A modular, primitive-first, python-first PyTorch library for Reinforcement Learning"
readme = "README.md"

authors = [
{name = "torchrl contributors", email = "vmoens@fb.com"}
]
maintainers = [
{name = "torchrl contributors", email = "vmoens@fb.com"}
]
keywords = ["reinforcement-learning", "pytorch", "rl", "machine-learning"]
classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Operating System :: OS Independent",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
requires-python = ">=3.9"
dependencies = [
"torch>=2.1.0",
"numpy",
"packaging",
"cloudpickle",
"tensordict>=0.9.0,<0.10.0",
]

[project.optional-dependencies]
atari = ["gymnasium[atari]"]
dm_control = ["dm_control"]
replay_buffer = ["torch>=2.7.0"]
gym_continuous = ["gymnasium<1.0", "mujoco"]
rendering = ["moviepy<2.0.0"]
tests = [
"pytest",
"pyyaml",
"pytest-instafail",
"scipy",
"pytest-mock",
"pytest-cov",
"pytest-asyncio",
"pytest-benchmark",
"pytest-rerunfailures",
"pytest-error-for-skips",
]
utils = [
"tensorboard",
"wandb",
"tqdm",
"hydra-core>=1.1",
"hydra-submitit-launcher",
]
checkpointing = ["torchsnapshot"]
offline-data = [
"huggingface_hub",
"minari",
"requests",
"tqdm",
"torchvision",
"scikit-learn",
"pandas",
"h5py",
"pillow",
]
marl = ["vmas>=1.2.10", "pettingzoo>=1.24.1", "dm-meltingpot"]
open_spiel = ["open_spiel>=1.5"]
llm = [
"transformers",
"vllm",
"playwright",
"datasets",
"langdetect",
"nltk",
"immutabledict",
"accelerate",
"sentencepiece",
"protobuf",
"einops",
"safetensors",
]

[project.urls]
Homepage = "https://github.com/pytorch/rl"
Documentation = "https://pytorch.org/rl"
Repository = "https://github.com/pytorch/rl"
"Bug Tracker" = "https://github.com/pytorch/rl/issues"

[tool.setuptools.dynamic]
version = {file = "version.txt"}

[tool.setuptools.packages.find]
exclude = [
"test*",
"tutorials*",
"docs*",
"examples*",
"knowledge_base*",
"packaging*",
]

[tool.setuptools.package-data]
"*" = ["*.txt", "*.md"]

[tool.usort]
first_party_detection = false
Loading
Loading