pip install foo==0.1.0, and pip finds
/local/path/to/foo-0.1.0-py3-none-any.whl, why doesn’t pip by default go ahead and install it? At least in my case, it still seems to be using network traffic and time by going out and querying indices when it would seem like the default behavior might identify this as the
BestCandidateResult and short circuit checking elsewhere.
Some context: r/learnpython/comments/nkv159/why_does_pip_search_indexes_when_a_local_wheel_is/ (sorry, new user 2 link limit)
Tox was taking literally hours to run my testing suite on my speedy new M1 Mac, even though the project is laughably small and has minimal dependencies; in debugging, it looks like my local
devpi server is running extremely slowly for some reason, roughly 20 seconds per package.
Regardless, I was surprised that devpi mattered at all; I had
wheeled my dependencies prior to running my test suite, and I could see with
pip install -vvv that it was finding these wheels. However, it was still querying the indices I’ve set up in my
pip.conf, and for some reason it was still downloading the wheels from my devpi server even though a local wheel was available (still trying to figure this out).
When a specific version is requested, isn’t finding a compatible wheel on the local filesystem about as good as it gets? I know I can set
--no-index and get this behavior, but it seems like having the default be that pip searches indices for a file that it has already found locally seems odd.
Would it be reasonable to refactor
get_applicable_candidates + relevant logic into a generator (instead of the
sorted greediness) that looked through local filesystems first, and if a specific version is requested and a matching candidate is found, short-circuits the subsequent network requests?
Just imagining something like:
def get_candidates() -> t.Generator[candidate]: ... for candidate in local_candidates: yield candidate for candidate in remote_candidates: yield candidate def find_best_candidate() -> candidate: candidates =  for candidate in get_candidates(): if specific_version_requested() and matches_requested_version(candidate) and is_local(candidate): return candidate candidates.append(candidate) return max(candidates, key=self._sort_key)