Skip to content

Commit f1f28ac

Browse files
authored
Merge branch 'main' into license-expression-distribution
2 parents acdb79c + 56c1fef commit f1f28ac

File tree

8 files changed

+162
-40
lines changed

8 files changed

+162
-40
lines changed

.github/workflows/test.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@ on:
66
branches-ignore:
77
- gh-readonly-queue/** # Temporary merge queue-related GH-made branches
88
pull_request:
9+
types:
10+
- opened # default
11+
- synchronize # default
12+
- reopened # default
13+
- ready_for_review # used in PRs created from GitHub Actions workflows
914
workflow_call:
1015

1116
concurrency:
1217
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
1318
cancel-in-progress: true
1419

20+
permissions: {}
21+
1522
jobs:
1623
build:
1724
name: ${{ matrix.noxenv }}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
3+
name: Update uv build version
4+
5+
on:
6+
schedule:
7+
- cron: "0 6 * * 1" # mondays at 6am
8+
workflow_dispatch:
9+
10+
jobs:
11+
update-uv-build-version:
12+
name: Update uv_build version
13+
if: github.repository_owner == 'pypa' # suppress noise in forks
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write
17+
pull-requests: write
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
with:
22+
persist-credentials: false
23+
- name: Set up uv
24+
uses: astral-sh/setup-uv@v5
25+
- name: Update uv_build version
26+
id: update_script
27+
run: uv run scripts/update_uv_build_version.py
28+
- # If there are no changes, no pull request will be created and the action exits silently.
29+
name: Create Pull Request
30+
uses: peter-evans/create-pull-request@v7
31+
with:
32+
token: ${{ secrets.GITHUB_TOKEN }}
33+
commit-message: Update uv_build version to ${{ steps.update_script.outputs.version }}
34+
title: Update uv_build version to ${{ steps.update_script.outputs.version }}
35+
draft: true # Trigger CI by un-drafting the PR, otherwise `GITHUB_TOKEN` PRs don't trigger CI.
36+
body: |
37+
Automated update of uv_build version bounds for uv ${{ steps.update_script.outputs.version }}.
38+
39+
This PR was created automatically by the cron workflow, ping `@konstin` for problems.
40+
branch: bot/update-uv-build-version
41+
delete-branch: true
42+
43+
...

scripts/update_uv_build_version.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# /// script
2+
# requires-python = ">= 3.12"
3+
# dependencies = [
4+
# "httpx>=0.28.1,<0.29",
5+
# "packaging>=25.0",
6+
# ]
7+
# ///
8+
import os
9+
import re
10+
from pathlib import Path
11+
12+
import httpx
13+
from packaging.utils import parse_wheel_filename
14+
from packaging.version import Version
15+
16+
17+
def main():
18+
response = httpx.get(
19+
"https://pypi.org/simple/uv-build/",
20+
headers={"Accept": "application/vnd.pypi.simple.v1+json"},
21+
)
22+
response.raise_for_status()
23+
data = response.json()
24+
current_release = None
25+
for file in data["files"]:
26+
if not file["filename"].endswith(".whl"):
27+
continue
28+
_name, version, _build, _tags = parse_wheel_filename(file["filename"])
29+
if version.is_prerelease:
30+
continue
31+
if current_release is None or version > current_release:
32+
current_release = version
33+
34+
[major, minor, _patch] = current_release.release
35+
if major != 0:
36+
raise NotImplementedError("The script needs to be updated for uv 1.x")
37+
upper_bound = Version(f"{major}.{minor + 1}.0")
38+
39+
repository_root = Path(__file__).parent.parent
40+
existing = repository_root.joinpath(
41+
"source/shared/build-backend-tabs.rst"
42+
).read_text()
43+
replacement = f'requires = ["uv_build >= {current_release}, <{upper_bound}"]'
44+
searcher = re.compile(re.escape('requires = ["uv_build') + ".*" + re.escape('"]'))
45+
if not searcher.search(existing):
46+
raise RuntimeError("Could not `uv-build` entry")
47+
updated = searcher.sub(replacement, existing)
48+
49+
if existing != updated:
50+
print("Updating source/shared/build-backend-tabs.rst")
51+
Path("source/shared/build-backend-tabs.rst").write_text(updated)
52+
if github_output := os.environ.get("GITHUB_OUTPUT"):
53+
with open(github_output, "a") as f:
54+
f.write(f"version={current_release}\n")
55+
f.write("updated=true\n")
56+
else:
57+
print("Already up-to-date source/shared/build-backend-tabs.rst")
58+
if github_output := os.environ.get("GITHUB_OUTPUT"):
59+
with open(github_output, "a") as f:
60+
f.write("updated=false\n")
61+
62+
63+
if __name__ == "__main__":
64+
main()

source/guides/creating-command-line-tools.rst

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,22 @@ named after the main module:
4040
4141
4242
def greet(
43-
name: Annotated[str, typer.Argument(help="The (last, if --gender is given) name of the person to greet")] = "",
44-
gender: Annotated[str, typer.Option(help="The gender of the person to greet")] = "",
45-
knight: Annotated[bool, typer.Option(help="Whether the person is a knight")] = False,
43+
name: Annotated[str, typer.Argument(help="The (last, if --title is given) name of the person to greet")] = "",
44+
title: Annotated[str, typer.Option(help="The preferred title of the person to greet")] = "",
45+
doctor: Annotated[bool, typer.Option(help="Whether the person is a doctor (MD or PhD)")] = False,
4646
count: Annotated[int, typer.Option(help="Number of times to greet the person")] = 1
4747
):
48-
greeting = "Greetings, dear "
49-
masculine = gender == "masculine"
50-
feminine = gender == "feminine"
51-
if gender or knight:
52-
salutation = ""
53-
if knight:
54-
salutation = "Sir "
55-
elif masculine:
56-
salutation = "Mr. "
57-
elif feminine:
58-
salutation = "Ms. "
59-
greeting += salutation
60-
if name:
61-
greeting += f"{name}!"
48+
greeting = "Greetings, "
49+
if doctor and not title:
50+
title = "Dr."
51+
if not name:
52+
if title:
53+
name = title.lower().rstrip(".")
6254
else:
63-
pronoun = "her" if feminine else "his" if masculine or knight else "its"
64-
greeting += f"what's-{pronoun}-name"
65-
else:
66-
if name:
67-
greeting += f"{name}!"
68-
elif not gender:
69-
greeting += "friend!"
55+
name = "friend"
56+
if title:
57+
greeting += f"{title} "
58+
greeting += f"{name}!"
7059
for i in range(0, count):
7160
print(greeting)
7261
@@ -145,12 +134,14 @@ Let's test it:
145134

146135
.. code-block:: console
147136
148-
$ greet --knight Lancelot
149-
Greetings, dear Sir Lancelot!
150-
$ greet --gender feminine Parks
151-
Greetings, dear Ms. Parks!
152-
$ greet --gender masculine
153-
Greetings, dear Mr. what's-his-name!
137+
$ greet
138+
Greetings, friend!
139+
$ greet --doctor Brennan
140+
Greetings, Dr. Brennan!
141+
$ greet --title Ms. Parks
142+
Greetings, Ms. Parks!
143+
$ greet --title Mr.
144+
Greetings, Mr. mr!
154145
155146
Since this example uses ``typer``, you could now also get an overview of the program's usage by calling it with
156147
the ``--help`` option, or configure completions via the ``--install-completion`` option.
@@ -160,7 +151,7 @@ To just run the program without installing it permanently, use ``pipx run``, whi
160151

161152
.. code-block:: console
162153
163-
$ pipx run --spec . greet --knight
154+
$ pipx run --spec . greet --doctor
164155
165156
This syntax is a bit impractical, however; as the name of the entry point we defined above does not match the package name,
166157
we need to state explicitly which executable script to run (even though there is only on in existence).
@@ -179,7 +170,7 @@ default one and run it, which makes this command possible:
179170

180171
.. code-block:: console
181172
182-
$ pipx run . --knight
173+
$ pipx run . --doctor
183174
184175
Conclusion
185176
==========

source/guides/writing-pyproject-toml.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ backend>` now support the new format as shown in the following table.
319319
- 77.0.3
320320
- 3.12
321321
- 2.4.0
322-
- `not yet <poetry-pep639-issue_>`_
322+
- 2.2.0
323323
- 0.7.19
324324

325325

@@ -587,7 +587,6 @@ A full example
587587
.. _pypi-search-pip: https://pypi.org/search?q=pip
588588
.. _classifier-list: https://pypi.org/classifiers
589589
.. _requires-python-blog-post: https://iscinumpy.dev/post/bound-version-constraints/#pinning-the-python-version-is-special
590-
.. _poetry-pep639-issue: https://github.com/python-poetry/poetry/issues/9670
591590
.. _pytest: https://pytest.org
592591
.. _pygments: https://pygments.org
593592
.. _rest: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html

source/overview.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ originated and where the technologies below work best:
339339
Bringing your own kernel
340340
^^^^^^^^^^^^^^^^^^^^^^^^
341341

342-
Most operating systems support some form of classical virtualization,
342+
Most desktop operating systems support some form of classical virtualization,
343343
running applications packaged as images containing a full operating
344344
system of their own. Running these virtual machines, or VMs, is a
345345
mature approach, widespread in data center environments.
@@ -348,9 +348,13 @@ These techniques are mostly reserved for larger scale deployments in
348348
data centers, though certain complex applications can benefit from
349349
this packaging. The technologies are Python agnostic, and include:
350350

351-
* `Vagrant <https://www.vagrantup.com/>`_
352-
* `VHD <https://en.wikipedia.org/wiki/VHD_(file_format)>`_, `AMI <https://en.wikipedia.org/wiki/Amazon_Machine_Image>`_, and :doc:`other formats <openstack:user/formats>`
353-
* `OpenStack <https://www.redhat.com/en/topics/openstack>`_ - A cloud management system in Python, with extensive VM support
351+
* KVM on Linux
352+
* Hyper-V on Windows
353+
* `VHD <https://en.wikipedia.org/wiki/VHD_(file_format)>`_,
354+
`AMI <https://en.wikipedia.org/wiki/Amazon_Machine_Image>`_,
355+
and :doc:`other formats <openstack:user/formats>`
356+
* `OpenStack <https://www.redhat.com/en/topics/openstack>`_ -
357+
A cloud management system written in Python, with extensive VM support
354358

355359
Bringing your own hardware
356360
^^^^^^^^^^^^^^^^^^^^^^^^^^

source/shared/build-backend-tabs.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,5 @@
3838
.. code-block:: toml
3939
4040
[build-system]
41-
requires = ["uv_build >= 0.7.19, <0.9.0"]
41+
requires = ["uv_build >= 0.8.17, <0.9.0"]
4242
build-backend = "uv_build"

source/specifications/core-metadata.rst

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ only, and indicates that the field value was calculated at wheel build time,
133133
and may not be the same as the value in the sdist or in other wheels for the
134134
project.
135135

136+
Note in particular that if you have obtained a prebuilt wheel, you cannot
137+
assume that a field which is not marked as ``Dynamic`` will have the same value
138+
in other wheels, as some wheels are not built directly from the sdist, but are
139+
modified from existing wheels (the ``auditwheel`` tool does this, for example,
140+
and it's commonly used when building wheels for PyPI). Such modifications
141+
*could* include changing metadata (even non-dynamic metadata). Similarly, if
142+
you have a sdist and a wheel which you didn't build from that sdist, you cannot
143+
assume that the wheel's metadata matches that of the sdist, even if the field
144+
is not marked as ``Dynamic``.
145+
136146
Full details of the semantics of ``Dynamic`` are described in :pep:`643`.
137147

138148
.. _core-metadata-platform:
@@ -926,8 +936,12 @@ Example::
926936
History
927937
=======
928938

929-
- August 2025: Clarified that ``License-Expression`` applies to the containing
939+
- October 2025: Clarified that ``License-Expression`` applies to the containing
930940
distribution file and not the project itself.
941+
942+
- August 2025: Clarified that ``Dynamic`` only affects how fields
943+
must be treated when building a wheel from a sdist, not when modifying
944+
a wheel.
931945

932946
- August 2024: Core metadata 2.4 was approved through :pep:`639`.
933947

0 commit comments

Comments
 (0)