#pip
1 messages Β· Page 2 of 1
Oh, I agree. :)
It's... Well, institutions want it for compliance reasons so that governments don't fine them about it. And, IMO volunteers shouldn't be responsible for too much stuff around them and moving "costs" of that on those institutions (which ideally handle this by supporting the upstream foundational infra). π
I agree with that! I'm mostly poking around if there's already been thinking about anything related wrt installers (or whether the project could become something that's under PyPA, or completely separate). I'm kinda taking pip-audit as the closest comparison, but noting that indeed SBOMs are likely to be of less utility to non-institutional open source users than vulnerabilities. I think there's still value in having a tool that does this work be close to the body that creates the standards for packaging.
100%
One of my hopes is that the whole packaging governance story settles with some reasonable body for people to throw money toward these PyPA projects.
That would be an excellent outcome indeed! Has anyone talked to PSF about that?
In what form?
Just about ways to help make that a reality. I know PSF does fiscal hosting for some OSS projects already.
PyPA is a fiscal sponsoree already.
The issue is the lack of unified direction (part of the motivation for a unified packaging vision).
Gotcha
And, there's also a Packaging-WG
who handles the funds IIUC.
Not sure I fully understand the relationship between the PyPA pool and the packaging-WG pool. OTOH, I don't really care enough to find out the details about it.
I remember reading a discuss thread about a Packaging Council awhile ago.
Is that the body that would ultimately be responsible for this?
That's my hope.
There's no answer on what the packaging council would be ultimately responsible for atm, because it's still just an idea so it has to get officially proposed and decided on... but I think the general consensus of what I've seen is that body would ultimately be responsible for these kind of ecosystem wide vision / scope decisions
$ pip install django
Collecting django
Obtaining dependency information for django from https://files.pythonhosted.org/packages/d4/83/227ebf197e413f3599cea96dddc7d6b8ff220310cc5b40dd0f1a15e5a9d1/Django-4.2.3-py3-none-any.whl.metadata
Just noticed the metadata file for the first time. OMG, it's cool!
does anyone know why pip's resolver would error out with
ERROR: Could not find a version that satisfies the requirement jax[tpu]==0.4.14 (from redacted) (from versions: 0.0, 0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.1.9, 0.1.10, 0.1.11, 0.1.12, 0.1.13, 0.1.14, 0.1.15, 0.1.16, 0.1.18, 0.1.19, 0.1.20, 0.1.21, 0.1.22, 0.1.23, 0.1.24, 0.1.25, 0.1.26, 0.1.27, 0.1.28, 0.1.29, 0.1.30, 0.1.31, 0.1.32, 0.1.33, 0.1.34, 0.1.35, 0.1.36, 0.1.37, 0.1.38, 0.1.39, 0.1.40, 0.1.41, 0.1.42, 0.1.43, 0.1.44, 0.1.45, 0.1.46, 0.1.47, 0.1.48, 0.1.49, 0.1.50, 0.1.51, 0.1.52, 0.1.53, 0.1.54, 0.1.55, 0.1.56, 0.1.57, 0.1.58, 0.1.59, 0.1.60, 0.1.61, 0.1.62, 0.1.63, 0.1.64, 0.1.65, 0.1.66, 0.1.67, 0.1.68, 0.1.69, 0.1.70, 0.1.71, 0.1.72, 0.1.73, 0.1.74, 0.1.75, 0.1.76, 0.1.77, 0.2.0, 0.2.1, 0.2.2, 0.2.3, 0.2.4, 0.2.5, 0.2.6, 0.2.7, 0.2.8, 0.2.9, 0.2.10, 0.2.11, 0.2.12, 0.2.13, 0.2.14, 0.2.15, 0.2.16, 0.2.17, 0.2.18, 0.2.19, 0.2.20, 0.2.21, 0.2.22, 0.2.23, 0.2.24, 0.2.25, 0.2.26, 0.2.27, 0.2.28, 0.3.0, 0.3.1, 0.3.2, 0.3.3, 0.3.4, 0.3.5, 0.3.6, 0.3.7, 0.3.8, 0.3.9, 0.3.10, 0.3.11, 0.3.12, 0.3.13, 0.3.14, 0.3.15, 0.3.16, 0.3.17, 0.3.18, 0.3.19, 0.3.20, 0.3.21, 0.3.22, 0.3.23, 0.3.24, 0.3.25, 0.4.0, 0.4.1, 0.4.2, 0.4.3, 0.4.4, 0.4.5, 0.4.6, 0.4.7, 0.4.8, 0.4.9, 0.4.10, 0.4.11, 0.4.12, 0.4.13, 0.4.14)
Traceback (most recent call last):
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 316, in _backjump
name, candidate = broken_state.mapping.popitem()
KeyError: 'dictionary is empty'
for bonus fun, this only happens when running pip-compile; pip install with the exact same requirement works fine π
(@shy echo I guess)
I've tested on macOS/py310 with latest pip-tools, "works on my machine":
$ echo jax[tpu]==0.4.14 | pip-compile -qo- \
--no-header --no-annotate --no-emit-options --no-strip-extras \
--find-links https://storage.googleapis.com/jax-releases/libtpu_releases.html
jax[tpu]==0.4.14
jaxlib==0.4.14
libtpu-nightly==0.1.dev20230727
ml-dtypes==0.2.0
numpy==1.25.2
opt-einsum==3.3.0
scipy==1.11.1
Do you have a reproducible example? It would be nice if you could report a bug on the pip-tools' bug tracker.
unfortunately my only reproducer right now requires running pip-compile on not only our entire monorepo, but also using our current set of pins as the base versions π¦ I've got hypothesis running to try to trim that down, but no luck so far
Interesting... Shouldn't try-except (IndexError, KeyError) catch KeyError?
Traceback (most recent call last):
name, candidate = broken_state.mapping.popitem()
KeyError: 'dictionary is empty'
yeah, the traceback continues as
Traceback (most recent call last):
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 316, in _backjump
name, candidate = broken_state.mapping.popitem()
KeyError: 'dictionary is empty'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 92, in resolve
result = self._result = resolver.resolve(
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 546, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 434, in resolve
success = self._backjump(causes)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 318, in _backjump
raise ResolutionImpossible(causes)
pip._vendor.resolvelib.resolvers.ResolutionImpossible: [RequirementInformation(requirement=SpecifierRequirement('jax[tpu]==0.4.14'), parent=EditableCandidate('file:///root/code/redacted'))]
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/root/.pyenv/versions/3.10.11/bin/pip-compile", line 8, in <module>
sys.exit(cli())
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/click/decorators.py", line 33, in new_func
return f(get_current_context(), *args, **kwargs)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/piptools/scripts/compile.py", line 592, in cli
results = resolver.resolve(max_rounds=max_rounds)
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/piptools/resolver.py", line 593, in resolve
is_resolved = self._do_resolve(
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/piptools/resolver.py", line 625, in _do_resolve
resolver.resolve(
File "/root/.pyenv/versions/3.10.11/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 101, in resolve
raise error from e
pip._internal.exceptions.DistributionNotFound: No matching distribution found for jax[tpu]==0.4.14
I don't think there's any additional information content in that part though
The KeyError is an implementation detail in resolvelib that basically means it has exhausted all possibilities. That exception is caught inside resolvelib to reraise ResolutionImpossible to indicate the direct cause and users should catch that to display relevant messages. From the above I think piptools fails to catch and handle an exception raised along the stack
i made the keyerror not be reported in https://github.com/sarugaku/resolvelib/pull/133
However, it seems odd that it fails to find the package, even though version 0.4.14 is available according to the log:
ERROR: Could not find a version that satisfies the requirement jax[tpu]==0.4.14 ... (from versions: ..,, 0.4.14)
I wouldn't be surprised if there's some sort of state corruption affecting the resolve here.
I mean even the latter two exceptions should not have been shown either (even if the package should not be found), and combining with the fact that pip does find a solution (indicating the package is obviously found to satisfy it) means this is really 100% on pip-tools and nowhere else
eventually my workaround was to... go in and manually copy the new requirements I was passing to pip-compile into the old pins file, and that turned out to be a valid resolution. total diff -3 +3.
no idea how pip-compile was screwing that up
If you can dump state and write the output somewhere with PIP_RESOLVER_DEBUG=1 (making appropriate redactions), that could be useful diagnosis logs.
@keen summit what did the pins look like when you run pip-compile and it failed?
with the requirement of <5% installs on EOL python versions, isn't that going to be quite difficult to achieve because newer non-EOL python versions bundle latest pip?
I'm not sure I follow your thinking here.
I think the line of thinking is that since non-EOL Python comes with the latest pip, those environments won't need to install pip as frequently as one based on an EOL Python version, causing the EOL versions to be overrepresented in the install statistics.
I don't buy that. pip is upgraded constantly regardless of the Python version
Yeah that's what I'm thinking
the 3.7 proportion for pip isn't much different compared to other packages
pip:
ββββββββββββ¬ββββββββββ¬ββββββββββββββ
β category β percent β downloads β
ββββββββββββΌββββββββββΌββββββββββββββ€
β 3.7 β 24.17% β 39,846,601 β
β 3.9 β 19.77% β 32,590,855 β
β 3.8 β 19.19% β 31,647,764 β
β 3.10 β 13.60% β 22,416,844 β
β 2.7 β 8.90% β 14,682,014 β
β 3.6 β 5.25% β 8,649,690 β
β 3.11 β 5.20% β 8,579,509 β
β null β 3.53% β 5,817,611 β
β 3.5 β 0.26% β 420,770 β
β 3.4 β 0.09% β 155,353 β
β 3.12 β 0.05% β 75,603 β
β 3.13 β 0.00% β 998 β
β 3.3 β 0.00% β 822 β
β 3.2 β 0.00% β 355 β
β 2.6 β 0.00% β 2 β
β 3.1 β 0.00% β 2 β
β 4.0 β 0.00% β 1 β
β Total β β 164,884,794 β
ββββββββββββ΄ββββββββββ΄ββββββββββββββ
setuptools:
ββββββββββββ¬ββββββββββ¬ββββββββββββββ
β category β percent β downloads β
ββββββββββββΌββββββββββΌββββββββββββββ€
β 3.7 β 19.78% β 53,635,167 β
β 3.8 β 19.66% β 53,311,659 β
β 2.7 β 15.75% β 42,709,012 β
β 3.9 β 13.87% β 37,612,549 β
β 3.10 β 13.52% β 36,680,128 β
β 3.11 β 6.40% β 17,367,188 β
β null β 5.77% β 15,661,435 β
β 3.6 β 5.02% β 13,605,348 β
β 3.5 β 0.17% β 470,967 β
β 3.12 β 0.05% β 131,666 β
β 3.4 β 0.01% β 34,022 β
β 3.13 β 0.00% β 3,650 β
β 3.3 β 0.00% β 1,125 β
β 3.2 β 0.00% β 283 β
β 2.6 β 0.00% β 81 β
β 3.1 β 0.00% β 1 β
β Total β β 271,224,281 β
ββββββββββββ΄ββββββββββ΄ββββββββββββββ
urllib3:
ββββββββββββ¬ββββββββββ¬ββββββββββββββ
β category β percent β downloads β
ββββββββββββΌββββββββββΌββββββββββββββ€
β 3.7 β 31.16% β 110,540,942 β
β 3.8 β 19.04% β 67,558,918 β
β 3.9 β 15.23% β 54,025,932 β
β 3.10 β 11.69% β 41,458,651 β
β 3.6 β 7.58% β 26,891,708 β
β 3.11 β 7.12% β 25,246,114 β
β 2.7 β 4.32% β 15,308,015 β
β null β 3.54% β 12,557,543 β
β 3.5 β 0.17% β 602,821 β
β 3.4 β 0.14% β 487,594 β
β 3.12 β 0.02% β 76,309 β
β 3.13 β 0.00% β 3,362 β
β 3.3 β 0.00% β 678 β
β 3.2 β 0.00% β 27 β
β 2.6 β 0.00% β 12 β
β 3.1 β 0.00% β 3 β
β Total β β 354,758,629 β
ββββββββββββ΄ββββββββββ΄ββββββββββββββ
These would be based on what client is used to send download requests to PyPI as a whole, so there's that.
Beyond that, the rationale for this has been to avoid ending up in a situation where we have a substantial number of users who can't be accommodated to by a new release -- packaging tooling needs to be generous in the support cycles rather than aggressive.
(which, as folks here might know, is something that I don't enjoy and actively push back on at every opportunity)
3.7 is ludicrously popular
pydantic are ignoring Amazon Linux installs as that seems to be the source of large numbers of 3.7 installs
Yea, we might do something like that. I don't have time at the moment to look into what the usage patterns are and what we should be doing here.
20% is Amazon Linux on 3.7!
(just 1 day's data to save some quota, but still covers 4.5m downloads)
That's 20% of PyPI downloads as a whole?
for downloads of pip
for downloads of all packages:
Ubuntu on 3.8 = 18%
Amazon Linux on 3.7 = 15%
(
β― pypinfo --days 1 --limit 100 --percent "" system distro pyversion
Served from cache: False
Data processed: 44.29 GiB
Data billed: 44.29 GiB
Estimated cost: $0.22
)
Thanks for running that!
@stuck girder Could you publish that data somewhere? I think it will be useful for folks who are making version support decisions.
Because TIL Amazon Linux is causing a big percentage of 3.7 downloads.
sure!
Perfect, thank you!
The PSF is a CNA (covering pip!) π₯³ https://pyfound.blogspot.com/2023/08/psf-authorized-as-cna.html
Awesome!
is it possible to get a wheel for a particular package from the cache?
You can query the cache by running pip cache subcommands IIRC.
I tried but was missing the format argument, thanks!
pip cache list --format abspath PACKAGE
do I get it right, that pip's dependency resolver only takes into consideration packages passed in CLI call? It doesn't inspect the environment for the packages that are already installed?
yes
and that works with requirements files too?
correct
Only caveat is if any of the packages are already installed, pip makes its best effort to prefer the installed version
While I'm here, I want to highlight this issue: https://github.com/pypa/pip/issues/7863#issuecomment-1741723512
It's about pip download not downloading build depdencies, which currently makes it impossible to automate pre-collecting wheels and source tarballs for offline build environments.
I spent 4h yesterday while building my Flatpak to manually gather all the build dependencies.
Now that more and more packages are switching to PEP517/PEP518 maintaining Flatpaks (which need to be built in an offline environment) is becoming an absolute nightmare, and I was a bit surprised no other Flatpak maintainer seems to really have raised this issue to the pip team yet.
I would love to personally work on implementing this, however a previous comment on the issue (3 years ago) suggested bigger architectural changes would be needed. Is that still the case?
Yea, I don't think it's a giant refactor but it's definitely a decent amount of work to improve this.
would alternatively a separate command for that be an option?
I don't think that's going to solve things, and making it opt-in via an option is definitely an option if you wanna go down that route.
Yeah, opt in via CLI arg / config would be my vote
And, no, a new command wouldn't be viable unless there's a strong case for it.
Iβve long wanted to steal a resolver that could power this for bandersnatch to auto resolve dependencies for people if it was ever βpublicallyβ available as itβs been requested many many times
There's some work being done on https://github.com/brettcannon/mousebender/issues/105 for this (I'd appreciate it if folks don't add noise over there -- my sense is that's where Brett's keeping his notes on the work publicly, and I already feel somewhat guilty about poking it with resolvelib details multiple times). π
--only-build-deps flag is on the table
If you can afford a CLI approach, pip install --quiet --dry-run --ignore-installed --report - essentially exposes the pip resolver.
Not yet indeed but I'd consider that in scope.
Yea, same.
Huh, wonder if pip-compile could make use of that.
Looks like @jovial jasper and I have collectively DOS'd out GitHub Actions worker queues for the pypa. Sorry folks! π
hi! i installed py3.12 from the ms store on win11 and trying to pip install opentypespec inside a fresh venv with only current pip fails because No module named 'distutils'. it works in a linux venv... am i overlooking something?
Check if opentypespec doesn't use distutils. If so, you should report it in the project repository
they have a setup.py and no pyproject.toml, but no direct use of distutils
even if i put in a proper pyproj toml (and remove setup.*), it still fails, but only on windows
Weird. My guess would be that python version you are using is weird. MS store python is always causing weird issues
(At least in my experience)
that's what i suspect
https://stackoverflow.com/ is a good place to ask this question, such that the answer to it isn't buried behind a non-indexable page. Consider posting the entire traceback with reproducer instructions there?
hm π ok will do after trying with the python.org version
ugh, same error
if i install setuptools in the venv, i at least get
ERROR: Can not execute
setup.pysince setuptools is not available in the build environment.
Important deprecations, removals or restrictions:
- gh-95299: Do not pre-install setuptools in virtual environments created with venv. This means that distutils, setuptools, pkg_resources, and easy_install will no longer available by default; to access these run pip install setuptools in the activated virtual environment.

yeah i saw that. the venv was created with virtualenv 20.24.5 though: virtualenv --python 3.12
the last part of the stack trace is
File "C:\Users\...\AppData\Local\Temp\pip-build-env-11pb36vg\overlay\Lib\site-packages\setuptools\__init__.py", line 8, in <module>
import distutils.core
ModuleNotFoundError: No module named 'distutils'
so that's why i came here to ask before filing an issue π
Setuptools is vendoring distutils in some hacky way, maybe it stopped working for some reason
https://github.com/pypa/pip/issues/12200 yeah this is the one
oh DUH. i had a SETUPTOOLS_USE_DISTUTILS=stdlib env var lying around from years ago
#yetAnotherUserError
FYI a bug on PyPy https://github.com/pypa/pip/issues/12326
does anyone know how the state of a package's metadata could break installation like this?
is this a cache bug? where is it? 
β― pip install -UI cryptography
Collecting cryptography
Obtaining dependency information for cryptography from https://files.pythonhosted.org/packages/d7/78/29d8332bebfe3c2d49a63fb23e1c9fc73a13507b5206b98479fda04c993b/cryptography-41.0.4-cp37-abi3-win_amd64.whl.metadata
Using cached cryptography-41.0.4-cp37-abi3-win_amd64.whl.metadata (5.3 kB)
Collecting cffi>=1.12 (from cryptography)
Obtaining dependency information for cffi>=1.12 from https://files.pythonhosted.org/packages/5a/c7/694814b3757878b29da39bc2f0cf9d20295f4c1e0a0bde7971708d5f23f8/cffi-1.16.0-cp311-cp311-win_amd64.whl.metadata
Using cached cffi-1.16.0-cp311-cp311-win_amd64.whl.metadata (1.5 kB)
Collecting pycparser (from cffi>=1.12->cryptography)
Using cached pycparser-2.21-py2.py3-none-any.whl (118 kB)
Using cached cryptography-41.0.4-cp37-abi3-win_amd64.whl (2.7 MB)
Using cached cffi-1.16.0-cp311-cp311-win_amd64.whl (181 kB)
Installing collected packages: pycparser, cffi, cryptography
Successfully installed cffi-1.15.1 cryptography-41.0.4 pycparser-2.21
β― pip cache list --format abspath cryptography
β―
pip cache currently only reads the wheel cache (cache storing wheels implicitly built by pip from source), not the network cache.
oh okay I was very confused. I found a way to get all of the wheels which is to just pip download and it won't hit network since everything is cached
I briefly got extremely excited about ABI and platform override options thinking everything finally got implemented until I expanded the caveat π
I'm quite happy about the new HTTP cache.
Is it just internal rewrite or did you switch to another library?
I think it's just a different backend from the same library.
I will need to have a look π
pip and pipx together are giving me a catch-22: I have a freshly installed ubuntu 23.10 and with python3-pip additionally installed. If i try to install anything with pip it tells me (correctly) "error: externally-managed-environment" "If you wish to install a non-Debian packaged Python application, it may be easiest to use pipx install xyz, which will manage avirtual environment for you. Make sure you have pipx installed.". Sure! I go to https://pypa.github.io/pipx/ and it tells me to run python3 -m pip install --user pipx which again leads to the aforementioned error message. It also tells me to try installing python3-xyz where xyz is the name of the package, but python3-pipx doesn't exist either
(i'm not sure what the right bootstrapping strategy here is, but i expect this loop to very confusing to newcomers)
FWIW, the Ubuntu package is just called pipx: https://packages.ubuntu.com/mantic/pipx
There's python-pipx as well
Yeah, pipx should definitely explain how to be installed using package managers before pip. Global tools like this should just be on your system once, managed and autoupdated by a package manager.
I agree that it's best to install pipx through package manager if that's possible on your system. Otherwise, https://pypi.org/project/pipx-in-pipx/ is the second best option
personally I do something like that on Windows (which doesn't have a package), just in a manual way
I do an equivalent of this:
venv_dir=$(mktemp -d)
python -m venv "$venv_dir"
"$venv_dir/bin/python" -m pip install pipx
"$venv_dir/bin/pipx" install pipx --python python3 --include-deps
rm -rf "$venv_dir"
python3 is the actual executable that you want it to use
so that it doesn't point at venv
the downside is that it's per-user install
but it is managed by pipx at least
and you get the latest version unlike with non-rolling distros
pipx-in-pipx is terrifying.
why?
It pretends to be a Python package, but actually does weird stuff to your machine.
I think it would make more sense as just a script.
I thought about rewriting pipx in rust or go, but the venv needs some sys/sysconfig stuff and I didn't dig deep enough to find out how to get that info without subprocessing to python
is there a way for pip freeze to emit hashes? I can't find an option
don't think so currently, could bump this old issue https://github.com/pypa/pip/issues/4732
ah thanks!
What hashes would it emit? It doesn't have access to the original packages.
the same way pip-tools does, I suppose?
I would think pip needs to start tracking that during install, only work on cached wheels, or deny this as a feature of pip freeze. but it's been a long open issue, with some of that already mentioned in there and (at least outside looking in) no progress towards any of those or other options made.
pip-tools (compile) resolves packages to do it, so simply doing what pip-tools does could have surprising results in some cases since freeze should reflect what is installed. (for instance, what if the local package was installed from sdist+patches that didn't modify the version? This is different from just an sdist or wheel, and should not match hashes.)
I would assume it uses cached wheels but there may be some edge cases I'm not considering
There might not be any cached wheels.
Even if there is, most backends donβt build wheels with reproducible hashes so the freeze result would not be particularly useful except for recreating the environment on the exact same machine.
recreating the environment on the exact same machine
that is my current use case at work actually
I wonder if itβd be better to have a way to locally clone an environment. That would work whenever the freeze-with-hash method work and would not work if any of the packages canβt be built into a wheel (which would make the hash method not work anyway)
The edge case where cloning an environment would not work is if any of the installed file is not relocatable (e.g. badly built dll, but also any other build-time generated file that depends on more than just the relative paths inside the environment). But wheels cannot contain such non-relocatable files in the first place, so those must have been built from source instead. Not supporting sdist (or plain source trees) seems like an acceptable trade-off.
would not work if any of the packages canβt be built into a wheel
how is that possible since installation requires a wheel to be built in all cases?
I mostly agree which is why I do that manually on my computers when I need to
But figured I shouldn't be omitting it as an option
Canβt be built into a good wheel I guess. A wheel would be produced but that wheel will only work for that one environment.
FWIW, I don't think installed projects have to come from wheels. They could be installed by some alternative installer.
the problem effectively becomes that there's no guarentee that "foo-1.0" in an environment matches any particular artifact for foo-1.0 that exists anywhere on the system
there is a PEP to add some provenance info that would enable this, but I think the state of that PEP languished after the author changed jobs
but I could be wrong on that, I'm not nearly as good as following all the discussions anymore
No, since there's no distribution files to generate the hashes of.
my workaround currently is to freeze, download wheels to a directory from an existing environment, get the hash of each wheel, then inject into the output from the freeze command
You could also do a pip install --dry-run --report to get the artifact hashes.
(throwing in the output of the freeze into it)
plus our own package index for wheels that we have to build ourselves, for example we require CentOS 6 still
Ooof.
we are in a unique situation in which the infra is out of our control and determined by whatever customers use
I wish lol
"OS too old, you are no longer permitted to be a customer"
my experience working on this has given me an incredible amount of respect for the engineers at Microsoft that maintain their backward compatibility guarantees
this is rough
https://github.com/pradyunsg/pip-resolver-benchmarks is a thing that came out of conversations at PackagingCon this year, about how Spack benchmarks their dependency resolution process on top of clingo et al.
Hi! I'm working on trying to add parallel download support to BatchDownloader. I've already opened one pull request to that effect, and am working on a separate pull request to add a proper progress bar for parallel downloads. I just wanted to make sure that, that sort of work is something that the pip project might actually want.
Hello hello!
I think that's useful still, yes.
I don't know though how much bandwidth people have to review a PR for this at the moment though, so all I can say is, a PR would be appreciated, please be patient with us and thanks for contributing! :)
Of course! I just wanted to make sure because I didn't want to waste the maintainers time with unwanted PR's
oh I just came here to post about the parallel download PR. I'm very excited for this!
anyone aware of a resolver debugging cheat-sheet - i have a case where a exact pin in a constraints file seems to be ignored and i get warnings about pip searching versions of botocore even tho a exact version is pinned
unfortunately i cant easily extract a demo reproducer yet and in the private case there's a few hundred packages involved and loads of backtracking/doom versioning
Could you try using pip-resolver-benchmarks to create a reproducer?
thanks for the sugestion, i jsut had pinned enoguh toplevel packages to lates that the resolves finally ran into the pathological case - for some reason i have a package that pinned urllib3==2.0.7 - i now added a new requirement that wil lhopefully find me the error
π€¦ someone had accidentally removed a python version pin for the locking process - i was locking my stuff with python3.11 on something that was running on python3.9 π±
π
worst of all , time is inappropriate for a disgustingly smoky glass of whiskey now that i know the issue
It's 4PM somewhere on Earth π
i have seen what happens to people that apply alcoholic timezone, its not pretty
Yeah, I know, I have it running in the family :/
my condolences , that one is a "gift" that keeps taking
What's the reason PEP 440 doesn't allow relative paths, but does allow absolute paths? I'm trying to understand why it was decided that way when PEP 440 was written
Naively, i'd have said that you need relative path for workspaces and vendored dependencies while absolute paths are the special, so i'm surprised the spec has it the other way round
I think #egg= didn't support relative paths at the time
Relatedly, does that mean that PEP 621 doesn't support relative paths at all atm?
I think so?
I'm currently working on editable installs (with the eventual goal of building some kind of workspace support) and i'm trying to figure out what the right semantics are
I've seen that pip expands environment variables in requirements.txt input https://github.com/pypa/pip/blob/aebc0c5fc321141ede837c80572427ab7b795c3f/src/pip/_internal/req/req_file.py#L503, which some people seem to use as a workaround (https://github.com/search?q=path%3Arequirements.txt+PWD&type=code)
sigh
is that a "that's not how you're meant to do that" sigh?
Hi! I think I'm running into https://github.com/pypa/pip/issues/11896 now that my company has rolled out some network configuration updates. IIUC the maintainers are potentially open to contributions related to this. Is that correct? I'm working with our networking team to better understand what's going on, so if I can upstream something I'd be happy to work on it.
The support typically comes from people like yourself, who have hit issues like this, worked out how to address them, and contribute advice back.
- https://github.com/pypa/pip/issues/11896#issuecomment-1813102579
I ask because the thread seems to go back and forth a little.
$ python -m pip debug --verbose 2>1 | rg 11_0
$ python -c 'import packaging.tags
for tag in packaging.tags.platform_tags():
print(tag)' | rg 11_0
macosx_11_0_x86_64
macosx_11_0_intel
macosx_11_0_fat64
macosx_11_0_fat32
macosx_11_0_universal2
macosx_11_0_universal
Why do packaging and pip disagree on my compatible tags?
different versions of packaging maybe?
2 theories:
- breaking changes between versions
- no one updated it
I think the first one is more plausible
it looks like greenlet is overwriting the platform tag as of v3.0.2 with the min supported macOS version being Big Sur (11.0): https://github.com/python-greenlet/greenlet/blob/edbdda27ab1983ac157b588dd0c04816cb31b0ea/.github/workflows/tests.yml#L67C36-L67C36
so anyone attempting to install greenlet on an Intel Mac will encounter this
IIUC upgrading packaging is blocked on the removal of legacy specifiers: https://github.com/pypa/pip/issues/11715
that is really quite unfortunate
Yeah it's really hard to upgrade packaging in pip without breaking the world. Last status in https://github.com/pypa/pip/pull/12300
I just realized this date is approaching https://hatch.pypa.io/1.9/config/metadata/#allowing-ambiguous-features
Does anyone know how long pip has supported this? I remember it was blocked on a vendor update to packaging but I don't remember how long ago that was.
The packaging upgrade has not happened yet, so if it was blocked on that, it'll still be blocked.
Heads up: I'll be away from the internet over the next bit, vacation time. π
that is certainly surprising, I could have sworn the update happened because it was over a year ago and at one point I stopped tracking it which I would have assumed meant it happened rather than I forgot about it...
found the tracking issue https://github.com/pypa/pip/issues/11715
(note the most recent comment saying that this would be required for nogil support)
is there anything a contributor such as myself could do to assist?
There's an open PR that does the code-base adaptations but we need to add tests and cover cases where the code used to fall back to legacy versions / specifiers and now raise errors -- and handle them gracefully.
Taking that PR forward would be welcome, if a bit non-trivial to put it mildly. π
And is there something blocking release of packaging that we could help with?
It's not a packaging release, it's a packaging upgrade in pip's vendored copy.
Hello, I took a look at the repo, I opened a super trivial single line PR
https://github.com/pypa/packaging/pull/752
I'd also be happy to help with whatever is necessary, but I've touched this project before, so I'd be slow
This is the relevant PR.
Right, for pip. But we also need a new packaging release so it can be vendored into wheel. This is currently blocking packages from being built for nogil free-threaded Python builds
Hmm, I'm running into a handful of test failures on a fresh clone of pip. I'm using a virtual environment based on a 3.11.7 install I compiled from source (manually). Any pointers to what may be causing these issues?
I think we have those in CI too. Haven't had time to investigate why/what changed.
I took a brief look at the pip repository and saw a green checkmark so I assumed that I'm dealing with a case of PEBKAC 
seems like normalization is at least partially at fault
that last test fail looks like bad case of normalization
spoke too late π
you sent your message the moment I pressed "send" lol
great minds think alike
although that may be an insult to your mind, haha
I'm not very clever
I could say the same π
It's an intermittent failure, or something that is being affected by a cache maybe?
Again, haven't looked closely beyond the notifications that our CI failed at some point and some PRs are red when they shouldn't have been.
normalization being affected by a cache sounds odd though
I mean, a setuptools release and a pre-created local dev environment will manifest as a non-reproducer.
Until you recreate the environment.
I presumed CI doesn't cache at all?
Trust, but verify.
Fair. I'll try to figure this out. Not exactly the way I envisioned how I'd start looking to contribute to pip, but oh well.
Thanks for the information, either way!
Sorry, but looking forward to your contributions.
And, as you know, feel welcome to ask questions here or on the issue tracker, with the issue tracker being preferred.
Richard's attempt at debugging test failures on a fresh pip clone
https://github.com/pypa/pip/pull/12454#issuecomment-1872445714 ... well it was setuptools, I am not surprised :)
Unblocking everyone's PRs is an excellent way to start contributing to pip, thank you!
Are egg-link filenames standardized anywhere?
pip is unable to detect certain egg-link files produced by setuptools 69.0.3 due to underscores which it now preserves
ah fun, so technically setuptools is violating the documentation
I'll investigate a bit more and report on GitHub.
Not that I'm aware of, no.
are eggs even relevant anymore?
Yeah, pkg_resources? Eggs? Unless you crawl old PyPI releases, you probably donβt want to engage with these.
Eggs no, but egg-link and egg-info still lives in legacy editables
FWIW, I'm waiting on someone to weigh in on https://github.com/pypa/setuptools/issues/4167 to be able to fix pip's CI
The easier solution would be if setuptools maintained the previous egg-link naming behaviour exibited by <=69.0.2, but I get the feeling the setuptools devs may not like that idea.
the fact that setuptools doesn't use major version number as a breaking changes identifier is an issue in my eyes... hard to change anything since there is always someone who depends on the legacy behavior
well it's setuptools, good luck changing anything
semvar will not save you :)
but yeah, definitely a risky change to add to a bugfix release
as much as I can appreciate the setuptools for years of service, I believe there has to be a do-over, a rewrite of the whole thing if it is to remain any kind of sane solution
but that's something for #setuptools I guess
I personally do not care for setuptools, I'm just trying to fix pip's CI
while I wait for progress on the setuptools issue, I'm tinkering with pip's improved error infrastructure. It's been lovely to work with, kudos @shy echo β¨
Nice!
I ran into this error specifically a fair bit while messing around with legacy editable installs (for some reason I do not feel like investigating...)
I've been meaning to backfill the whole set of errors, and I'm glad to hear that others also find it nice. :)
I forget if I ended up filing my PR that removed the [present-rich] hack.
Iβm not sure we want to make the suggestion. IIRC some package managers (RH?) deliberately remove RECORD so pip canβt accidentally uninstall a package it installs. Maybe we should make the message an info and add a documentation pacakge to explain the situation in more detail instead.
We make it already.
it feels like a nice balance between "is it easy to work on?" and "for hour spent on project, how much does it improve QOL?" task stats
Ichard the pip king these days π€©
i have literally filed only one documentation pr lol
Seen lots of chat. For some reason discord notifies me when you do β¦ no idea why
I think I only have 1 pip contribution too β¦
I dunno about a dedicated doc page for this -- I'm inclined to throw together the error index page/section and start bundling these into that.
Yeah. I was hesitant to use the "missing" verbage since no RECORD is a valid situation.
FWIW, the hint is different if the recorded installer is not pip.
Ah, good touch
(pssst, let's discuss the details when the PR is filed)
which will be tomorrow because I absolutely should not be up this late :P
it's too easy to get caught up in the terminal when you got something good going on
https://github.com/pypa/pip/pull/12304 you did, don't worry 
Good job past me, and thanks for finding that PR#!
Hey, I just realized that pip download actually runs setup.py and whatever arbitrary code is in there.
https://stackoverflow.com/questions/52486985/pip-download-without-executing-setup-py
I never thought about that and considered pip download safe to run, I thought it only downloaded some wheels. Just like how a browser download (like the "download" feature on PyPI) shouldn't be able to run any code.
Maybe there should be some warning about this in the --help of pip download, or in other places that introduce pip download?
pip download needs to run setup.py to figure out a wheel-less packageβs dependencies so it can download them too. There are --binary-only and/or --no-deps if thatβs what you want
(--no-deps runs the metadata generation too)
Yes, I understand why it needs to do that. It's just not obvious to a (casual?) user of Python that it executes arbitrary code form the internet, like install
I'd be on board for adding a warning, so please go ahead and file an issue for this (or a PR directly, if you're so inclined).
I'll make an issue π
https://github.com/pypa/pip/issues/12465
Please tell if there's a better way to phrase the issue
how can one define a path with spaces when using the PIP_FIND_LINKS environment variable?
mwahaha, I win
I'll comment on the issue as a potential workaround
Oh God
why would you put spaces in FS names...
in the case of C:\Program Files I have no choice π
windows is always a special child
true, but in fairness macOS also uses spaces
Library Framework or something like that
/Library/Application Support/
that's why (in this developer's eyes) linux is the one and only sane system
You can have spaces in a Linux file path too.
you can, but (AFAIK) there are none of those in default paths
Point being that the issue here isn't the os, but tools designed by devs that made assumptions about what was reasonable that didn't match the world, then people get into self re-enforcing loops of "just don't use spaces in a path" because of devs continuing to handle that wrong
This developer disagrees, pointing to his experience dealing with oh-all-the quirks that are distro specific.
that's pretty much my take on this as well. in this particular case, each OS already has a dedicated character for separating paths so it's unclear to me why spaces were used originally
There's also an argument to allow specifying the separator char as a separate env var to allow portable configuration since that char varies by os, but that's something you reach only after avoid space as a seperator
I may add my thoughts/possible pr later, need to think about it more, but I think an env var for custom separator and keeping the current broken behavior as default for compatibility may be a viable way forward on that
the context formatting of Hatch actually allows for the insertion of path separators in a portable way https://hatch.pypa.io/latest/config/context/#system-separators
(I would have chosen colon but that would conflict with string formatting syntax so everybody must use the Windows semicolon π )
in the case of C:\Program Files I have no choice
You do,C:\PROGRA~1(DOS compatibility FTW)
All Windows paths (on the local filesystem, not mounted) can be represented in a space-less format because a lot of MS-DOS softwares do not allow spaces in paths
But percent-escaping is the standard way to put URL-invalid characters in a URL. Not even a hack, thatβs just the way to do it.
My development directory in Linux is a path with a space in it. In the last 10 years or so, there was exactly one problem: a C library that refused to compile when I tried to set up a Ruff dev environment.
I reported it, it got fixed, and when I next tried to contribute to Ruff, there were 0 things in my life that were coded so badly that they broke on spaces.
Wait, there's line wrapping in the output?
haha
Do you have a reproducer?
I was just about to say... maybe there's not actually line wrapping
maybe it's stylistic formatting
I was looking at some output like
The conflict is caused by:
The user requested b<3.0.0 and >=2.0.0
a 3.0.0 depends on b==3.0.0
The user requested b<3.0.0 and >=2.0.0
a 1.0.0 depends on b==1.0.0
and thought it was wrapped but of course as soon as I ask it occurs it's probably not
Nah, that's each of the items separately.
Cool haha thanks for your help π
π¬
Was there a lot of consideration of the formatting of conflicts? (just curious)
if you have to ask then... unlikely π
it's a difficult problem. as much as I love Rust I've encountered some rather cryptic messages from Cargo about conflicts
Yes, it was a topic we discussed at some length when working on the dependency resolver in 2020. As Ofek says though, it's quite a difficult problem to solve.
I encountered a massive amount of pain last year (especially regarding error messages) when I had to patch dependencies in order to build on CentOS 6 https://github.com/DataDog/datadog-agent/pull/18303/files#diff-85a53f2362d9a8aeaf81712aeec92218a065f4169f76001f3188ce4ef5b4a83dR545
we had to fork a few projects and use Zig to target a specific glibc version, very hacky but it works
I'm working on a package resolver testing tool and going to do a lot of comparing error messages across tools π
I've not tried this, but here's a new "Python virtualenv manager written in Rust" https://github.com/LilyFoote/lilyenv
Lilyenv is a tool for managing python interpreters and virtualenvs.
Why is this not a hard requirement https://github.com/LilyFoote/lilyenv/issues/6
Sadly, it's just subprocessing python -m venv on a specific python version
is there a way to use cloud storage buckets as package indices directly without web serving functionality? specifically, I'm wondering if there's a way to direct pip to automatically append index.html when setting the index URL to .../ since that doesn't happen without a server
ah got it, I can actually rely on blob semantics and treat / as a distinct blob and write the index.html to that instead
question... I know this is hacky but I really need to work around this https://github.com/pypa/pip/issues/11664
what can I monkey patch in the interpreter to make pip think it is on a different platform/architecture?
pip just uses this logic https://github.com/pypa/packaging/blob/main/src/packaging/markers.py#L234
So you just need to patch default_environment
that's awesome, thank you!
pip just uses this logic https://github.
good evening. cheers=)
when does pip do setup.py develop vs pyproject.toml based editables?
I'm finding on 3.11 for https://github.com/plotly/dash/ pip -e . does a legacy setup.py develop
but for 3.12 it does a pyproject.toml build even though there's no pyproject.toml installed
I also have setuptools installed
ah I didn't have wheel installed
Are there differences between --upgrade and --force-reinstall?
pip install foo && pip install --upgrade foo will install foo once
pip install foo && pip install --force-reinstall foo, will instal foo twice
(just a guess) upgrade checks versions and bumps only when newer is available and force-reinstall will always reinstall (could also be useful when for some reason previous installation of the same version is broken)
Makes sense thank you!
(also, force reinstall implies an upgrade)
It does? It doesn't just reinstall the current version?
I would have assumed that using the flag by itself would reuse the same wheel
I don't think it's possible to locate the same wheel just from the information in the installed project.
Not to mention that the project may not have been installed from a wheel in the first place.
Yeah, that would require a lock file
Note there are many quirks in pip upgrade strategies in presence of direct URLs or editables. See for instance https://github.com/pypa/pip/pull/10564#issuecomment-1484093165
Thank you! I'll study that
Hi everyone ...
I am wondering, how pip gets the .whl file, from the html file serverd by pypi server in url https://pypi.org/simple/pandas/
It does a regular http download.
yeah .. but there are list of all versions in that html file..
it doesn't even have version attribute in that <a/> tag, how it does parsing this ?
there's an API: https://pypi.org/pypi/pandas/json
pip doesn't use that, and we really don't want anyone to rely on that at scale.
oh yeah .. I think it is using https://pypi.org/simple
It's parsing the wheel filename, and the details of what that HTML page looks like is contained in https://packaging.python.org/en/latest/specifications/simple-repository-api/
if you observe, the line 561, they are refering to the rel attribute, I am not sure what it is .. !!
https://sourcegraph.com/github.com/pypa/pip@51de88ca6459fdd5213f86a54b021a80884572f9/-/blob/src/pip/_vendor/distlib/locators.py?L561
yeah and one more, like if we observe the filenames, they are not only name-version .. they are also attached with - win - py3 - py2 stuff like that ..
pip's not using distlib either for this stuff.
ohh ..
If you're comfortable looking at the implementation, it's here: https://github.com/pypa/pip/tree/main/src/pip/_internal/index
Although, https://github.com/frostming/unearth might be a better choice for thing to look at for understanding things, if you wanna look at an implementation/docs.
ohh now I get it ..
I was looking for this, in whole repo .. haha xD
thankyou .. I will first go through it, and see if my little brain can handle that much
what is this ?
Neato!
It's a project that pulled out pip's implementation and made it reusable.
ohh I see, interesting though ...
why?
is it subject to change and the simple API isnt?
hmm interesting
so projects currently using it should be fine as long as they dont use another index server?
Which is basically preventing use with devpi if you want to have local caching or with mirrors like bandersnatch-generated indexes or piwheels or... like corporate indexes for stuff that can't be on pypi.org
But, yes.
What's the reason that https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl contains a pip3.10 entrypoint?
When we're trying to install pip ourselves, this creates an entrypoint mismatching the user's python version. Is there a requirement to special case pip when installing?
Yes
pip special cases itself
Now there's multiple installers it might be worth getting that wart in the whl spec
I've wanted to clean this up for a while, but it's just not been something I've had time to come around to.
Thanks!
Just for pip or a general "install this tool as tool{python_major}.{python_minor}"?
pip and easy_install
Probably at least worth specifying the current behaviour so uver installers can have a go
yeah it'd be great if this was added to packaging.python.org
Do you have a GitHub issue for UV for this?
Could you drop an issue on packaging.python.org as well? Please also mention that I asked for it there (so that I get autosubscribed π ).
I also have another packaging.python.org docs thing, making the direct_url.json url field a valid url. I've put it up as a PR there, not sure if there's a better place to discuss: https://github.com/pypa/packaging.python.org/pull/1506
I don't think this is true https://github.com/astral-sh/uv/pull/2083
Previously, uv would always prioritize the index given by
--index-url. It would then try any indexes after that given by zero
or more --extra-index-url flags. This differed from pip in that any
priority was given at all, where pip doesn't guarantee any priority
ordering of indexes.
I'm almost positive that the --index-url takes priority. Is that not true actually?
in testing it appears that way at least
There's no guaranteed ordering there, from pip's PoV.
yeah, that was one of the pain points Poetry tried to solve with it's sources (that being mimicing the way pip works, while maintaining some kind of ordering for solver)
I'm pretty sure that there's some arbitrary order but I don't fully remember what and, well, we might have to change it at some point theoretically.
a standard (PEP-ified) way to deal with indices other than "point to PEP 503 index" would be great
especially mapping dependencies to indices
(which is one of the issues that stop Poetry from adapting PEP 621)
thats uhh... kindof happening right now with the lockfile pep
yeah, but lockfile is an output of resolver. what I mean is standard spec of resolver input
There doesn't need to be a standard spec for that though
well, I disagree. currently you can't specify that for example, for system X and python version Y, you want dependency D to be taken from index A and in every other case from index B
that could be the outcome of the resolver in lockfile
but there is no standard way for users to map that in the input
I don't think there needs to be a standard for that if the lockfile pep process creates a standard format for consuming dependency information, but I'd want to see people explore the use cases they want out of it more before standardizing on that for resolvers.
I do think a deterministic way to map requirements to indices as input to a resolver is very important. One of the pain points I see in practice with people using 3rd party package indices is either pulling the package from the wrong index, or general confusion about how to be sure packages will resolve to come from a certain index. Today there isn't really a way to guarantee that a package will come from a 3rd party index (AIUI), without using --index-url which isn't usable if you only want to pull one or two packages from that third party package index.
exactly
and Poetry solves that
but that syntax is not portable to pep 621 requirements
I agree being able to declare this in package metdata would be good, but I also think people need to be able to declare this at the pip command line
I agree that it should be specifiable at the command line, but I disagree that we need a standard way to do that, that enforces things about tool design rather than leaving it as "something resolvers should be capable of generating and installers should be capable of consuming", both of which are covered in lockfiles.
Hi, are ci tests not currently working on PR's? In failed tests I'm getting errors indicating that nox can't find the setup.py, and it was removed in a recent commit on main.
Context: https://github.com/pypa/pip/pull/12388
Nicee
Has anyone ever needed to call a system tool during the build which itself was written in Python?
from what I see pip sets PYTHONPATH in a way that breaks any calls to them and doesn't check which Python is used
but even if it would check that the build interpreter is used, PYTHONPATH could contain incompatible libraries and still break things.. meh
so, don't write build tools in Python π
If you need a Python-based tool, can't you declare it as a build requirement?
those are not on pypi, they are scripts that are part of system packages
on a second though sitecustomize could remove itself from path if it detects it... I guess I'll open an issue with meson-python.
sorry for the ramblings..
I've been hacking some more on improving the presentation of pip's error messages. This time I'm working on the requirements related errors. β¨
Oh, they're gonna be even nicer once we can get newer packaging into pip; since it'll make the invalid-requirement case even clearer.
Already asked on #pipx but this is probably a better place. Would shipping pipx with pip (or adding that feature to pip natively) be possible? I am willing to do the leg work if maintainers say yes to that
How are you imagining maintenance working for that setup & how are you thinking of installations not going awry because two packages want to provide pipx?
I don't know how/if we can make it work, but I also don't really have a strong opinion on this. π
Well, I am more inclined towards adding native support for that kind of functionality, probably the entrypoint would have to be different or something. It would just make life easier for tools creators
Ah.
There's some discussion of a pip run, and I'd be on board for it if we can figure out what shape it's supposed to take.
For now I just wanted to know if maintainers would be ok with such feature, the details could be discussed later
I am.
From what I know, it's supposed to be a solution for single-file scripts to avoid having to make env for their dependencies, rather than isolated env management
But I will revisit that
IMO, pipx would be a good candidate for inclusion into ensurepip.
It's extremely unlikely to be a part of ensurepip I think.
Yeah, pipx has too many dependencies to be just made part of ensurepip
Taking a look into the code, I would say that most likely scenario would be to add the functionality of pipx into pip, using patterns and code already available in pip
pip x command π
as far as I can tell, pipx has only got the 2 additional dependencies
It has like 5-6 dependencies
"additional" [to what pip already has]
yeah, userpath depends on click it looks like, so 3 extra in total
yeah, that's more than enough overhead
having this as part of native pip would be much cleaner solution
dunno, not a pip dev, but I don't think a few extra dependencies is gonna be the dealbreaker here
does pip have a feature for only installing a project's dependencies, without the project itself? like poetry install --no-root?
but how do you envision this working as part of ensurepip anyway?
no
would such a new feature be welcomed as a PR?
I think pip's more likely to lean on the upcoming dependency group PEP
I don't. That would require patching pipx and/or shipping extra wheels
Hi all! This is my attempt to follow up on Projects that aren't meant to generate a wheel and pyproject.toml . Some notes and questions to seed discussion: I have mostly stayed close to @brettcannonβs proposed simplified solution from that thread, but have made a couple of changes. Thatβs part of why I listed him as sponsor, rather than...
I mean even if it were to be bundled, unless you're installing Python from python.org, it'll have been configured without ensurepip. In fact, I don't think having a different pipx script per Python install makes much sense at all, except for run
Ooo, does packaging 23.* come with better error messages? π
I briefly tried including the current packaging InvalidRequirement/Marker errors in the pip error and it was less than informative :P
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ichard26/dev/oss/pip/venv/lib/python3.11/site-packages/packaging/requirements.py", line 37, in __init__
raise InvalidRequirement(str(e)) from e
packaging.requirements.InvalidRequirement: Expected end or semicolon (after name and no valid version specifier)
blac-
^
ah very nice
I suppose we can surface the error location in the pip error when newer packaging lands... eventually
Not necessarily opposed to the inclusion of pipx in pip but note that we'll be working on pipx for uv in the near future.
@azure heron once you get uv installed by default with python installations, it will be fine
But we'll be the ones installing Python π
pyenv my beloved π
- https://github.com/pypa/pip/issues/9657
- https://github.com/pypa/pip/issues/10813
- https://github.com/pypa/pip/issues/11889
these issues can be closed as they've been resolved
@hidden flame I'm slowly catching up on my notifications for pip -- https://github.com/pypa/pip/pull/12566 is quite nice!
@shy echo I'm out on a walk, but the short of it is that 1. I don't remember, and 2. I think I was going to check for error messaging/styling consistency between the PRs
Evidently I never got around to that (because I was busy on a third error migration PR) but I'll take a look sometime this week if I can :)
No hurries on this, enjoy your walk!
Psst, this was the network import optimisation thingie. :P
I'm a serial perfectionist. Everything's got to be perfect... but right, I think I can address the import PR tonight then, haha
any thoughts on this? https://github.com/astral-sh/uv/issues/3014
Other than pip's behaviour is correct, no.
okay just thought I would bring it up here, I haven't read that spec in a while
so I guess the fact that UV always produces a commit hash is not what the spec says?
If pip's behaviour does not align with the spec, the spec needs updating IMO since this is what my understanding of the format is: the whole point of this entry is to reflect the user's request.
Of course, opinion subject to change in light of additional information. :)
taking a quick look at the spec, it seems that they are within what spec allows
Yup.
I don't know that they are compliant looking at it now https://packaging.python.org/en/latest/specifications/direct-url-data-structure/#vcs-urls
I think the spec language needs improvement.
"requested" really does imply that the user information should be reflected
Made a comment on the issue, to encode the main point of these last few messages there.
they might have used the PEP rather than the living document spec because there is actually something that was not brought over https://peps.python.org/pep-0610/#specification
- If the installer could discover additional information about the requested revision, it MAY add a
resolved_revisionand/orresolved_revision_typefield. If no revision was provided in the requested URL,resolved_revisionMAY contain the default branch that was installed, andresolved_revision_typewill bebranch. If the installer determines thatrequested_revisionwas a tag, it MAY addresolved_revision_typewith valuetag.
oh even that is not correct that says resolved, my bad
resolved_revision was left out from packaging.python.org because not implemented by any tool
We need the resolved revision for caching
Yes, but if we have to make the change from requested_revision to resolved_revision, it would be great to add resolved_revision to the living specification
I agree.
The resolved commit that can be used for caching is commit_id
good point
resolved_revision was meant to be, say, main (the default branch name) when installing from a vcs URL without explicit ref
Ah, for posterity: I clearly misunderstood resolved revision to mean resolved commit hash, which was
wrong.
Understandable misunderstanding π We had quite a lot of back and forth with my co-author on the naming of these things... it's now what it is for good or worse.
I've never seen this error before https://github.com/pypa/pip/issues/12621
The ux research results are finally up π https://pip.pypa.io/en/latest/ux-research-design/research-results/
I sure hope y'all don't mind me slamming your inbox via the issue tracker :P
Nah, it's appreciated. π
this is me for the past few days. You thought I'd stop at just one, two, or even maybe three issues, but nope!
Anyway, I'm actually done for today, going to go outside or something.
https://github.com/pypa/pip/issues/12460 does anyone understand what this person is asking for? I don't think it's very actionable as-is...
might be related to the thing that torch wanted: some sort of virtual selector packages to help users, but doesn't sound like something pip can just guess at even if it is that.
Additional context: [...] you will see.
"you will see"
Yeah no. It's the responsibility of the requestor to provide an MRE. Close the ticket and tell the requester that they can reopen it if they edit their comment to contain an MRE.
But even without that part, it's notpip's job to pick which version goes in yourrequirements.txt, it just dumps out the version that you've installed. This issue is out of scope regardless.
oh
I'll warn the user then π
Thanks @hidden flame for mentioning!
FWIW, it was a feature request, just a poorly written one that wasn't really actionable as-is.
I agree the issue should've been closed, but the reasoning is a bit different from the rest of the other issues I've been marking for closure.
does pip follow the recommendation and enable the executable bit for scripts on Linux? https://packaging.python.org/en/latest/specifications/binary-distribution-format/#recommended-installer-features
nice thank you! I encountered a script at work right now with an error but it must be something else we do that's weird
No, I was mistaken, my first URL is for the installer = pip file
pip sets maker.set_mode = True and the magic happens here https://github.com/pypa/pip/blob/800c1245bd7d5b3ad3fd52fd84c17a230bfa28e4/src/pip/_vendor/distlib/scripts.py#L308
I can't see what happens if the wheel has scripts but not entry points
Would help in reducing the PR backlog be welcomed? I was thinking about reviewing the laundry list of open PRs and flagging those that can probably be merged (in a new issue). I also wouldn't mind taking on (some) PRs that have been approved on principal but need a bit more work to be landed (addressing merge conflicts/review comments).
I realize that getting the packaging upgrade landed and release 24.1 cut is the current priority, so I would likely pick this up sometime in May.
How do I install extras when doing an editable install via pip? I ask because when running this command...
venv-windows/Scripts/pip install --editable ".[all]"
...I'm told WARNING: libretro-py 0.0.0 does not provide the extra 'all' despite the following section in my pyproject.toml:
# This package's name is libretro.py
[optional-dependencies]
dev = [
'bandit == 1.7.*',
'black == 23.*',
'flake8 == 6.*',
'isort == 5.*',
'mypy == 1.5.*',
]
opengl = [
'moderngl == 5.10.*',
]
pillow = [
'pillow == 10.2.*',
'types-Pillow',
]
all = ["libretro.py[opengl,pillow]"]
Any tips?
Itβs [project.optional-dependencies], not [optional-dependencies]
I've since been advised of that in another server, but thank you.
In some fairly different news... This is what my last few days of free time has gotten me:
https://github.com/google/triage-party/issues/306
Will some Googler respond to me? Who knows... π€·π»ββοΈ
Description When trying to use triage-party with https://github.com/pypa/pip, I'm consistently getting a SIGSEGV crash. panic: runtime error: invalid memory address or nil pointer dereference [...
a multi-player triaging party night is not an idea I was expecting, but you know what, that sounds pretty nifty, haha
reminds me of the time when Jelle and I spent a few hours cleaning up Black's issue tracker together in 2021
pandemic times were weird :)
I miss that weirdness :/
The more interesting piece for me is that it'll let me triage with custom filters more powerful than GitHub's built in ones.. π
YAYAY!
I bodged it, and figured it out.
β― g diff -- **/*.go
diff --git a/pkg/hubbub/item.go b/pkg/hubbub/item.go
index 05833e1..11ac59a 100644
--- a/pkg/hubbub/item.go
+++ b/pkg/hubbub/item.go
@@ -161,7 +161,7 @@ func (h *Engine) createConversation(i provider.IItem, cs []*provider.Comment, ag
}
}
- if !seenCommenters[*c.User.Login] {
+ if c.User.GetLogin() != "" && !seenCommenters[*c.User.Login] {
co.Commenters = append(co.Commenters, c.User)
seenCommenters[*c.User.Login] = true
}
Not exactly a patch I understand, but it seems to make it not panic and that's good-enough for me.
Congratulations!
Thank you!
I'm glad it didn't turn into one of these :P
I may asking the obvious here, but how much of a mess is your inbox? :)
oh.
doing quick napkin math, I'm only responsible for maybe at most 0.7% of those emails which makes me feel better about my activity on the repository
LOL
honestly though for github, I just click "mark all as read" there is no way I'm reading all of my notifications
my corpo inbox is always close to zero, wish I could do the same with my personal one
Hehe, my corpo inbox is also not even close to 0.
fixing corpo inbox is easy, you can just change jobs if you got it to a bad state and start following the inbox zero practices in the new job /s
can't do the same with personal email
The problem isn't me, it's that tools and software that sends me emails and notifications.
And, people tell software to send me emails.
If you have to look at it at least once then just archive it after. If you don't have to look at it at all... filters?
Oh, I have those too.
one of the Jira boards I have access to is configured poorly so I get email about every created ticket even though it doesn't relate to my team at all so that was annoying until I got to creating a filter π
archive functionality is great though, just gotta do it eagerly
New Outlook app combines threads like Gmail which also helps, I wish the classic app did that too since it is a more complete product.
It starts with only a few emails that I tell myself "I'll get to them eventually..." which becomes 20 and then 100 :)
Whelp, pip's CI is failing due to the bump to macos-14 which lacks subversion https://github.com/pypa/pip/actions/runs/8853699641/job/24315160176#step:7:3093
https://github.com/pypa/pip/pull/12617 will add it
small fix https://github.com/pypa/pip/pull/12665
Hello folks! I just cut https://pypi.org/project/pip/24.1b1/ a few minutes ago -- please do test it out by installing it and trying it in various environments. It should be generally quicker and a lot stricter about various names and various other details.
Already one issue: https://github.com/pypa/pip/issues/12675 pip crashes during its pip self version check when downgrading pip (note that the downgrade is still successful as the check is deferred to the very end of the command). This was my fault π
The feature I want most from uv: --exclude-newer DATE. This is so good for building old projects without lock files. π
Hmm, yea, now that the simple API has this metadata, pip should probably also support it.
I think we actually have an issue in the tracker for this
i think im missing something, i'd like to always enable the truststore usage for a certain virtualenv, but the docs i skimmed don't indicate how to add the use-feature flag to a config file
Good timing https://github.com/pypa/pip/pull/12699
https://github.com/pypa/pip/pull/12705 lots of vendoring removals β¨
(^ CI is broken due to typing-extensions' incompletesupport for Python 3.13)
How can this work? https://github.com/pypa/pip/pull/12705/files#diff-7a05c7ad174407ce6cb4af3e50b581952acf0114d989fa874e26b58883a6d0daR41
The retry decorator returns a function without a .calls attribute
I think mypy is correct to error here with attr-defined
It turns out that functools.wraps copies the original function's attributes
But they won't be mutated?
Oh it's a list
@shy echo Did you intend to share your pip 24.1 beta blog post on DPO? I don't see it currently, but it's probably worth sharing there.
I did, thanks for the reminder!
I spent a bunch of time today figuring out what is going on with pip's CI.
It's broken because git disabled lazy fetching.
wait really
isn't that like a core component of blobless/treeless clones? or am I misunderstanding the issue here?
Yes.
Sounds annoying. Do you have a documentation link about that at hand?
I made it to https://github.com/git/git/commit/7b70e9efb18c2cc3f219af399bd384c5801ba1d7 for the commit.
It's changed in the latest bugfix release basically.
OK, other than that, I've had a chat with the Faster CPython folks about including the pip requirement parser (from packaging) and the pip resolver (resolvelib) as benchmarks that they're testing against.
I've got a bunch of details I need to either write down or implement.
other than somebody devoting time to it, is there a desire to implement an experimental form of caching which keeps wheels unpacked on disk similar to UV?
no promises but like if a giant PR happened one day would that be considered?
I think the "problem" ( for lack of a better word ) is it's an observable behavior change, and it's not clear if it's expected or desired for users
my assumption is that it would be behind flags until such time that it would be deemed desirable to make it the default
it would definitely be unexpected, 100%! however I cannot think of any reason where it would not be desirable
maybe something to do with hash integrity but I'm stretching
There was an issue filed by Glyph at some point for the same thing.
ah neat thanks https://github.com/pypa/pip/issues/11092
Disk usage would definitely be one of them, especially since pip does no automatic cache housekeeping.
true good point though I think everyone would still prefer it
when distributing there would never be caches anyway like container images where there would be a removal step or shipping pre-built Python installations like I now do for Hatch
and on a developer machine my assumption is that it would be a net decrease in disk utilization because as the number of virtual environments increases the net difference would as well
I've done absolutely no math on this but I'd say after 4 virtual environments for mostly shared packages there would be a net decrease compared to the wheel cache approach
if you're a data scientist/AI researcher/Nvidia user/etc. then the gains probably start at 2 lol
So symlinks in addition to unpacked wheels? That's a bit different than your proposal earlier.
oh yeah definitely you would have to change the installation mechanism to gain the same performance as UV, although as Donald mentioned in that issue it would be an immediate win because copying files is fast
I'd start with copying files, I've seen more than one project that modifies installed files. π
Reflinks would be a good fit.
sorry I commented then got distracted by something shiny
I relate strongly. π
FWIW, and take opinion very lightly!, I don't see any real long term problem with having a shared "database" of unpacked wheels that we... copy? symlink? reflink? something?, my statement about things being a problem is more talking about the problem of getting from point a to point b
I did actually write a distribution deduplicator at some point. I never used it as the storage savings weren't that great (in fairness, it was definitely poorly optimized) and frankly I like being able to scratch on my venvs sometimes π
I definitely start yolo editing my venvs occasionally
"investigates bugs and starts aggressively inserting print calls into site-packages"
pfft. That's a debugger UX problem for most users. Debuggers are a lot less intuitive a tool than they probably could be, and the only time anyone wants to improve them (hyperbole) is while they are in the middle of fixing something else more important.
I end up debugging a lot by writing all this in site-packages or even the stdlib (eg socket.py)
def __init__(self, ...):
f = io.StringIO()
traceback.print_stack(file=f)
self.tb=f.getvalue()
def __del__(self):
if not self.closed():
print(self.tb)
I'm not sure how else to do it
I will go check GitHub for full discussions, but @willow flicker suggested that I ask here why
python -m pip --no-cache-dir download --no-deps --no-binary :all: <package name>
is also running the prepare metadata steps. While pip download --help doesn't seem to show it, is there a flag that can be used to skip this and just download the sdist?
Example:
$ docker run --rm -ti python:3.12 /bin/bash
root@27ab9b0779ef:/# python -m venv venv && . venv/bin/activate
(venv) root@27ab9b0779ef:/# python -m pip install --upgrade --pre pip
Requirement already satisfied: pip in /venv/lib/python3.12/site-packages (24.0)
Collecting pip
Downloading pip-24.1b1-py3-none-any.whl.metadata (3.6 kB)
Downloading pip-24.1b1-py3-none-any.whl (1.9 MB)
ββββββββββββββββββββββββββββββββββββββββ 1.9/1.9 MB 9.8 MB/s eta 0:00:00
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 24.0
Uninstalling pip-24.0:
Successfully uninstalled pip-24.0
Successfully installed pip-24.1b1
(venv) root@27ab9b0779ef:/# python -m pip --no-cache-dir download --no-deps --no-binary :all: hist
Collecting hist
Downloading hist-2.7.3.tar.gz (992 kB)
ββββββββββββββββββββββββββββββββββββββββ 992.2/992.2 kB 8.1 MB/s eta 0:00:00
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Saved /hist-2.7.3.tar.gz
Successfully downloaded hist
(venv) root@27ab9b0779ef:/#
Ah. Old old issue. Thanks for this.
The "1000ft view" is that this is tech debt hitting us. The "download" and "generate metadata" pieces are highly coupled in pip.
Thanks @shy echo. That's a good enough summary for me.
I'm trying to use pip 24.1beta so that I can run the nogil Python builds. It works fine for 3.14, but on 3.12 and 3.13 pip fails:
pip._vendor.packaging.version.InvalidVersion: Invalid version: '3.12.3+'
The failing GitHub Action is here: https://github.com/nedbat/coveragepy/actions/runs/9401046533/job/25891965210#step:8:19
Have I missed an important step?
I guess this is because 3.12 reports its version as "3.12.3+" while 3.14 reports as "3.14.0a0"
You're probably running into https://github.com/python/cpython/issues/99968
yes, looks like it. What can I do about it?
I'm asked to test pip betas and Python alphas and Python nightlies, but they don't get along.
It looks like there might already be a fix: https://github.com/pypa/packaging/pull/802/files and just not released yet?
following links from that issue, https://github.com/pypa/packaging/pull/802 is a merged PR to fix it, which hopefully will be in pip 24.1, planned for the week of 17th June: https://github.com/pypa/pip/issues/12613#issuecomment-2151171787
Not yet, it's blocked on me finding time to cut a packaging release followed by a pip beta release.
Or, directly jumping to non-beta depending on what the timelines look like.
If i wanted to be really cutting-edge, would I be nuts to install pip from github?
No but, also, not yet. π
ok!
@keen void You can do so now.
thanks. Will there be a beta2? Or when is the next release?
https://github.com/pypa/pip/pull/12763
I need to eat, but I'll cut one after dinner. :)
@lunar gyro Any idea what might be happening with https://github.com/pypa/pip/actions/runs/9477464511/job/26112070352?pr=12763? It's a windows-specific failure that I don't quite understand (beyond that unc path stuff is implicated and it's only failing on 3.13 π ).
> assert path_to_url(r"\\unc\as\path") == "file://unc/as/path"
E AssertionError: assert 'file:////unc/as/path' == 'file://unc/as/path'
E
E - file://unc/as/path
E + file:////unc/as/path
E ? ++
Nvm me, I found https://github.com/python/cpython/pull/118089 related to this.
So looks like C implementation is behaving a bit different from the Python one?
Yep.
Bummer
Yea, it looks like we only picked up b2 in the release PR (hehe) -- I'm gonna push through with this release after dropping a comment on the relevant CPython issue.
CI has been red so much in the last two months 
That emoji is called ducky australia π
Offensive
I joke, but yes, most upside down emoji's get branded Australian
USA pushed your cricket team @shy echo π
Wish they had won. Would have been awesome.
I did chuckle that they had two big batters out in the first 15 balls. XD
I bet @hidden flame doesn't even know Canada has a cricket team in the World Cup π
I mean, I'm not surprised, but yes I did not know we have one.
I don't follow sports in general :)
i don't understand how cricket is played and there doesn't appear to be a sports anime to explain it to me through the plight of a teenager with weird hair so i guess it will remain a mystery
Itβs not that difficult to understand what the players are doing but the scoring system is def confusing
97% of scoring is easy. 1 run every time batsmen run across the pitch, 4 if it crosses the boundary rope, 6 if it crosses the boundary rope without touching the ground
It's all the "extras" that add complexity.
Ways to score:
- Baseball: 1
- Football: 1
- Basketball: 3
- Cricket: 3?
- American football: ????
American football: 3?
Itβs definitely more than 3, I can count TD, extra, 2p conv, FG, and I think there are more than one safety rule?
4 or 5 depending on how you count:
ARTICLE 2. TYPES OF SCORING PLAYS
Points are scored as follows:
- Touchdown: 6 points
- Field Goal: 3 points
- Safety: 2 points
- Try after touchdown: 1 point (Field Goal or Safety) or 2 points (Touchdown)
https://operations.nfl.com/the-rules/nfl-video-rulebook/scoring-plays/
there are definitely more than 3
(but this is #pip, not #off-topic :P)
Who said rules had to be followed :p
Should make main green (until 3.13.0b2 is released) https://github.com/pypa/pip/pull/12774
Heads up: I'm gonna have very limited internet access for ~4 days starting Saturday GMT since I'm gonna be on a vacation. And, I'm probably gonna cut the release tonight.
Enjoy vacation!
I'm probably scarred for life by pip 20.0, coz I'm like... wait, we don't have an issue immediately after cutting a pip release. Did I actually do the release properly?
I'll be around (although with limited availability). I'll try to handle some issue triage as I'd imagine we'll see some new issues filed as pip 24.1 is picked up.
(also, this reminds me that https://www.volunteeramnestyday.net/ is a thing and it's today!)
π―
I still remember when I introduced a regression on like my 5th contribution (ever) to Black. I freaked out upon reading the newly opened issue :)
FWIW, if there's some showstopper issue and I'm unreachable (because, idk, I'm somewhere in the middle of Scotland), I trust the other maintainers to pick one amongst ourselves to cut an emergency bugfix.
I think this trust is implied already, but figured this is the sort of thing that it doesn't hurt to reiterate. :)
Usage of betas was high this time around due to needing it for free-threading. Manylinux and cibuildwheel had to ship with 24.1 betas for CPython 3.13 due to that, and I've had to use it in various CI's for CPython 3.13. (IMO, this is the major new feature and it's not mentioned in the highlights!) So, probably going to jinx it, but I think it should be pretty quiet!
Well, the thing is that there are likely some corporate environments and a wack ton of legacy environments where legacy versions/specifiers are in still in use. Once they upgrade to pip 24.1, we'll start getting pitchforks.
Yea, I hear ya! I can edit the highlights to mention it. :)
You know, I was expecting worse, but two issues isn't too bad so far.
The CPython change that causes Windows test failures (see https://github.com/pypa/pip/pull/12774) was backported to 3.12.4 which is now included in GHA runners https://github.com/actions/python-versions/commit/1c85886f9c23363cd42fe0d4c2decee499485df0#diff-f69ccbefcbee0c9c68b41a0e58591150a3c87aa13d476d33fc8ebf90588e13c5R377 so it's now causing failures in pip's test suite https://github.com/pypa/pip/actions/runs/9614117106/job/26518252566 (backports for other versions have also been merged upstream, those versions aren't in the runners yet).
@shy echo you better be enjoying your vacation, submitting and reviewing PRs during your vacation :P
I am! Just figured I'd take a look before wrapping up my day. π
And, it's like... ~2 minutes of work to file that PR (once I got network working on my laptop).
Fair :)
Attempt at fixing the test failures https://github.com/pypa/pip/pull/12788. It need some more work since there are more failing cases I didn't catch, but happy to hear any feedback on the approach
@shy echo random Q for you: does pip install check the file's content against the PEP 503 index-supplied hash, or only against hashes when supplied via requirements.txt in hash-checking mode? i tried to find conclusive evidence in the source but coudn't with a short search π
You'll probably only see this when I get network, but the answer is yes.
For the first part.
Much appreciated! Apologies if my message reached you in a place where youβre avoiding computers π
Alrighty, let's see what 24.1.1 needs.
Hmm, do we think we need one for the hardlink one as well? I mean, 24.2 is due in about a month, so Β―_(γ)_/Β―
I think so, haven't looked at the PR yet.
Coolio. I'm curious as I got some PRs I've like to see land in the next release cycle, but let's finish 24.1 first.
I'm back to hacking on pip errors. This is what I have so far for improving connection failures. I still easily have 80% of the work left, but the prototype is promising. Disclaimer: this already involves some hacks :(
Noice!
Y'all weren't kidding about it being nontrivial to improve the error reporting in pip. This alone took a few hours (consisting primarily reading urllib3/request source code and documentation, and exploring the exception state that is available to me).
Yea, this in particular is a hairy one and improving it is worth a lot IMO.
Mhmm. The retrying messages are particularly bad.
To potentially pop your bubble, I'm currently relying on installing a custom logging filter on urllib3.connectionpool that "sniffs out" the retrying warning. A slightly less hacky solution would be to patch urllib3 to pass a special flag/enough state in that log.warning(...) call that the filter can look for.
I'd like to upstream the extra={...} patch to urllib3 but we can't upgrade to modern urllib3 until 2025 AFAIU due to OpenSSL incompatibilities.
FWIW, I got stuck when I started thinking about what should be logged when we're dealing with flaky indexes and stuff where even "what to write" is different from a regular hand-typed URL... mostly because the guidance would possibly be different and because I couldn't decide who my audience was for the error messages (is it a professional dev, teacher, student, someone-trying-to-do-their-job etc).
Don't end up there, I guess, is the word of caution here. π
Wait, did I miss something? Why do you say this?
Honestly, I haven't thought that far yet. I'm just trying to raise the baseline to something above "it's truly awful". I'm very much in the mindset of "we can iterate on this later once we get more feedback."
Yes, please!
I did miss something!
AFAUI that's also the primary blocker for parallelizing HTTP requests too, although I'm sure that maintainer time is the biggest :P
(I'm not volunteering to parallelize that.)
Yea, I remember that there's a PR somewhere on the repo implementing parallel downloads but couldn't figure out if it was actually correct and all that.
Yeah.. there are a lot of things to review π . We'll get through what we can.
I'm simply trying to help move the PRs process along where I can. Improving error reporting is my personal project beyond that.
There is legitimately no way for me to query the URL hostname or even the full URL from the pre-existing SSLError-related retry warning state. I don't want to patch urllib3 more than I need to, but hmm, this seems more and more necessary.
I'll deal with the patching later. I'll try to do as much as I can without it, and then see how much further I can go with some judicious patching.
OTOH, this looks nice.
I like that while I'm totally out of the house and without internet, pip 24.1.2 is cut and a flurry of activity takes place on the tracker :)
I'm currently working through my notification backlog, but after that I'll take another look at the milestone. I'll try to push the scheduled PRs along as much as I can reasonably can so hopefully this release cycle doesn't drag on forever.
should (or is it already?) this Discord channel be a documented way of communication, like IRC is?
asking since I jumped on IRC before here and noticed it was quite a bit quieter
I don't think it is and... like... yea? I really really don't want to end up with user support questions here though.
I certainly would have appreciated the documentation, I only found the discord this week, I'd looked at the IRC several months ago but saw it wasn't particularly active
Whoops
Yea, alright, let's add it to the developer docs at least then π
Welcome to the triage team by the way @finite perch! It's good to see you join the team, thanks for all of your help in investigating and improving pip's dependency resolution!
@shy echo how would you suggest that I go about highlighting PRs that look ready to land, but don't really belong in a milestone? For example, https://github.com/pypa/pip/pull/12572 is purely maintenance only so it doesn't make sense to add to a release milestone, but otherwise, it should be merged at some point. I've left comments to suggest merging on other PRs with limited success.
I realize that this is mostly a problem of "limited maintainer availability" so there's probably no good solution, but I'm curious if you have any thoughts on this.
Awaiting merge is now a label. You should be able to tack that onto things.
Great, thanks!
Man, I found another issue I'd like to tackle, but I already have enough tasks on my plate for the time being. Haha.
Anyway, we should be nearly ready for pip 24.2 this weekend. All of the remaining items in the 24.2 milestone should be trivial for the most part, barring the truststore PR but it's getting there :)
Oh hmm, the changelog entries are definitely going to need some tweaking this release actually.
ichard, always wanting to do more π₯°
@shy echo I'm about to leave the house for 2 hours (poor timing, heh) but https://github.com/pypa/pip/blob/c2d706f82b1cd9332c70bed170501413240ae008/news/12728.feature.rst should be moved to the process category.
That was the main changelog item I wanted to flag earlier.
Good to know. I'll probably copy edit the changelog before the release anyway.
Can I somehow specify --only-binary such that it applies to all packages except for packages I specify?
You can specify --only-binary :all: and --no-binary {package_name} for all the packages you want the source file from instead.
A less manual approach is to use --prefer-binary which will only use source installation if no binary version is available
hmm, would --only-binary :all: --prefer-binary {package_name} work?
Basically I want to test that I can install all dependencies from wheels except for packages that I know do not have wheels right now.
I guess I'll just try it later π
I don't think so, I don't think --prefer-binary takes an argument
oh, right..
I thought it did lol
well, thanks for helping, I didn't know that --no-binary will correctly work as an exclude, if --only-binary :all: is used
I'm not sure it's intended behavior, but it works, I even requested that and uv has copied this behavior: https://github.com/astral-sh/uv/issues/4063
π I think I've finally got a fix for backjumping resolution π: https://github.com/sarugaku/resolvelib/pull/155
x-ref: https://github.com/pypa/pip/issues/12317 and https://github.com/pypa/pip/issues/12768
Totally uninformed layperson commentary, but how does this compare to changing the contract of resolvelib's APIs so backjumping is safe?
This is great news, however. Hopefully it pans out!
I don't quite follow the question, what do you mean by "safe"? And what contract?
I think the only think resolvelib tries to guarantee, is if there is at least 1 solution it will provide a solution
Sorry, I was referring to https://github.com/sarugaku/resolvelib/issues/134#issuecomment-2180697555.
Ah, yes, this is far superior because we don't need to change the contract
And I have not been able to find a solution to changing the contract that I wasn't able to find some resolution that still fails
Just spent the last couple of hours starting at diffs I created of the state of various resolutions to see if there was something I was missing, and finally found 1 consistent pattern of when a resolution fails and it shouldn't
Very neat.
Yeah, once this lands, I can finally get back to my suggestions on improving performance
Of course :)
I don't have any immediate plans for PRing my installation progress patch. I'm currently working on finishing my existing PRs, and then I'll get back to working towards reducing the PR backlog.
However, there has been a fair bit of work done by a contributor speeding up the installation step. I'd be interested in seeing you rerun your test and see how much the runtime will improve under v24.2. It should be fairly significant, especially under Python 3.11+ which uses the previously poorly optimized importlib metadata backend.
I suppose it probably makes sense to PR it once the --progress-bar raw version of installation progress lands, which should occur soon. I've scheduled that PR for 24.3.
Oh yeah, that reminds me, you said:
However, it did not play nicely with the logging stack, so any intervening logs would break the progress bar. To fix this, I had to redo how rich was initialized in the logging stack which took a bit π
And I was a bit concerned that actually maybe this isn't a good idea. I have it set up at work like this, so we can log and have a progress bar in rich at the same time. But it seems like letting rich take full control over the display might not work well in lots of edge cases where people might be using pip π¦
We already use rich for the download progress bar so those use-cases would be already broken, and AFAIU, rich gracefully handles the "are we running under a modern TTY or not?" question for us.
Yeah, I will rerun tests soon and get new performance numbers and call graphs
commit fe5f224ab89ca5faf73b80ebaae025f9f23e1358 (HEAD -> installation-progress)
Author: Richard Si <sichard26@gmail.com>
Date: Mon Jul 15 23:18:36 2024 -0400
[wip] Add rich progress bar for package installation
src/pip/_internal/cli/progress_bars.py | 48 +++++++++++++++++++++++++++++++++++++++---------
src/pip/_internal/req/__init__.py | 15 ++++++++++-----
src/pip/_internal/utils/logging.py | 33 ++++++++++++++++++++-------------
3 files changed, 69 insertions(+), 27 deletions(-)
It's not that bad of a patch. We just have to enforce that there is only one rich console per stream at use globally. Rich, including rich progress bars actually is able to play nice with non-rich code that prints at will. The problem was that currently pip's rich progress bars are completely unaware of the logging stack, which also uses rich, so the locks that rich implements are sidestepped.
This is completely irrelevant, but I have a laugh whenever I talk about rich because it's a nickname of mine that I hear with regularity, ha.
Oh that's funny
Not a particular fan of it, but I don't really mind it. People like to use it.
I think there are worse nicknames for Richard
And actually, I'm pretty sure if pip emitted any logs while downloading a distribution, it would break as of right now. This can and should be fixed at some point.
Coolio, TIA!
Oh... I think I might have found a show stopper for pip 24.2
You can't just bookend your message there, heh.
Oh, I'm confirming I can reproduce and writing up the issue now, it actually looks like it might be fairly cosmetic and purely related to pip development
Maybe my patch to lazy load the pip self version check module was a mistake π.
I feel like that patch would make truststore less likely to be invoked, rather than more likely
The problem is probably another class of "the pip self version check loads after a new set of pip code is installed, which predictably blows up", although I'm not sure how that manifests here as truststore should be already loaded as the pip install command needs to access the network anyway.
Ah
I think the easy patch is simply to eagerly load the self version check module at the top of the install command module.
I suggested this earlier, but we went with a more targeted patch to only eagerly import it when installing pip.
Can you try adding import pip._internal.self_outdated_check to the very top of src/pip/_internal/self_outdated_check.py and attempting to reproduce the crash again?
Sure
If this fixes it, then this should suffice as a short-term fix to unblock the release, although I'm wondering whether I should just revert the lazy loading entirely as lazy imports are in general pretty dubious in a package installer where packages may be replaced under our feet suddenly.
Oh wait, I'm an idiot. Sorry I meant src/pip/_internal/commands/install.py.
Great, because your earlier suggestion didn't work
Still doesn't work
Hmm, fun.
I'll copy n' paste our discussion to the issue, but that's not great.
Ah, yeah, that makes sense. The problem is that we're initializing a new (requests) PipSession in the pip self version check. This involves setting up truststore again which breaks as certifi has already loaded and certifi.where() returns the old location for its CA bundle.
So, I didn't break this, although this is still not great.
Is that because of the ctx.load_verify_locations(certifi.where())?
I was thinking that line was going to cause problems eventually
I do wonder why this didn't break earlier when we relied entirely on certifi. It must have been used in a different way.
Yup.
You should've spoken up, you would've gotten a cookie for being right on the nose πͺ /lh
Weren't manually calling certifi before right? Leaving all that logic to requests, imagine it's quite battle tested
Well, my bigger concern about that line, is people who don't want certifi certificates, and will at some point complain about old/incorrect ceritificates being loaded, perhaps after a real world security incident
Ah yeah, you're right.
I don't know what the state of system certificates via Python around the world is, but my gut instinct is that this will probably have to start off as an option.
I do remember reading some ancient issues about asking pip to use the system certificates though.
Well, I was more thinking of something that happens in 5 years. But there's also the point that if you use truststore in pip 24.1 you don't get certifi certificates, but in pip 24.2 you do, with no way to turn off
Hmm, right. I did call out that line in my PR review, but I definitely didn't appreciate the implications at that time.
That isn't great...
I just don't have a feel for if anyone is relying on that right now though
Probably people who are so paranoid to not use certifi certificates are manually patching pip and the rest of their Python stack, but who knows
It would be nice to get to a state where hacks like certifi aren't needed, but that'll take some time.
If there isn't a currently open issue for weeding us off of certifi, perhaps it would be worth it to create a new one?
Right, because requests uses it internally anyway.
Yeah, by default
It's the assumed good store for certificates in the Python HTTP stack
Thanks for discovering and filing an issue about this @finite perch. It's definitely better to get this fixed before the release. I've left a comment explaining the root issue, a potential solution, and bringing up the bigger question of what pip's relationship with certifi may look like in the future. I will go to bed now as I got work in the morning :P
Thanks @hidden flame and @finite perch for your effort on tracking down this issue π Is there anything needed from me or Truststore for this fix?
I don't think so, this PR fixes the issue and it's internal pip handling: https://github.com/pypa/pip/pull/12865
@shy echo @idle harness is this a good place to ping for a resolvelib release? Or should I do it on the issue tracker? I'd like to vendor it into pip ahead of 24.3 and make sure there are no unexpected issues
The issue tracker works.
I was seeing some errors trying to build docs locally with a fresh env: https://github.com/pypa/pip/pull/12886 (issue is incompatibility with new version of towncrier from 2 days ago)
For compatibility reasons, see comment
actually, I was seeing different errors to the one in the linked issue (and that issue is also closed). Digging deeper
EDIT: nevermind, I had too many issue tabs open π€¦ββοΈ the one linked is indeed the problem
Hey, if anyone has examples of very long resolutions or reaching ResolutionTooDeep please send them over to me, I'm back to working on improving algorithmic resolution performance
Home assistant apparently has really bad performance, and IIRC, it was reexploration when we were backjumping.
Home assistant has over 1000 direct dependencies, so not surprising, it's a miracle they managed to move to the new resolver
What do you consider very long?
It's not a hard rule, but "seems to be backtracking longer than it should for the amount of requirements I have", could be taking over 5 minutes for a few requirements, or taking over 30 minutes for a lot of requirements
Does it make sense to raise a PR to remove the IRC link from https://github.com/pypa/pip/issues/new/choose ? Is anyone from pip on that IRC?
I used to be, but I think we can safely remove that now.
there are 55 users in that channel and the last message was July 29th
I know there are PyPA users in there in general, but I was more focused on if there are any pip devs there, no point sending pip users to a group that can't help them
why not change it to point here?
We have links over on the development side to here.
ok
I'd mentally modelled this Discord as closer to what #pypa-dev used to be. π
Maybe that's the wrong model? I dunno.
i sure don't know. it's up to you. I come here as a user and get help.
I just got timed out for sharing the typical user support links that gets used to point users to more general help, so I'll just say here is an example at the bottom of my post: https://github.com/pypa/pip/issues/12820#issuecomment-2207206343
So I started reading the various preparer and resolver PRs filed by Danny. My god is it going to take a while. The preparer <-> distribution <-> resolver interactions are so complex and confusing. π
This is going to be a multi-day project as I first need to understand how the current preparer impl. works.
Yeah, I want to help out there, I might have some time soon, I'm mostly waiting on a resolvelib release, then then I can vendor and fix some stuff in pip
In mean time, I was thinking of looking at them, if it helps detangle this stuff at all I'm all for it
I don't understand what an AbstractDistribution is and how it differs in usage from a BaseDistribution...
I mean, realistically any reviews I end up filing are unlikely to be that important, but this is a good opportunity to learn and understand a part of the codebase I've avoided in the past frankly.
9 times out of 10, when I see AbstractX or BaseX it reminds me of why so many people consider OOP an antipattern
I don't come from a CS background, Python very slowly tricked me in to learning OOP !
There are like 3 or 4 longish ancient issues on the tracker discussing refactoring the preparer, distributions, and metadata logic, which definitely do not comprise 1/3 of the pip codebase... π₯΄
And then after you do the work it turns out that someone was relying on some quirks of old implementation and you broke their setup...
can I have a penny for each instance of that?
Well, the goal of the refactoring is that it's actually possible to tweak or add functionality in a maintainable way so the quirks ought to go at some point (or become documented features).
I look forward to the day we can remove the legacy resolver although that probably will be at least a few more years out.
Why would you need that? According to someone posting to the setuptools issue tracker yesterday, everyone who works on critical Python packages are either well paid by tech companies to do so or covered by grants
It's not like I was talking the cost of security keys earlier...
Security keys just magically appear in the hands of critical OSS maintainers.
Haven't read that thread yet though. I'm curious to how badly it devolved.
(oh sorry, actually it was packaging not setuptools), anyway, I was very tempted to give a pretty sharp reply, but decided it was better just to not follow up at all, seems like so far no one else has cared to respond
lol, yup.
lol
Honestly, the relationship between volunteer maintainers and corporate users is already dysfunctional. I don't think there is much point in arguing or continuing to engage with them if it's evident they aren't going to realize that this is all a project of love.
The optimist within me would love to hope that if we continue listening and accommodating their needs when reasonable, they'll come around, but given how modern corporations work, I don't see that changing ever.
I realize that the individual users != soulless mega corporations, but they often come in with the corporate expectations.
In this case, it comes from a University of Oxford CS lecturer, not a corporate user
I replied on the issue to answer the original question, but I don't have issue closure privileges on the packaging repo.
While I initially resisted, I eventually gave in and added a parenthetical comment about the nature of paid contributions (specifically, almost nobody gets paid to keep slow and unreliable APIs working, they get paid to replace them with something better)
History reasons and different people want to use Distribution for different purposes but didnβt want to involve in giant refactoring workβ¦ Things inheriting from BaseDistribution are for the resolver, while those from AbstractDistribution are for the preparer and evaluator.
And, I do have a couple of half-done refactors that have open issues. It wouldn't be the first thing I started doing in pip that ended up being a case off "bit off a lot more than I can chew". π
Okay, so I've found using compileall.compile_dir to provide quite a big speed up over compileall.compile_file, it knocks 25 seconds off installing Airflow on my computer.
However, when I use workers=0 I can not get the output to be quiet, I get a bunch of SyntaxWarnings even if I set quiet=2: https://docs.python.org/3/library/compileall.html#compileall.compile_dir
Anyone know if I can filter a subprocess from printing to stdout or stderr even if I don't have access to the subprocess object?
ChatGPT confidentally gave me a series of wrong answers π
A question, will this negatively impact installation of one to a few small packages? Multiprocessing startup is not free.
Possibly, it's worth benchmarking
Between that and it looking like I can't use compile_dir, a lot more work than expected π¦
@finite perch Are you testing on Linux? IIRC, Linux has the lowest process startup overheads of the big three platforms and those overheads will be about as small as they get there.
Yes, but I will test on both Linux and Windows before making a new PR
FYI a user posted the same issue twice after I closed the first one as a duplicate: https://github.com/pypa/pip/issues/12910. Closed it asking them politely not to do that.
Was very confused when git push wasn't working, took me a while of tinkering to realize github is down
You force pushed too hard 
It's a rite of passage I feel like. You know you do a lot of open source stuff when you have GitHub is down as the reason you can't do a thing you were hoping to do.
(I forgot the top text)
Yeah, not too familiar with this, as all the comapnies I work for very explicitly never rely on anything on the Internet
Fortunately full Github outages aren't tooo common
We'll blame the next one on you :D
Also, gave me a moment to run tests before opening PR and find out it broke about 30% of pip's tests
Hmmm, pip accepts _ to indicate a post version, e.g. 0.1_1 gets converted to 0.1-1 by pip, which is equivalent to 0.1.post1, this is not PEP 440 compliant, going to write up an issue, as this prevents moving some package parsing out of pip into packaging
That is definitely not confusing at all...
Just make very long names for things BaseDistribution -> BaseResolverDistribution, AbstractDistribution -> AbstractPreparerDistribution, some generic class that inherits from both BaseResolverAbstractPreparerDistribution. OO development solved.
@finite perch Another idea for reducing the subprocess penalty for precompiling would be to spin up a pool of subprocesses at the start of the installation process that could batch compile the installed Python files. You'd probably want to gate this both on the maximum processes allowed (e.g., on my system, os.cpu_count() returns 16!!) and also require a minimum amount of files to avoid slowing down "tiny" installations ... which yeah, is a lot of complexity.
Alternatively, you could do all of the batch compiling at the end, but that would change how packages are installed.
I'm not going to propose enabling --no-compile, but I am curious, why do we compile on installation? I wasn't able to find a clear reason in the original PR (from a long time ago).
I had the same idea, however it would require a significant refactoring to know ahead of time how many Python files need to be installed as to whether is worth it.
Where as currently the compile_file step happens at a point where it's knowable how many files are available, so it's easier to put in limiting heuristics.
Yup.
I had planned to make a simple benchmark and test this all this week, but then I got distracted when I was digging through the code for this reported issue (https://github.com/pypa/pip/issues/12911) and found a big regex that can be eliminated (https://github.com/pypa/pip/pull/12917/files#diff-f9e3db06303cb2538cdc54229e6e76ee3b8821d399b655204923ca598c1f3cfc)
Haha, I relate to that.
I try to not get too distracted as I find that working on a bunch of scattered things at once results in nothing being finished :P
Of course, that has the equally bad side-effect that I'm "procrastinating" reviewing the large PRs I've been meaning to review.
I refuse to accept this consequence, might take me years to finish a small task, but I'll get there
Stay involved in open source long enough and you may get to see ideas you once had actually amount to something a decade or more later π
As both a maintainer and contributor, I feel conflicted when PRs languish. On the one hand, I acutely understand the reasons why PRs can stall and take forever to land, but OTOH, it is discouraging to see a PR (or worse, have your own PR) sit untouched for weeks or months on end.
GitHub issues needs a confused emoji reaction
is that not a confused emoji?
If you hover over it, it says "x reacted with confused emoji"
It looks more sad than confused.
Fair
On my screen it doesn't have eyebrows, which makes it look less confused and more unamused or disappointed
Each OS has different emoji designs. Plus, those evolve too.
I cycle through all of those in the course of a day.
It's not obvious windows is slow until you run a benchmark which involves creating a lot of files and processes, and then wow... :/
So yup, my benchmarking shows Windows would generally not benefit from using multiprocessing compile_file
So instead I've raised the question, why not turn off compiling by default: https://github.com/pypa/pip/issues/12920
Have you tried running them on dev drives?
Though that will sort of artificially inflate the benchmarks I guess
Yeah, I don't think I have that feature on Windows 10 anyway, and the idea was to look at the worst performance pip users could commonly face
That used to really be the case until everyone started copying Apple's design, which in some cases is exceptionally ugly and doesn't fit the Unicode description at all. But Apple decided that this is the emotion that it really should be
Androids old Jelly Bean emojis certainly had a lot of character that don't exist any more: https://emojipedia.org/google/android-4.4
If someone with the admin bit for pip could delete this issue that would be appreciated. Someone opened a bug report with their company account which turns out was not OK. They already opened a new one with their personal account. https://github.com/pypa/pip/issues/12905#issuecomment-2278927272
Deleted
i made an issue providing context + an outline of all my metadata resolve work. i just converted all the open PRs to draft except for 3: https://github.com/pypa/pip/issues/12921#issuecomment-2299454418. i implemented parallel wheel downloads a couple days ago but the parallelism one is drafted as it depends on changes to progress bar output (one of the undrafted ones) which i expect we'll want to discuss since it drastically changes the way pip looks
the parallel downloads stuff is totally separate from metadata caching and doesn't touch the requirement preparer logic. one of the open PRs does touch the preparer logic, but it's short and part 1 of 3 which cleans up a lot of the preparer logic to make the caching logic much less intrusive and complex
interested in anyone's input on any of them, including ones in draft mode. i believe all of these PRs are extremely high-quality work and all of them include thorough test cases and docstrings, i'm using the draft status to make it more clear for maintainers which would be helpful to focus on
i was asking for input on mastodon on whether to download bigger wheels first for batched downloads and a friend just suggested making downloads resumable if interrupted which is a GREAT idea and should be orthogonal to the rest / not have any dependencies on other PRs
was linked to this issue for context https://github.com/pypa/pip/issues/4796
I can't speak for the other maintainers, but it is on my to-do list to review your PRs. The blocker is that it all involves parts of pip that I'm wholly unfamiliar with. π I've been reading and tracing through pip's codebase so I'll have the foundational knowledge needed to evaluate your changes.
please don't feel rushed to do so at all, nothing has been bitrotting. sorry for that framing, i only meant to provide context on their readiness for review by non-maintainers in case they were curious or had any specific performance-sensitive use cases they wanted to ask about
i have been using a specific install command to benchmark resolve/download performance but until someone mentioned spotty downloads and resuming interrupted requests a few minutes ago i hadn't considered that angle at all
There is an ancient PR for autoresumption of interrupted downloads, but I have no idea what state it is in.
will check it out
The feature is wanted, but the implementation may be not trivial as A) our cache backend may or may not play nicely with interrupted downloads, and B) partial downloads should probably not persist in the cache forever.
yes! π i was almost upset bc it's obv useful but expect it to be a lot of work and i thought i was done for now
The caching story should improve by the start of 2025 as someone has committed to contributing to pip on related changes which involves the cache, and it was suggested they improve the caching management story.
would def recommend they read through the comments on my resolve workstream thread then as i go into the rationale for why metadata caching is likely to be more appropriate than e.g. parallelism and how it relates to pip use cases (CI vs laptop etc)
hmm unless you mean caching of big downloads
The thing about parallelism is that it's cool and all, but pip currently has zero parallel logic. So, it really should be approached separately as it has its own host of edge cases to consider.
the metadata caching PRs add new cache subdirs
yes this was my argument too
@limber ore
this issue https://github.com/pypa/pip/issues/12921
I don't have time to look right now but if the caching has not improved then in Q4 I do plan on making PRs for an experimental new type that stores wheels unpacked (like UV)
parallelism is still useful but I haven't accounted to spend time on that other than reviews because there is an open PR
if only there were 72 hours in a day
My intuitive feeling is the caching of metadata files (also something uv does) will have a bigger effect on user feeling of snappiness for most users using PyPI, than caching unpacked wheels, it's near the top of my list to try cosmicexplorers PR that implements this
was doing dishes but actually my argument is a little different; i actually do not believe parallelism (except for parallel downloads of large files, which i have already implemented) is likely to achieve any performance that caching cannot
Also, parallelizing the initial index page fetch probably help a fair bit with cold but easy resolves during CI builds.
Of course, CI systems generally have low-latency connections anyway so this is mostly moot :)
actually you can cache this too https://github.com/pypa/pip/pull/12257
I believe the vast majority of people do not use pip caching in CI.
But this is mostly theoretical discussion, caching comes first and then parallelization can come second.
i interviewed for astral and they liked me until i made the mistake of asking about their monetization strategy lol. you actually can store wheels fully zipped and use them for caching, i did it for pex https://github.com/pex-tool/pex/pull/2175
yes, the idea is that the metadata cache can be stored separately from the wheel cache so CI systems can avoid large cache dirs but still achieve resolve perf
totally open to parallelization too but this caching approach would also reduce PyPI bandwidth costs
Pip currently stores downloaded wheels as cachecontrol (i.e. msgpack) HTTP responses. A small optimization that could be done to store the wheels directly, instead of HTTP responses to avoid decoding. I have no idea how much this would help, but it may have a nontrivial impact on large (and I really do mean large) wheels.
not with binary extensions
will definitely investigate this
hm how so?
One positive side effect of storing HTTP Responses is the names are all hashes, wheel names can sometimes get so long they exceed Windows file path length when in a directory that's also a little long, something to be aware of when touching
extension modules must be loaded from disk
ah yeah, right, windows
π
nothing can be considered a small change here
i was mistaken earlier, i believe pex also stores all wheels unpacked for this reason. the reason my technique applied there was because pex was interested in reconstituting zipapps from cached zips, so there was an optimization possible to avoid decompressing entries. sorry about that and very interested in your work on this
pants and spack regularly overrun maximum file path lengths on linux too, i'm the first one to bash windows but this happens a lot in CI
not sure if it would ever be useful for pip itself but have been doing a lot of work on the rust zip crate after getting really into zip file stuff for pip https://github.com/zip-rs/zip2/pull/236. this PR makes zip file extraction much much faster and i haven't been able to find any prior art for similar techniques
There is a PR for pip that implements custom zip extraction code to speed up installs, but once again, it's a lot of complexity for pip to take on. None of us are experts on the ZIP format (AFAIK) and we don't want to (half) implement another zip library in pip.
This is interesting... https://github.com/astral-sh/uv/issues/6279
I'm a bit confused about what the user wants to happen, and if it happens with the latest pip / pip-tools or not
thanks! makes sense. definitely excited to see @ofek's work on caching and wheel extraction, i'm not as familiar with performance of python loading or how to rearrange stuff outside of wheels
oh yeah for example the metadata caching stuff currently writes each dist's metadata into its own file, which is then gzipped but that's still likely not very space-efficient. could probably save a lot of space by merging metadata for dists from the same project together. that may also be faster
I just added some additional ram to my laptop, and I was curious to how running the pip test suite performs. I honestly don't remember the previous performance so I can't say if it's better, however, my god are the keyring tests awfully slow. These results are on a 2021 8-core AMD CPU:
pytest -n8~> 518.62s (0:08:38)pytest -n8 --dist=worksteal~> 383.90s (0:06:23)pytest -n8 --dist=worksteal -k "not keyring"~> 204.82s (0:03:24)
There are a lot of expensive tests (the keyring tests, ahem) and they seem to be often crammed on a few cores to a single core in the last third of the run which is inefficient, the worksteal distribution method seems to mitigate this fairly well. And yup, at least on my system, the keyring tests seem to nearly double the test suite runtime...
Basically they want the packages following an invalid extra to be ignored, in addition to the invalid extra declaration.
I don't think the front end installer should do that without a spec, btw, apache-airflow declares a development extra that they don't export to their metadata, I think they do that through some build magic, but I've not looked at it
I can sit down and take a look some time later tomorrow, I got a backlog of user tickets I know I can help people with this week I haven't had the chance to get to
That "private extra" weirdness sounds to me like a project that should be using a dependency management tool with support for declaring unpublished dependency groups...
Europa has ~84, but the comms latency is brutal π
FYI, I do plan on providing an additional write-up for https://github.com/pypa/pip/issues/11457 so any people that encounter the deprecation warning and follow the link will hopefully have an easier time understanding what it means and what to do. I was going to do that yesterday, but I got side-tracked into writing a larger blog post about pip 24.2 (because it's been a while since I wrote something and this release has a bunch of cool changes... I'm well aware it would be nearly a month late). :P
OK, while it's still a draft, the blog post is in a state where I'm happy to share it for feedback. The optimization section is incomplete, but otherwise, it's mostly fully written. https://hugo-draft.floralily.dev/blog/2024/08/whats-new-in-pip-24.2/
In version 24.2, pip learns to use system certificates, receives a handful of optimizations, and deprecates legacy editable installations.
.