From ed1cef2b0e03727906973972303ec07ab4c5ef37 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 12 Jan 2026 12:46:28 -0500 Subject: [PATCH 01/12] ci: add downstream testing Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 18 ++++++++++++++++++ noxfile.py | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5ab27ced5..5570929a7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,6 +50,24 @@ jobs: - name: Run nox run: pipx run nox -s tests --force-python=${{ matrix.python_version }} + downstream: + name: Downstream + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + + - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + name: Install Python 3.14 + with: + python-version: "3.14" + cache: "pip" + + - name: Run nox + run: pipx run nox -s downstream + pass: name: All pass if: always() diff --git a/noxfile.py b/noxfile.py index a8adfb513..be6ca1c4f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -76,6 +76,30 @@ def tests(session: nox.Session) -> None: ) +PROJECTS = {"packaging_legacy": "https://github.com/di/packaging_legacy.git"} + + +@nox.parametrize("project", list(PROJECTS)) +@nox.session(default=False) +def downstream(session: nox.Session, project: str) -> None: + session.install("-e.", "pip") + + tmp_dir = Path(session.create_tmp()) + session.chdir(tmp_dir) + + shutil.rmtree(project, ignore_errors=True) + session.run("git", "clone", PROJECTS[project], external=True) + session.chdir(project) + + if project == "packaging_legacy": + session.install("-r", "tests/requirements.txt") + session.install("-e.") + session.run("pip", "list") + session.run("pytest") + else: + session.error("Unknown package") + + @nox.session(python="3.10") def lint(session: nox.Session) -> None: """ From ee142a5882c7552c691ac08ccb2b7692ade38e26 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 15 Jan 2026 10:33:01 -0500 Subject: [PATCH 02/12] fix: use tarfile instead Signed-off-by: Henry Schreiner --- noxfile.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index be6ca1c4f..a6016542a 100644 --- a/noxfile.py +++ b/noxfile.py @@ -8,14 +8,17 @@ import datetime import difflib import glob +import io import os import re import shutil import subprocess import sys +import tarfile import tempfile import textwrap import time +import urllib.request from pathlib import Path from typing import IO, Generator @@ -76,7 +79,9 @@ def tests(session: nox.Session) -> None: ) -PROJECTS = {"packaging_legacy": "https://github.com/di/packaging_legacy.git"} +PROJECTS = { + "packaging_legacy": "https://github.com/di/packaging_legacy/archive/refs/tags/23.0.post0.tar.gz" +} @nox.parametrize("project", list(PROJECTS)) @@ -88,8 +93,12 @@ def downstream(session: nox.Session, project: str) -> None: session.chdir(tmp_dir) shutil.rmtree(project, ignore_errors=True) - session.run("git", "clone", PROJECTS[project], external=True) - session.chdir(project) + with urllib.request.urlopen(PROJECTS[project]) as resp: + data = resp.read() + with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as tf: + tf.extractall(project) + (inner_dir,) = Path(project).iterdir() + session.chdir(inner_dir) if project == "packaging_legacy": session.install("-r", "tests/requirements.txt") From fb74db40f62b424e36d912ae8b286de5a826b77c Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 15 Jan 2026 10:55:28 -0500 Subject: [PATCH 03/12] tests: add build to downstream testing Signed-off-by: Henry Schreiner --- noxfile.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index a6016542a..82375888f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -80,14 +80,15 @@ def tests(session: nox.Session) -> None: PROJECTS = { - "packaging_legacy": "https://github.com/di/packaging_legacy/archive/refs/tags/23.0.post0.tar.gz" + "packaging_legacy": "https://github.com/di/packaging_legacy/archive/refs/tags/23.0.post0.tar.gz", + "build": "https://github.com/pypa/build/archive/refs/tags/1.4.0.tar.gz", } @nox.parametrize("project", list(PROJECTS)) @nox.session(default=False) def downstream(session: nox.Session, project: str) -> None: - session.install("-e.", "pip") + session.install("-e.") tmp_dir = Path(session.create_tmp()) session.chdir(tmp_dir) @@ -100,10 +101,15 @@ def downstream(session: nox.Session, project: str) -> None: (inner_dir,) = Path(project).iterdir() session.chdir(inner_dir) + pip_cmd = ["uv", "pip"] if session.venv_backend == "uv" else ["pip"] + if project == "packaging_legacy": session.install("-r", "tests/requirements.txt") session.install("-e.") - session.run("pip", "list") + session.run(*pip_cmd, "list") + session.run("pytest") + elif project == "build": + session.install("-e.", "--group=test") session.run("pytest") else: session.error("Unknown package") From ab782f74f7867eaba9661380cc78d11d4eb188f8 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 15 Jan 2026 10:58:48 -0500 Subject: [PATCH 04/12] tests: add pyproject-metadata to downstream testing Signed-off-by: Henry Schreiner --- noxfile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 82375888f..370b9d25d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -82,6 +82,7 @@ def tests(session: nox.Session) -> None: PROJECTS = { "packaging_legacy": "https://github.com/di/packaging_legacy/archive/refs/tags/23.0.post0.tar.gz", "build": "https://github.com/pypa/build/archive/refs/tags/1.4.0.tar.gz", + "pyproject_metadata": "https://github.com/pypa/pyproject-metadata/archive/refs/tags/0.10.0.tar.gz", } @@ -108,8 +109,10 @@ def downstream(session: nox.Session, project: str) -> None: session.install("-e.") session.run(*pip_cmd, "list") session.run("pytest") - elif project == "build": + elif project in {"build", "pyproject_metadata"}: session.install("-e.", "--group=test") + if project != "build": + session.run(*pip_cmd, "list") session.run("pytest") else: session.error("Unknown package") From effb2473d9a9fe1f7cf2e8400ba5794fdbda66ac Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 15 Jan 2026 12:11:00 -0500 Subject: [PATCH 05/12] tests: fix strip force color Signed-off-by: Henry Schreiner --- noxfile.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index 370b9d25d..e5aa08d9e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -89,6 +89,7 @@ def tests(session: nox.Session) -> None: @nox.parametrize("project", list(PROJECTS)) @nox.session(default=False) def downstream(session: nox.Session, project: str) -> None: + env = {"FORCE_COLOR": None} session.install("-e.") tmp_dir = Path(session.create_tmp()) @@ -108,12 +109,12 @@ def downstream(session: nox.Session, project: str) -> None: session.install("-r", "tests/requirements.txt") session.install("-e.") session.run(*pip_cmd, "list") - session.run("pytest") + session.run("pytest", env=env) elif project in {"build", "pyproject_metadata"}: session.install("-e.", "--group=test") if project != "build": session.run(*pip_cmd, "list") - session.run("pytest") + session.run("pytest", env=env) else: session.error("Unknown package") From a580acf6a17a101614e8514d9487ab6cfde96d6a Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 15 Jan 2026 12:18:36 -0500 Subject: [PATCH 06/12] ci: split up downstream projects Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5570929a7..c2788bdb1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -53,6 +53,10 @@ jobs: downstream: name: Downstream runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + project: [packaging_legacy, build, pyproject_metadata] steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 @@ -66,7 +70,7 @@ jobs: cache: "pip" - name: Run nox - run: pipx run nox -s downstream + run: pipx run nox -s 'downstream(project="${{ matrix.project }}")' pass: name: All pass From a804c129641885b966a06788544ebacb0e56f63f Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 21 Jan 2026 14:23:44 -0500 Subject: [PATCH 07/12] chore: add setuptools Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 4 ++-- noxfile.py | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c2788bdb1..62212688e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,12 +51,12 @@ jobs: run: pipx run nox -s tests --force-python=${{ matrix.python_version }} downstream: - name: Downstream + name: Downstream ${{ matrix.project }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: - project: [packaging_legacy, build, pyproject_metadata] + project: [packaging_legacy, build, pyproject_metadata, setuptools] steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 diff --git a/noxfile.py b/noxfile.py index e5aa08d9e..1361d1694 100644 --- a/noxfile.py +++ b/noxfile.py @@ -82,6 +82,7 @@ def tests(session: nox.Session) -> None: PROJECTS = { "packaging_legacy": "https://github.com/di/packaging_legacy/archive/refs/tags/23.0.post0.tar.gz", "build": "https://github.com/pypa/build/archive/refs/tags/1.4.0.tar.gz", + "setuptools": "https://github.com/pypa/setuptools/archive/refs/tags/v80.10.1.tar.gz", "pyproject_metadata": "https://github.com/pypa/pyproject-metadata/archive/refs/tags/0.10.0.tar.gz", } @@ -89,6 +90,7 @@ def tests(session: nox.Session) -> None: @nox.parametrize("project", list(PROJECTS)) @nox.session(default=False) def downstream(session: nox.Session, project: str) -> None: + pkg_dir = Path.cwd() / "src/packaging" env = {"FORCE_COLOR": None} session.install("-e.") @@ -109,12 +111,19 @@ def downstream(session: nox.Session, project: str) -> None: session.install("-r", "tests/requirements.txt") session.install("-e.") session.run(*pip_cmd, "list") - session.run("pytest", env=env) + session.run("pytest", *session.posargs, env=env) elif project in {"build", "pyproject_metadata"}: session.install("-e.", "--group=test") if project != "build": session.run(*pip_cmd, "list") - session.run("pytest", env=env) + session.run("pytest", *session.posargs, env=env) + elif project == "setuptools": + session.install("-e.[test,cover]") + session.run(*pip_cmd, "list") + repl_dir = "setuptools/_vendor/packaging" + shutil.rmtree(repl_dir) + shutil.copytree(pkg_dir, repl_dir) + session.run("pytest", *session.posargs, env=env) else: session.error("Unknown package") From d50298b13bb2fa630963f33649880239f01fa989 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Wed, 21 Jan 2026 19:56:26 -0500 Subject: [PATCH 08/12] ci: add pip Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 2 +- noxfile.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 62212688e..5998986f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -56,7 +56,7 @@ jobs: strategy: fail-fast: false matrix: - project: [packaging_legacy, build, pyproject_metadata, setuptools] + project: [packaging_legacy, build, pyproject_metadata, setuptools, pip] steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 diff --git a/noxfile.py b/noxfile.py index 1361d1694..c26e789fb 100644 --- a/noxfile.py +++ b/noxfile.py @@ -84,6 +84,7 @@ def tests(session: nox.Session) -> None: "build": "https://github.com/pypa/build/archive/refs/tags/1.4.0.tar.gz", "setuptools": "https://github.com/pypa/setuptools/archive/refs/tags/v80.10.1.tar.gz", "pyproject_metadata": "https://github.com/pypa/pyproject-metadata/archive/refs/tags/0.10.0.tar.gz", + "pip": "https://github.com/pypa/pip/archive/refs/tags/25.3.tar.gz", } @@ -124,6 +125,21 @@ def downstream(session: nox.Session, project: str) -> None: shutil.rmtree(repl_dir) shutil.copytree(pkg_dir, repl_dir) session.run("pytest", *session.posargs, env=env) + elif project == "pip": + session.install("-e.", "--group=test") + session.run( + "pip", + "wheel", + "-w", + "tests/data/common_wheels", + "--group", + "test-common-wheels", + ) + session.run(*pip_cmd, "list") + repl_dir = "src/pip/_vendor/packaging" + shutil.rmtree(repl_dir) + shutil.copytree(pkg_dir, repl_dir) + session.run("pytest", "tests/unit", "--numprocesses=auto", *session.posargs) else: session.error("Unknown package") From f0959d76c25f6044671df5dcc42752a63e9d9ffa Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 23 Jan 2026 12:21:35 -0500 Subject: [PATCH 09/12] chore: use a newer pip Signed-off-by: Henry Schreiner --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index c26e789fb..c8538ed06 100644 --- a/noxfile.py +++ b/noxfile.py @@ -84,7 +84,7 @@ def tests(session: nox.Session) -> None: "build": "https://github.com/pypa/build/archive/refs/tags/1.4.0.tar.gz", "setuptools": "https://github.com/pypa/setuptools/archive/refs/tags/v80.10.1.tar.gz", "pyproject_metadata": "https://github.com/pypa/pyproject-metadata/archive/refs/tags/0.10.0.tar.gz", - "pip": "https://github.com/pypa/pip/archive/refs/tags/25.3.tar.gz", + "pip": "https://github.com/pypa/pip/archive/200251ab8df071b6c0a83504c29db7871a29b8c9.tar.gz", } From cfc7e65b5a8a52f923af7c8d5a07ea8186c0c5d3 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 12 Feb 2026 09:46:54 -0500 Subject: [PATCH 10/12] tests: update releases Signed-off-by: Henry Schreiner --- noxfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index c8538ed06..19ce26d61 100644 --- a/noxfile.py +++ b/noxfile.py @@ -82,9 +82,9 @@ def tests(session: nox.Session) -> None: PROJECTS = { "packaging_legacy": "https://github.com/di/packaging_legacy/archive/refs/tags/23.0.post0.tar.gz", "build": "https://github.com/pypa/build/archive/refs/tags/1.4.0.tar.gz", - "setuptools": "https://github.com/pypa/setuptools/archive/refs/tags/v80.10.1.tar.gz", - "pyproject_metadata": "https://github.com/pypa/pyproject-metadata/archive/refs/tags/0.10.0.tar.gz", - "pip": "https://github.com/pypa/pip/archive/200251ab8df071b6c0a83504c29db7871a29b8c9.tar.gz", + "setuptools": "https://github.com/pypa/setuptools/archive/refs/tags/v82.0.0.tar.gz", + "pyproject_metadata": "https://github.com/pypa/pyproject-metadata/archive/refs/tags/0.11.0.tar.gz", + "pip": "https://github.com/pypa/pip/archive/refs/tags/26.0.1.tar.gz", } From f74e94d337531f61b4df9ea596cd232c2cf90cda Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 12 Feb 2026 10:07:39 -0500 Subject: [PATCH 11/12] tests: skip pip svn test Signed-off-by: Henry Schreiner --- noxfile.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 19ce26d61..c889799eb 100644 --- a/noxfile.py +++ b/noxfile.py @@ -139,7 +139,14 @@ def downstream(session: nox.Session, project: str) -> None: repl_dir = "src/pip/_vendor/packaging" shutil.rmtree(repl_dir) shutil.copytree(pkg_dir, repl_dir) - session.run("pytest", "tests/unit", "--numprocesses=auto", *session.posargs) + session.run( + "pytest", + "tests/unit", + "--numprocesses=auto", + "-k", + "not test_ensure_svn_available", + *session.posargs, + ) else: session.error("Unknown package") From 2f4e5b6b38d4245eecc671f7f01395360a258a93 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 6 Mar 2026 11:06:46 -0500 Subject: [PATCH 12/12] chore: avoid known flaky tests in setuptools Signed-off-by: Henry Schreiner --- noxfile.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index c889799eb..bfb1b9557 100644 --- a/noxfile.py +++ b/noxfile.py @@ -91,6 +91,9 @@ def tests(session: nox.Session) -> None: @nox.parametrize("project", list(PROJECTS)) @nox.session(default=False) def downstream(session: nox.Session, project: str) -> None: + """ + Run downstream projects with this packaging. + """ pkg_dir = Path.cwd() / "src/packaging" env = {"FORCE_COLOR": None} session.install("-e.") @@ -124,7 +127,8 @@ def downstream(session: nox.Session, project: str) -> None: repl_dir = "setuptools/_vendor/packaging" shutil.rmtree(repl_dir) shutil.copytree(pkg_dir, repl_dir) - session.run("pytest", *session.posargs, env=env) + skips = ["-k", "not test_editable_install and not test_editable_with_pyproject"] + session.run("pytest", *skips, *session.posargs, env=env) elif project == "pip": session.install("-e.", "--group=test") session.run(