Drop in uv for pip (#10428)

It's a [drop-in
replacement](https://docs.astral.sh/uv/pip/compatibility/) that speeds
things up. I don't see any reason why not.

`--use-pep517` is [set by default](
https://docs.astral.sh/uv/pip/compatibility/#pep-517-build-isolation),
so we don't need it.

`--disable-pip-version-check` also does nothing on uv.

`uv` [uses
separate](https://docs.astral.sh/uv/pip/compatibility/#build-constraints)
`UV_BUILD_CONSTRAINT` and `UV_CONSTRAINT`. I just added it to both to do
the simplest thing here. We could split them.

We probably don't actually need to pipstrap pip anymore, I could take
that out.

What's happening with `parsedatetime` and `python-digitalocean` is that
they were always secretly wrong. Since `pip` compiles bytecode by
default, it was suppressing the errors. If you add the
`--compile-bytecode` flag to `uv`, it passes, but I don't think we
should do that. You can see the failure happen on main by passing
`--no-compile` to the pip args and running `certbot -r -e oldest`.

Now what I don't understand is that some places seem to say the `'\/'`
error from `parsedatetime` only started in python 3.12, whereas others
see it on earlier python. Perhaps pytest is vendorizing python or
something. Not too worried about that, needed to get updated anyway, and
it's an accurate oldest version based on our oldest OSes.
`python-digitalocean` is techincally newer than debian 11, but we've
made that decision before so it seems fine to me.
This commit is contained in:
ohemorange 2025-08-18 13:17:02 -07:00 committed by GitHub
parent cad2c61db1
commit 00a51ab22b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 35 additions and 22 deletions

3
.gitignore vendored
View file

@ -62,3 +62,6 @@ certbot-dns*/certbot-dns*_arm*.txt
/certbot_arm*.txt
certbot-dns*/snap
snapcraft.cfg
# pyenv files
.python-version

View file

@ -5,7 +5,7 @@ from setuptools import setup
version = '5.0.0.dev0'
install_requires = [
'python-digitalocean>=1.11', # 1.15.0 or newer is recommended for TTL support
'python-digitalocean>=1.15.0', # 1.15.0 or newer is recommended for TTL support
]
if os.environ.get('SNAP_BUILD'):

View file

@ -68,6 +68,7 @@ test = [
"types-pywin32",
"types-requests",
"types-setuptools",
"uv",
"wheel",
]
all = [

View file

@ -33,7 +33,7 @@ install_requires = [
'distro>=1.0.1',
'importlib_metadata>=8.6.1; python_version < "3.10"',
'josepy>=2.0.0',
'parsedatetime>=2.4',
'parsedatetime>=2.6',
'pyrfc3339',
# This dependency needs to be added using environment markers to avoid its
# installation on Linux.

View file

@ -0,0 +1 @@
Added `uv` as a test dependency, and switched most `pip` invocations to `uv pip` for faster installs.

View file

@ -15,7 +15,7 @@ cloudflare==2.19.0 ; python_version == "3.10"
colorama==0.4.6 ; (sys_platform == "win32" or platform_system == "Windows") and python_version == "3.10"
configargparse==1.5.3 ; python_version == "3.10"
configobj==5.0.6 ; python_version == "3.10"
coverage==7.10.3 ; python_version == "3.10"
coverage==7.10.4 ; python_version == "3.10"
cryptography==43.0.0 ; python_version == "3.10"
cython==0.29.37 ; python_version == "3.10"
dill==0.4.0 ; python_version == "3.10"
@ -25,9 +25,8 @@ dns-lexicon==3.15.1 ; python_version == "3.10"
dnspython==2.6.1 ; python_version == "3.10"
exceptiongroup==1.3.0 ; python_version == "3.10"
execnet==2.1.1 ; python_version == "3.10"
filelock==3.18.0 ; python_version == "3.10"
filelock==3.19.1 ; python_version == "3.10"
funcsigs==0.4 ; python_version == "3.10"
future==1.0.0 ; python_version == "3.10"
google-api-python-client==1.6.5 ; python_version == "3.10"
google-auth==2.16.0 ; python_version == "3.10"
httplib2==0.9.2 ; python_version == "3.10"
@ -38,13 +37,14 @@ isort==6.0.1 ; python_version == "3.10"
jmespath==0.10.0 ; python_version == "3.10"
josepy==2.1.0 ; python_version == "3.10"
jsonlines==4.0.0 ; python_version == "3.10"
jsonpickle==4.1.1 ; python_version == "3.10"
mccabe==0.7.0 ; python_version == "3.10"
mypy-extensions==1.1.0 ; python_version == "3.10"
mypy==1.17.1 ; python_version == "3.10"
ndg-httpsclient==0.3.2 ; python_version == "3.10"
oauth2client==4.1.3 ; python_version == "3.10"
packaging==25.0 ; python_version == "3.10"
parsedatetime==2.4 ; python_version == "3.10"
parsedatetime==2.6 ; python_version == "3.10"
pathspec==0.12.1 ; python_version == "3.10"
pbr==1.8.0 ; python_version == "3.10"
pip==25.2 ; python_version == "3.10"
@ -66,14 +66,14 @@ pytest-xdist==3.8.0 ; python_version == "3.10"
pytest==8.4.1 ; python_version == "3.10"
python-augeas==0.5.0 ; python_version == "3.10"
python-dateutil==2.9.0.post0 ; python_version == "3.10"
python-digitalocean==1.11 ; python_version == "3.10"
python-digitalocean==1.15.0 ; python_version == "3.10"
pytz==2025.2 ; python_version == "3.10"
pywin32==311 ; python_version == "3.10" and sys_platform == "win32"
pyyaml==6.0.2 ; python_version == "3.10"
requests-file==2.1.0 ; python_version == "3.10"
requests==2.25.1 ; python_version == "3.10"
rsa==4.9.1 ; python_version == "3.10"
ruff==0.12.8 ; python_version == "3.10"
ruff==0.12.9 ; python_version == "3.10"
s3transfer==0.5.2 ; python_version == "3.10"
setuptools==80.9.0 ; python_version == "3.10"
six==1.16.0 ; python_version == "3.10"
@ -92,5 +92,6 @@ types-urllib3==1.26.25.14 ; python_version == "3.10"
typing-extensions==4.14.1 ; python_version == "3.10"
uritemplate==3.0.1 ; python_version == "3.10"
urllib3==1.26.5 ; python_version == "3.10"
uv==0.8.11 ; python_version == "3.10"
virtualenv==20.34.0 ; python_version == "3.10"
wheel==0.45.1 ; python_version == "3.10"

View file

@ -72,7 +72,7 @@ httplib2 = "0.9.2"
idna = "2.6"
ipaddress = "1.0.16"
ndg-httpsclient = "0.3.2"
parsedatetime = "2.4"
parsedatetime = "2.6"
pbr = "1.8.0"
ply = "3.4"
pyOpenSSL = "25.0.0"
@ -81,7 +81,7 @@ pyasn1 = "0.4.8"
pycparser = "2.14"
pyparsing = "2.4.7"
python-augeas = "0.5.0"
python-digitalocean = "1.11"
python-digitalocean = "1.15.0"
requests = "2.25.1"
six = "1.16.0"
urllib3 = "1.26.5"

View file

@ -28,6 +28,10 @@ def call_with_print(command, env):
subprocess.check_call(command, shell=True, env=env)
def uv_install_with_print(args_str, env):
command = ['"', sys.executable, '" -m uv pip install ', args_str]
call_with_print(''.join(command), env=env)
def pip_install_with_print(args_str, env):
command = ['"', sys.executable, '" -m pip install --disable-pip-version-check --use-pep517 ', args_str]
call_with_print(''.join(command), env=env)
@ -49,19 +53,21 @@ def pip_constrained_environ():
# are also used when installing build dependencies. See
# https://github.com/certbot/certbot/pull/8443 for more info.
env["PIP_CONSTRAINT"] = constraints_path
env["UV_CONSTRAINT"] = constraints_path
env["UV_BUILD_CONSTRAINT"] = constraints_path
return env
def pipstrap(env=None):
if env is None:
env = pip_constrained_environ()
pip_install_with_print('pip setuptools wheel', env=env)
pip_install_with_print('pip setuptools wheel uv', env=env)
def main(args):
env = pip_constrained_environ()
pipstrap(env)
pip_install_with_print(' '.join(args), env=env)
uv_install_with_print(' '.join(args), env=env)
if __name__ == '__main__':

View file

@ -17,8 +17,8 @@ babel==2.17.0 ; python_version >= "3.10" and python_version < "4.0"
backports-tarfile==1.2.0 ; python_version >= "3.10" and python_version < "3.12"
bcrypt==4.3.0 ; python_version >= "3.10" and python_version < "4.0"
beautifulsoup4==4.13.4 ; python_version >= "3.10" and python_version < "4.0"
boto3==1.40.8 ; python_version >= "3.10" and python_version < "4.0"
botocore==1.40.8 ; python_version >= "3.10" and python_version < "4.0"
boto3==1.40.11 ; python_version >= "3.10" and python_version < "4.0"
botocore==1.40.11 ; python_version >= "3.10" and python_version < "4.0"
build==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
cachecontrol==0.14.3 ; python_version >= "3.10" and python_version < "4.0"
cachetools==5.5.2 ; python_version >= "3.10" and python_version < "4.0"
@ -32,7 +32,7 @@ cloudflare==2.19.4 ; python_version >= "3.10" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0"
configargparse==1.7.1 ; python_version >= "3.10" and python_version < "4.0"
configobj==5.0.9 ; python_version >= "3.10" and python_version < "4.0"
coverage==7.10.3 ; python_version >= "3.10" and python_version < "4.0"
coverage==7.10.4 ; python_version >= "3.10" and python_version < "4.0"
crashtest==0.4.1 ; python_version >= "3.10" and python_version < "4.0"
cryptography==45.0.6 ; python_version >= "3.10" and python_version < "4.0"
cython==0.29.37 ; python_version >= "3.10" and python_version < "4.0"
@ -49,11 +49,11 @@ exceptiongroup==1.3.0 ; python_version == "3.10"
execnet==2.1.1 ; python_version >= "3.10" and python_version < "4.0"
executing==2.2.0 ; python_version >= "3.10" and python_version < "4.0"
fabric==3.2.2 ; python_version >= "3.10" and python_version < "4.0"
fastjsonschema==2.21.1 ; python_version >= "3.10" and python_version < "4.0"
filelock==3.18.0 ; python_version >= "3.10" and python_version < "4.0"
fastjsonschema==2.21.2 ; python_version >= "3.10" and python_version < "4.0"
filelock==3.19.1 ; python_version >= "3.10" and python_version < "4.0"
findpython==0.6.3 ; python_version >= "3.10" and python_version < "4.0"
google-api-core==2.25.1 ; python_version >= "3.10" and python_version < "4.0"
google-api-python-client==2.178.0 ; python_version >= "3.10" and python_version < "4.0"
google-api-python-client==2.179.0 ; python_version >= "3.10" and python_version < "4.0"
google-auth-httplib2==0.2.0 ; python_version >= "3.10" and python_version < "4.0"
google-auth==2.40.3 ; python_version >= "3.10" and python_version < "4.0"
googleapis-common-protos==1.70.0 ; python_version >= "3.10" and python_version < "4.0"
@ -101,7 +101,7 @@ packaging==25.0 ; python_version >= "3.10" and python_version < "4.0"
paramiko==4.0.0 ; python_version >= "3.10" and python_version < "4.0"
parsedatetime==2.6 ; python_version >= "3.10" and python_version < "4.0"
parso==0.8.4 ; python_version >= "3.10" and python_version < "4.0"
pbs-installer==2025.8.8 ; python_version >= "3.10" and python_version < "4.0"
pbs-installer==2025.8.14 ; python_version >= "3.10" and python_version < "4.0"
pexpect==4.9.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform != "win32" and sys_platform != "emscripten"
pip==25.2 ; python_version >= "3.10" and python_version < "4.0"
pkginfo==1.12.1.2 ; python_version >= "3.10" and python_version < "4.0"
@ -113,7 +113,7 @@ poetry-plugin-export==1.9.0 ; python_version >= "3.10" and python_version < "4.0
poetry==2.1.4 ; python_version >= "3.10" and python_version < "4.0"
prompt-toolkit==3.0.51 ; python_version >= "3.10" and python_version < "4.0"
proto-plus==1.26.1 ; python_version >= "3.10" and python_version < "4.0"
protobuf==6.31.1 ; python_version >= "3.10" and python_version < "4.0"
protobuf==6.32.0 ; python_version >= "3.10" and python_version < "4.0"
ptyprocess==0.7.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform != "win32" and sys_platform != "emscripten"
pure-eval==0.2.3 ; python_version >= "3.10" and python_version < "4.0"
pyasn1-modules==0.4.2 ; python_version >= "3.10" and python_version < "4.0"
@ -147,7 +147,7 @@ rfc3986==2.0.0 ; python_version >= "3.10" and python_version < "4.0"
rich==14.1.0 ; python_version >= "3.10" and python_version < "4.0"
roman-numerals-py==3.1.0 ; python_version >= "3.11" and python_version < "4.0"
rsa==4.9.1 ; python_version >= "3.10" and python_version < "4.0"
ruff==0.12.8 ; python_version >= "3.10" and python_version < "4.0"
ruff==0.12.9 ; python_version >= "3.10" and python_version < "4.0"
s3transfer==0.13.1 ; python_version >= "3.10" and python_version < "4.0"
secretstorage==3.3.3 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "linux"
semantic-version==2.10.0 ; python_version >= "3.10" and python_version < "4.0"
@ -186,10 +186,11 @@ types-setuptools==80.9.0.20250809 ; python_version >= "3.10" and python_version
typing-extensions==4.14.1 ; python_version >= "3.10" and python_version < "4.0"
uritemplate==4.2.0 ; python_version >= "3.10" and python_version < "4.0"
urllib3==2.5.0 ; python_version >= "3.10" and python_version < "4.0"
uv==0.8.11 ; python_version >= "3.10" and python_version < "4.0"
virtualenv==20.32.0 ; python_version >= "3.10" and python_version < "4.0"
wcwidth==0.2.13 ; python_version >= "3.10" and python_version < "4.0"
wheel==0.45.1 ; python_version >= "3.10" and python_version < "4.0"
wrapt==1.17.3 ; python_version >= "3.10" and python_version < "4.0"
xattr==1.2.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "darwin"
zipp==3.23.0 ; python_version >= "3.10" and python_version < "3.12"
zstandard==0.23.0 ; python_version >= "3.10" and python_version < "4.0"
zstandard==0.24.0 ; python_version >= "3.10" and python_version < "4.0"