question 487 Application Delivery · medium
Why is this package installed?
pip-compile writes, under each pinned package, which packages required it: # via pandas on one line, or # via followed by one name per comment line. -r requirements.in means you asked for it directly. Turn a lock file into a dictionary that answers "why is this installed?"
Function
why_installed(lock_text)Pin line
name==version, possibly followed by \ and indented --hash=… lines (ignore those)Via commentsafter a pin:
# via a (one reason), or # via then lines # a (one reason each)Reasons
-r requirements.in becomes "direct"; other reasons are package namesReturns
{package: sorted list of reasons} for every pinned package, in the order the pins appear; a pin with no via comment gets []Examples
callwhy_installed('# This file is autogenerated by pip-compile\nnumpy==2.1.3 \\\n --hash=sha256:2f10e1910e389422d852df6d9860305296fb716610ca6d234c5ca410b550b12b\n # via pandas\npandas==2.2.3 \\\n --hash=sha256:53b4e41aa9e92b1cdec11db92d9d0f33db738f6ad4e4a942bbb11ec32886fdcd\n # via -r requirements.in\nsix==1.17.0\n # via\n # python-dateutil\n # rfc3339-validator\n')returns{'numpy': ['pandas'], 'pandas': ['direct'], 'six': ['python-dateutil', 'rfc3339-validator']}
callwhy_installed('rich==13.9.4\n')returns{'rich': []}
callwhy_installed('tzdata==2025.1\n # via pandas\n')returns{'tzdata': ['pandas']}