tox-dev / pipdeptree

A command line utility to display dependency tree of the installed Python packages
https://pypi.python.org/pypi/pipdeptree
MIT License
2.77k stars 151 forks source link

pipdeptree doesn't work against devendored pip #395

Closed mgorny closed 2 months ago

mgorny commented 2 months ago

What pipdeptree version are you using?

2.23.1

Are you running pipdeptree in a virtual environment?

No

Describe the problem

pipdeptree directly imports Python packages vendored within pip. As a result, it doesn't import when pip is debundled and uses system packages:

$ python3.12 -m pytest
ImportError while loading conftest '/tmp/portage/dev-python/pipdeptree-2.23.1/work/pipdeptree-2.23.1/tests/conftest.py'.
tests/conftest.py:11: in <module>
    from pipdeptree._models import PackageDAG
../pipdeptree-2.23.1-python3_12/install/usr/lib/python3.12/site-packages/pipdeptree/_models/__init__.py:3: in <module>
    from .dag import PackageDAG, ReversedPackageDAG
../pipdeptree-2.23.1-python3_12/install/usr/lib/python3.12/site-packages/pipdeptree/_models/dag.py:17: in <module>
    from .package import DistPackage, InvalidRequirementError, ReqPackage
../pipdeptree-2.23.1-python3_12/install/usr/lib/python3.12/site-packages/pipdeptree/_models/package.py:15: in <module>
    from pipdeptree._adapter import PipBaseDistributionAdapter
../pipdeptree-2.23.1-python3_12/install/usr/lib/python3.12/site-packages/pipdeptree/_adapter.py:13: in <module>
    from pip._vendor.packaging.version import Version  # noqa: PLC2701
E   ModuleNotFoundError: No module named 'pip._vendor'

I'm guessing this is done to workaround the isinstance() problem that is inflicted by multiple packages vendoring packaging. However, can we have a fallback to system packaging when the one in pip doesn't import (indicating it's been debundled)?

kemzeb commented 2 months ago

Thanks for the bug report. I haven't heard of a debundled pip before, but this would be a simple enough fix.

I did read into debundled pip docs, and one question I have is why doesn't pip._vendor exist? According to these docs, it should exist in your environment; I guess this is needed so that they can use their vendor aliasing feature. They do have a vendor alias to packaging.version (see here).

mgorny commented 2 months ago

We're following a different approach, since the "official" approach is broken (and doesn't seem well supported).

gaborbernat commented 2 months ago

Well pip only supports the official way, anything else is unsupported and you're out of luck.

mgorny commented 2 months ago

Well pip only supports the official way, anything else is unsupported and you're out of luck.

Do you want bug reports for it then? I presumed it's only semi-supported.

gaborbernat commented 2 months ago

This is a pip bug at best, but I believe it is just purely unsupported by them.

eli-schwartz commented 2 months ago

Importing pip as a python library rather than executing it via runpy / subprocess.run([sys.executable, '-m', 'pip']) is much more unsupported than people patching pip.

Which I guess leads me to: why is this being imported from pip._vendor at all, given that pipdeptree already depends on the packaging module and therefore shouldn't need to import a vendored copy from pip?