question 295 Packaging & Databases · medium
Pin a project's dependencies
Before a release, the team turns the version ranges in pyproject.toml into exact pins, using the versions that passed the tests. Write pinned_lines(pyproject_text, installed): one name==version line per dependency in [project].dependencies, with the name normalised (lower case, runs of -, _, . as one -), sorted by name, each package once.
Function
pinned_lines(pyproject_text, installed)pyproject_textTOML text; dependencies look like
"pandas[parquet]>=2.2,<3" or "tomli; python_version < '3.11'"installeda dictionary from package name to version, e.g.
{"Pandas": "2.2.2"} (names may be written in any style)Returnsa sorted list such as
['pandas==2.2.2', 'requests==2.32.3']; [] when there are no dependenciesRaises
ValueError naming the package when a dependency isn't installedExamples
callpinned_lines('[project]\nname = "market-reports"\nversion = "1.4.2"\ndependencies = ["requests>=2.31", "pandas[parquet]>=2.2,<3"]\n', {'requests': '2.32.3', 'pandas': '2.2.2'})returns['pandas==2.2.2', 'requests==2.32.3']
callpinned_lines('[project]\nname = "market-reports"\nversion = "1.4.2"\ndependencies = ["tomli; python_version < \'3.11\'"]\n', {'Tomli': '2.0.1', 'rich': '13.7.1'})returns['tomli==2.0.1']
callpinned_lines('[project]\nname = "notes"\n', {'requests': '2.32.3'})returns[]