pip check is your digital detective for Python package dependencies, and it’s surprisingly good at catching subtle but critical incompatibilities that can derail your application.
Here’s pip check in action, simulating a common dependency conflict scenario:
# First, let's create a situation where we have conflicting requirements.
# Imagine we have a project that needs 'requests' version 2.20.0,
# but also another package, 'my-utility', which explicitly requires
# 'requests' version < 2.20.0.
# Simulate installing these:
# (In a real scenario, these would be installed via pip install)
# Assume 'requests' 2.20.0 is already installed.
# Now, let's try to install 'my-utility' that has an incompatible requirement.
# --- Simulated Environment ---
# Imagine your requirements.txt or installed packages look like this:
# requests==2.20.0
# my-utility==1.0.0 # (This package internally requires requests<2.20.0)
# ---------------------------
# Now, run the check:
# pip check
When you run pip check in this simulated environment, you’d see output like this:
requests 2.20.0 has requirement idna<2.8,>=2.5, but you have idna 2.8.
my-utility 1.0.0 has requirement requests<2.20.0, but you have requests 2.20.0.
This output tells you:
requests 2.20.0 has requirement idna<2.8,>=2.5, but you have idna 2.8.: This means thatrequestsversion 2.20.0 itself has a dependency onidnathat must be between 2.5 and 2.8 (exclusive of 2.8). However, your environment currently hasidnaversion 2.8 installed, which violates this requirement. This is a direct conflict within therequestspackage’s own dependencies.my-utility 1.0.0 has requirement requests<2.20.0, but you have requests 2.20.0.: This is the core conflict we simulated. Yourmy-utilitypackage requires a version ofrequestsolder than 2.20.0, but you haverequestsversion 2.20.0 installed.
pip check works by examining the METADATA (or PKG-INFO) file within each installed package. This file contains a Requires-Dist field, which lists the package’s dependencies and their version specifiers. pip check then compares these declared requirements against the versions of packages actually installed in your environment. If any installed package’s version does not satisfy the Requires-Dist constraints of another installed package, pip check reports it. It’s not just checking your top-level requirements.txt; it’s inspecting all installed packages and their transitive dependencies.
The primary problem pip check solves is dependency hell. When you have multiple packages in your project, and each package has its own set of dependencies, it’s very common for these dependencies to overlap and conflict. For example, Package A might need libraryX>=1.0 and Package B might need libraryX<1.5. If you install both A and B, and your environment ends up with libraryX==2.0, then Package A will work, but Package B will break. pip check is the tool that surfaces these hidden incompatibilities before your application starts throwing obscure runtime errors.
To fix the simulated error:
You need to reconcile the conflicting requirements. The most straightforward way is to find a version of my-utility that is compatible with requests 2.20.0, or downgrade requests to a version that my-utility can use, while ensuring other packages still work.
Let’s assume my-utility has a newer version, say my-utility==1.1.0, which is compatible with requests==2.20.0.
- Identify the conflicting package and its requirements: In our example,
my-utilityis the problematic one, requiringrequests<2.20.0. - Consult package metadata or changelogs: Look for newer versions of
my-utilitythat might have updated theirrequestsdependency. - Upgrade the conflicting package (if a compatible version exists):
(Assumingpip install --upgrade my-utility==1.1.0my-utility 1.1.0now requiresrequests>=2.20.0or has no strict upper bound that conflicts with2.20.0).
If upgrading my-utility isn’t an option, you’d have to downgrade requests. This might break other parts of your application that do rely on features in requests 2.20.0.
pip install "requests<2.20.0"
After making the fix (e.g., upgrading my-utility), you would run pip check again to confirm:
pip check
The output should now be clean:
No broken requirements found.
The idna issue is a secondary conflict. requests 2.20.0 requires idna < 2.8, >= 2.5. If pip check reported idna 2.8 was installed, it means idna was likely installed independently or as a dependency of another package, and its version was updated past the requirement of requests. Fixing the my-utility conflict might resolve this too if my-utility was the one pulling in the newer idna, or you might need a separate pip install "idna<2.8,>=2.5" to satisfy requests.
Common causes for pip check failures include:
- Directly installing conflicting versions: Manually installing one package, then another that requires a different, incompatible version of the first.
- Transitive dependency conflicts: Package A requires
libX==1.0, and Package B requireslibX==2.0. If you install A and B,pipwill install one version oflibX, leaving the other package unsatisfied.pip checkwill catch this. - Outdated packages: Installing an older package that has strict, outdated dependency requirements that are now incompatible with newer versions of other common libraries.
- Environment drift: Over time, as you install and uninstall packages, or upgrade individual ones, the dependency graph can become messy, leading to subtle conflicts that
pip checkreveals. - Pinning issues: Not pinning dependencies correctly in
requirements.txtcan lead topipresolving to incompatible versions during an install. - System-level packages: Sometimes, a Python package’s dependency might also be a system-level library, and an update to the system library breaks the Python package.
pip checkwon’t see system libraries, but it will see the resulting Python package incompatibility.
The next error you’ll likely hit after fixing pip check issues is a ModuleNotFoundError or an AttributeError when your code tries to import or use a function from a package that pip check flagged as broken, but you haven’t yet addressed in your application code.