Skip to content

Commit 42154ad

Browse files
authored
Upgrade to Python 3.13.1 (#17447)
* Upgrade to Python 3.13.1 * add a diaper test to ensure we don't regress on passlib funcitonality * recompile dependencies
1 parent 5c8c415 commit 42154ad

File tree

14 files changed

+55
-25
lines changed

14 files changed

+55
-25
lines changed

.python-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.12.7
1+
3.13.1

.readthedocs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ version: 2
88
build:
99
os: ubuntu-24.04
1010
tools:
11-
python: "3.12"
11+
python: "3.13"
1212
commands:
1313
- ./bin/rtd-docs

Dockerfile

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ RUN NODE_ENV=production npm run build
3838

3939

4040
# We'll build a light-weight layer along the way with just docs stuff
41-
FROM python:3.12.7-slim-bookworm AS docs
41+
FROM python:3.13.1-slim-bookworm AS docs
4242

4343
# By default, Docker has special steps to avoid keeping APT caches in the layers, which
4444
# is good, but in our case, we're going to mount a special cache volume (kept between
@@ -107,7 +107,7 @@ USER docs
107107

108108
# Now we're going to build our actual application, but not the actual production
109109
# image that it gets deployed into.
110-
FROM python:3.12.7-slim-bookworm AS build
110+
FROM python:3.13.1-slim-bookworm AS build
111111

112112
# Define whether we're building a production or a development image. This will
113113
# generally be used to control whether or not we install our development and
@@ -191,7 +191,7 @@ RUN --mount=type=cache,target=/root/.cache/pip \
191191

192192
# Now we're going to build our actual application image, which will eventually
193193
# pull in the static files that were built above.
194-
FROM python:3.12.7-slim-bookworm
194+
FROM python:3.13.1-slim-bookworm
195195

196196
# Setup some basic environment variables that are ~never going to change.
197197
ENV PYTHONUNBUFFERED 1

bin/lint

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export LANG="${ENCODING:-en_US.UTF-8}"
1111
set -x
1212

1313
# Actually run our tests.
14-
find . -name '*.py' -exec python -m pyupgrade --py312-plus {} +
14+
find . -name '*.py' -exec python -m pyupgrade --py313-plus {} +
1515
python -m flake8 .
1616
python -m black --check --diff *.py warehouse/ tests/
1717
python -m isort --check *.py warehouse/ tests/

bin/reformat

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22
set -ex
33

4-
find . -name '*.py' -exec python -m pyupgrade --py312-plus {} +
4+
find . -name '*.py' -exec python -m pyupgrade --py313-plus {} +
55
python -m isort *.py warehouse/ tests/
66
python -m black *.py warehouse/ tests/

dev/flake8/checkers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def __init__(self, tree: ast.AST, filename: str) -> None:
8787
self.tree = tree
8888
self.filename = filename
8989

90-
def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
90+
def run(self) -> Generator[tuple[int, int, str, type[Any]]]:
9191
visitor = WarehouseVisitor(self.filename)
9292
visitor.visit(self.tree)
9393

requirements/deploy.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/deploy.txt requirements/deploy.in
@@ -94,6 +94,10 @@ importlib-metadata==8.5.0 \
9494
--hash=sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b \
9595
--hash=sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7
9696
# via opentelemetry-api
97+
legacy-cgi==2.6.2 \
98+
--hash=sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f \
99+
--hash=sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff
100+
# via ddtrace
97101
opentelemetry-api==1.29.0 \
98102
--hash=sha256:5fcd94c4141cc49c736271f3e1efb777bebe9cc535759c54c936cca4f1b312b8 \
99103
--hash=sha256:d04a6cf78aad09614f52964ecb38021e248f5714dc32c2e0d8fd99517b4d69cf

requirements/docs-blog.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/docs-blog.txt requirements/docs-blog.in

requirements/docs-dev.txt

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/docs-dev.txt requirements/docs-dev.in
@@ -404,10 +404,6 @@ starlette==0.45.2 \
404404
--hash=sha256:4daec3356fb0cb1e723a5235e5beaf375d2259af27532958e2d79df549dad9da \
405405
--hash=sha256:bba1831d15ae5212b22feab2f218bab6ed3cd0fc2dc1d4442443bb1ee52260e0
406406
# via sphinx-autobuild
407-
typing-extensions==4.12.2 \
408-
--hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \
409-
--hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8
410-
# via anyio
411407
urllib3==2.3.0 \
412408
--hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \
413409
--hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d

requirements/docs-user.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/docs-user.txt requirements/docs-user.in

requirements/lint.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/lint.txt requirements/lint.in

requirements/main.txt

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/main.txt requirements/main.in
@@ -994,6 +994,10 @@ lazy-object-proxy==1.10.0 \
994994
--hash=sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03 \
995995
--hash=sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c
996996
# via openapi-spec-validator
997+
legacy-cgi==2.6.2 \
998+
--hash=sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f \
999+
--hash=sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff
1000+
# via webob
9971001
limits==4.0.1 \
9981002
--hash=sha256:67667e669f570cf7be4e2c2bc52f763b3f93bdf66ea945584360bc1a3f251901 \
9991003
--hash=sha256:a54f5c058dfc965319ae3ee78faf222294659e371b46d22cd7456761f7e46d5a
@@ -2286,10 +2290,8 @@ typing-extensions==4.12.2 \
22862290
# via
22872291
# alembic
22882292
# limits
2289-
# psycopg
22902293
# pydantic
22912294
# pydantic-core
2292-
# pyopenssl
22932295
# sqlalchemy
22942296
# stripe
22952297
tzdata==2024.2 \

requirements/tests.txt

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# This file is autogenerated by pip-compile with Python 3.12
2+
# This file is autogenerated by pip-compile with Python 3.13
33
# by the following command:
44
#
55
# pip-compile --allow-unsafe --generate-hashes --output-file=requirements/tests.txt requirements/tests.in
@@ -211,6 +211,10 @@ iniconfig==2.0.0 \
211211
--hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
212212
--hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
213213
# via pytest
214+
legacy-cgi==2.6.2 \
215+
--hash=sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f \
216+
--hash=sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff
217+
# via webob
214218
mirakuru==2.5.3 \
215219
--hash=sha256:2fab68356fb98fb5358ea3ab65f5e511f34b5a0b16cfd0a0935ef15a3393f025 \
216220
--hash=sha256:39b33f8fcdf13764a6cfe936e0feeead3902a161fec438df3be7cce98f7933c6
@@ -383,9 +387,7 @@ termcolor==2.5.0 \
383387
typing-extensions==4.12.2 \
384388
--hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \
385389
--hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8
386-
# via
387-
# faker
388-
# psycopg
390+
# via faker
389391
urllib3==2.3.0 \
390392
--hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \
391393
--hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d

tests/unit/accounts/test_services.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,33 @@ def test_check_password_valid(self, user_service, metrics):
303303
),
304304
]
305305

306-
def test_check_password_updates(self, user_service):
306+
@pytest.mark.parametrize(
307+
"password",
308+
[
309+
(
310+
"$argon2id$v=19$m=8,t=1,p=1$"
311+
"w/gfo5QSQihFyHlvDcE4pw$Hd4KENg+xDlq2bfeGUEYSieIXXL/c1NfTr0ZkYueO2Y"
312+
),
313+
(
314+
"$bcrypt-sha256$v=2,t=2b,r=12$"
315+
"DqC0lms6x9Dh6XesvIJvVe$hBbYe9JfdjyorOFcS3rv5BhmuSIyXD6"
316+
),
317+
"$2b$12$2t/EVU3H9b3c5iR6GdELZOwCoyrT518DgCpNxHbX.S1IxV6eEEDhC",
318+
"bcrypt$$2b$12$EhhZDxGr/7HIKYRGMngC.O4sQx68vkaISSnSGZ6s8iOfaGy6l9cma",
319+
],
320+
)
321+
def test_check_password_updates(self, user_service, password):
322+
"""
323+
This test confirms passlib is actually working,
324+
see https://github.com/pypi/warehouse/issues/15454
325+
"""
326+
user = UserFactory.create(password=password)
327+
328+
assert user_service.check_password(user.id, "password")
329+
assert user.password.startswith("$argon2id$v=19$m=1024,t=6,p=6$")
330+
assert user_service.check_password(user.id, "password")
331+
332+
def test_hash_is_upgraded(self, user_service):
307333
user = UserFactory.create()
308334
password = user.password
309335
user_service.hasher = pretend.stub(

0 commit comments

Comments
 (0)