Skip to content

Add option to dump PEP 517 metadata#940

Merged
henryiii merged 13 commits intopypa:mainfrom
layday:feat-metadata-json
Oct 28, 2025
Merged

Add option to dump PEP 517 metadata#940
henryiii merged 13 commits intopypa:mainfrom
layday:feat-metadata-json

Conversation

@layday
Copy link
Member

@layday layday commented Oct 22, 2025

No description provided.

So that it can be used with pyproject-hooks.
* Sectionised help text.
* Redirected logging messages to stderr by default to prevent piping
  conflicts.
* Factored out the config settings mangler 'cause McCabe was displeased.
@layday layday force-pushed the feat-metadata-json branch from 3546ce7 to 0e6dad1 Compare October 22, 2025 20:36
@layday layday marked this pull request as ready for review October 23, 2025 05:20
@hynek
Copy link

hynek commented Oct 24, 2025

That's a lot more code changes than I hoped and I don't think I can have a worthwhile opinion on them, but ../build/.venv/bin/pyproject-build --metadata 2>/dev/null | jq -r .version works like a charm in my projects! Thanks for the extremely fast workaround! cc @glyph

@henryiii henryiii requested a review from Copilot October 28, 2025 14:27
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for dumping PEP 517 metadata in JSON format via a new --metadata flag, while also refactoring the internal build and logging infrastructure to improve code organization.

Key changes:

  • Introduces --metadata option to output wheel metadata as JSON
  • Refactors build environment bootstrapping into a shared context manager
  • Redirects all logging output to stderr to keep stdout clean for metadata output

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_main.py Adds test coverage for metadata output functionality and updates existing tests to match new logging behavior (stderr instead of stdout)
tests/constraints.txt Updates packaging dependency to version 24.0
src/build/_ctx.py Refactors subprocess execution to support custom runners and consolidates stdout/stderr streams
src/build/main.py Implements metadata extraction, refactors build environment setup, reorganizes CLI argument groups, and redirects logging to stderr
pyproject.toml Updates packaging and mypy dependency versions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
@henryiii henryiii merged commit 4434de5 into pypa:main Oct 28, 2025
64 checks passed
@henryiii
Copy link
Contributor

I'm curious, how are you supposed to use this since it prints out to stdout, where we are already printing things (and the backend might, too)?

$ uv run pyproject-build --metadata
* Creating isolated environment: virtualenv+pip...
* Installing packages in isolated environment:
  - flit-core >= 3.11
* Getting build dependencies for wheel...
* Getting metadata for wheel...
{
  "license_files": [
    "LICENSE"
  ],
  "provides_extra": [
    "uv",
    "virtualenv"
  ],
  "author_email": "Filipe Laíns <lains@riseup.net>, Bernát Gábor <gaborjbernat@gmail.com>, layday <layday@protonmail.com>, Henry Schreiner <henryschreineriii@gmail.com>",
  "metadata_version": "2.4",
  "classifiers": [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Programming Language :: Python :: Implementation :: CPython",
    "Programming Language :: Python :: Implementation :: PyPy"
  ],
  "license_expression": "MIT",
  "requires_python": ">= 3.9",
  "version": "1.3.0",
* Creating isolated environment: virtualenv+pip...
* Installing packages in isolated environment:
  - flit-core >= 3.11
* Getting build dependencies for wheel...
* Getting metadata for wheel...
{
  "name": "build",
  "description_content_type": "text/markdown",
  "license_files": [
    "LICENSE"
  ],
  "provides_extra": [
    "uv",
    "virtualenv"
  ],
  "project_urls": {
    "changelog": "https://build.pypa.io/en/stable/changelog.html",
    "homepage": "https://build.pypa.io",
    "issues": "https://github.com/pypa/build/issues",
    "source": "https://github.com/pypa/build"
  },
  "author_email": "Filipe Laíns <lains@riseup.net>, Bernát Gábor <gaborjbernat@gmail.com>, layday <layday@protonmail.com>, Henry Schreiner <henryschreineriii@gmail.com>",
  "classifiers": [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
  "project_urls": {
    "changelog": "https://build.pypa.io/en/stable/changelog.html",
    "homepage": "https://build.pypa.io",
    "issues": "https://github.com/pypa/build/issues",
    "source": "https://github.com/pypa/build"
  },
  "name": "build",
  "description_content_type": "text/markdown",
  "requires_dist": [
    "packaging >= 24.0",
    "pyproject_hooks",
    "colorama; os_name == \"nt\"",
    "importlib-metadata >= 4.6; python_full_version < \"3.10.2\"",
    "tomli >= 1.1.0; python_version < \"3.11\"",
    "uv >= 0.1.18 ; extra == \"uv\"",
    "virtualenv >= 20.11 ; extra == \"virtualenv\" and ( python_version < '3.10')",
    "virtualenv >= 20.17 ; extra == \"virtualenv\" and ( python_version >= '3.10' and python_version < '3.14')",
    "virtualenv >= 20.31 ; extra == \"virtualenv\" and ( python_version >= '3.14')"
  ],
  "summary": "A simple, correct Python build frontend",
  "description": "# build\n\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pypa/build/main.svg)](https://results.pre-commit.ci/latest/github/pypa/build/main)\n[![CI test](https://github.com/pypa/build/actions/workflows/test.yml/badge.svg)](https://github.com/pypa/build/actions/workflows/test.yml)\n[![codecov](https://codecov.io/gh/pypa/build/branch/main/graph/badge.svg)](https://codecov.io/gh/pypa/build)\n\n[![Documentation Status](https://readthedocs.org/projects/pypa-build/badge/?version=latest)](https://build.pypa.io/en/latest/?badge=latest)\n[![PyPI version](https://badge.fury.io/py/build.svg)](https://pypi.org/project/build/)\n[![Discord](https://img.shields.io/discord/803025117553754132?label=Discord%20chat%20%23build)](https://discord.gg/pypa)\n\nA simple, correct Python build frontend.\n\nSee the [documentation](https://build.pypa.io) for more information.\n\n### Installation\n\n`build` can be installed via `pip` or an equivalent via:\n\n```console\n$ pip install build\n```\n\n### Usage\n\n```console\n$ python -m build\n```\n\nThis will build the package in an isolated environment, generating a\nsource-distribution and wheel in the directory `dist/`. See the\n[documentation](https://build.pypa.io) for full information. Build is also\navailable via the command line as `pyproject-build` once installed.\n\n### Common arguments\n\n- `--sdist` (`-s`): Produce just an SDist\n- `--wheel` (`-w`): Produce just a wheel\n- `--metadata`: Produce just the metadata as JSON. Cannot be used with `--sdist`/`--wheel`.\n- `-C<option>=<value>`: A Config-setting, the PEP 517 way of passing options to a backend. Can be passed multiple times. Matching options will make a list. Note that setuptools has very limited support.\n- `--config-json=<value>`: An alternative way to pass in complex config settings as JSON strings. Can't be used with `-C`.\n- `--installer`: Pick an installer for the isolated build (`pip` or `uv`).\n- `--no-isolation` (`-n`): Disable build isolation.\n- `--skip-dependency-check` (`-x`): Disable dependency checking when not isolated; this should be done if some requirements or version ranges are not required for non-isolated builds.\n- `--outdir` (`-o`): The output directory (defaults to `dist`)\n\nSome common combinations of arguments:\n\n- `--sdist --wheel` (`-sw`): Produce and SDist and a wheel, both from the source distribution. The default (if no flag is passed) is to build an SDist and then build a wheel _from_ the SDist.\n- `-nx`: Disable build isolation and dependency checking. Identical to pip and uv's `--no-build-isolation` flag.\n\n### Integration with other tools\n\n#### pipx\n\nIf you use [pipx][], such as in GitHub Actions, the following command will download\nand run build in one step:\n\n```console\n$ pipx run build\n```\n\n#### uv\n\nIf you want to use [uv][] to speed up the virtual environment creation, you can\nuse `--installer=uv`. You can get a Python wheel for `uv` with the `[uv]`\nextra. For example, using pipx like above:\n\n```console\n$ pipx run 'build[uv]' --installer uv\n```\n\nIf you already have uv, you don't need the extra. For example:\n\n```console\n$ uvx --from build pyproject-build --installer uv\n```\n\n#### cibuildwheel\n\nIf you are using [cibuildwheel][], build is integrated and the default builder in 3.0+. If you want to use `uv` as the installer, you can use:\n\n```toml\n[tool.cibuildwheel]\nbuild-frontend = \"build[uv]\"\n```\n\n(Be sure to pre-install uv before running cibuildwheel for this one!)\n\n#### Conda-forge\n\nOn conda-forge, this package is called [python-build][].\n\n### Code of Conduct\n\nEveryone interacting in the build's codebase, issue trackers, chat rooms, and mailing lists is expected to follow\nthe [PSF Code of Conduct].\n\n[psf code of conduct]: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n[pipx]: https://pipx.pypa.io\n[uv]: https://docs.astral.sh/uv/\n[cibuildwheel]: https://cibuildwheel.pypa.io\n[python-build]: https://github.com/conda-forge/python-build-feedstock\n\n"
}

I'm thinking we could provide a new --report-file option, which would write out the filename info to a file if building file(s), or this report if building metadata?

@henryiii
Copy link
Contributor

Ahh, I see the 2>/dev/null trick above. That helps.

@layday
Copy link
Member Author

layday commented Oct 28, 2025

You don't need to redirect stderr to /dev/null unless you are intent on not seeing any output. The following is sufficient: pyproject-build --metadata | jq -r .version.

@layday layday linked an issue Nov 1, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an option to dump PEP 517 metadata?

5 participants