Package: iso-freeze
iso-freeze: Usepip install --reportto separate pinned requirements for different optional dependenciesWarning: The--reportoption ofpip installis considered experimental. Expect stuff to break after pip updates.pip 22.2introduced thepip install --reportoption, which together with the--dry-runand--ignore-installedoptions can be used to resolve requirements without installing them. While the classicpip freezealways pins everything installed, this makes it possible to pin requirements independently from your current environment.iso-freezeis an experimental application that uses these newpipoptions to pin requirements. Just specify arequirementsfile or dependencies in yourpyproject.tomland it uses the output ofpip install --reportto generate pinned*requirements.txtfiles. You can also sync packages installed in your virtual environment with the output ofpip install report.This makesiso-freezea very simple version of thepip-compileandpip-synccommands provided bypip-tools. The biggest difference is that isiso-freezedoes not rely on anypipinternals.InstallThe recommended way to installiso-freezeis withpipx:pipxinstalliso-freezeHowever, you can of course installiso-freezein your local venv via pip:python-mpipinstall--upgradeiso-freezeUsageYou can useiso-freezeeither with aPEP621 compatiblepyproject.tomlfile or withrequirementsfiles.Let's assume you're currently in the directory where yourpyproject.tomlfile is stored and you want to pin the base dependencies of your project. Simply call:iso-freeze# OR `iso-freeze pyproject.toml` if you like to be explicitAfterwards, your pinned requirements are stored inrequirements.txt:# Top level requirements
iso-freeze==0.0.11
# Dependencies of top level requirements
tomli==2.0.1If you would like to pin requirements for a specific optional dependency listed in yourpyproject.tomlfile, saydevdependencies, you can specify it with the-d/--dependencyflag. Ideally you will use it in combination with the-o/--outputflag to specify the name and location of the file you want to store the pinned requirements in:iso-freeze-ddev-odev-requirements.txt# OR `iso-freeze pyproject.toml -d dev -o dev-requirements.txt`For working with requirements files,iso-freezefollows the convention established bypip-toolsand assumes you store your unpinned top-level requirements in*requirements.infiles. So if you're currently in the directory that contains yourrequirements.infile, you can also just call the following to create or update yourrequirements.txt:iso-freezeNote: If you have both arequirements.inand apyproject.tomlfile in the same directory,requirements.inis preferred ifiso-freezeis called without specifying a file name.To pin requirements from a different*requirements.infile, simply specify it:iso-freezerequirements/dev-requirements.in-orequirements/dev-requirements.txtBy default,iso-freezewill use whatever Python interpreter is currently activate in your shell by callingpython3 -m pip install. If you need a different version of Python, you can specify it with the--python/-pflag:iso-freezepyproject.toml-ppython3.11-o311-requirements.txt# Or specify full path if the Python version you need is not in your PATH:iso-freezepyproject.toml-p/Library/Frameworks/Python.framework/Versions/3.11/bin/python-o311-requirements.txtYou can pass arguments directly topip installwith the--pip-argsflag:iso-freezedev-requirements.in--pip-args"--upgrade-strategy eager --require-hashes"Please note that by default,iso-freezecallspipas follows:# If dependencies come from pyproject.tomlenvPIP_REQUIRE_VIRTUALENV=falsepython_exec-mpipinstall-q--dry-run--ignore-installed--report-package1package2# If dependencies come from a requirements fileenvPIP_REQUIRE_VIRTUALENV=falsepython_exec-mpipinstall-q--dry-run--ignore-installed--report--rrequirements_fileenv PIP_REQUIRE_VIRTUALENV=falseis set to ensure that this command will not fail ifrequire-virtualenv = trueis set inpip.conf. Arguments added with--pip-argswill be injected after theinstallkeyword. Example: Callingiso-freeze dev-requirements.in --pip-args "--upgrade-strategy eager"will result in the following command:envPIP_REQUIRE_VIRTUALENV=falsepython3-mpipinstall--upgrade-strategyeager-q--dry-run--ignore-installed--report--rdev-requirements.inSyncWith the--sync/-sflag,iso-freezesyncs your current environment with the output ofpip install --report:iso-freezepyproject.toml-ddev--syncThis will remove any packages that are not dependencies ofdev, install missing packages and update existing packages to match the exact versions provided in thepip install --reportoutput.Warning: Be careful when combining the--syncand--pythonoptions. For example:iso-freezepyproject.toml-ddev--sync--pythonpython3.11This command would install your dependencies globally! If used in combination with--sync, the--pythonflag should point to the executable of a virtual environment. Using--syncwithout the--pythonflag when no virtual environment is activated will install packages globally too. For security, consider addingrequire-virtualenv = trueto yourpip configuration.Note that--syncignores editable installs.Hashesiso-freezehas limited support for adding hashes becausepip install --reportonly provides one hash for the exact file used to install a package on your system. You can include hashes with the--hashesflag:iso-freezepyproject.toml-ddev--hashesThis creates an output like this (truncated example):# Top level requirements
pytest==7.1.2 \
    --hash=sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c
# Dependencies of top level requirements
attrs==21.4.0 \
    --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4