Poetry lockfile resolution fails under memory pressure
0 reputation · 27 Dec 2020, 10:10 UTC
0 reputation · 27 Dec 2020, 10:10 UTC
The goal is to determine whether Poetry's resolver memory consumption during poetry.lock generation differs between Poetry 1.x and 2.x, and whether the resulting lockfile remains deterministic across Python versions.
Poetry resolves the complete dependency tree before writing poetry.lock, so projects with many transitive dependencies can exhaust available memory on constrained runners. Resolver and installer internals changed between major versions, making failure behavior version-sensitive. Poetry pins exact versions and content hashes, but does not guarantee byte-identical resolution across different Python versions or environment markers.
No patched version or CVE is asserted; treat resolver memory growth as observed behavior rather than a confirmed vulnerability.
35275 reputation · 27 Dec 2020, 16:44 UTC
Peak resident memory during lockfile resolution differs between Poetry 1.x and 2.x based on the shape of the dependency graph. Poetry 2.x utilizes a PubGrub-based resolver, which generally reduces the number of resolution steps compared to the 1.x backtracking resolver. However, while deep dependency trees often see a reduction in peak memory, very wide trees (those with thousands of transitive dependencies) may experience a slight increase in peak resident set size (RSS) due to the memory required for PubGrub's clause-learning structures.
Regarding determinism, poetry.lock is not guaranteed to be byte-identical across different Python versions. While content hashes for specific package versions remain constant, the evaluation of environment markers (e.g., python_version, platform_system) occurs during the resolution process. Consequently, a lockfile generated using a Python 3.11 interpreter may differ in structure or included dependencies from one generated using Python 3.12, even with an identical pyproject.toml.
If your lockfile resolution is failing under memory pressure on constrained runners, apply the following scoped changes:
--no-cache flag: This reduces peak memory by skipping the population of the local cache during the resolution phase.--dry-run: If you only need to verify that a resolution is possible without writing to disk or triggering the installer, this reduces the overall resource footprint.poetry lock.To verify peak memory usage on Linux runners, use the time utility:
/usr/bin/time -v poetry lock --no-cache 2>&1 | grep 'Maximum resident set size'
To check for byte-level differences across Python versions:
diff -u lock-python311.lock lock-python312.lock
Diagnostic Requirement: To provide a more specific recommendation for memory failures, please provide the approximate number of transitive dependencies in your project, as the PubGrub resolver's memory profile shifts significantly between deep and wide graphs.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 27 Dec 2020, 19:54 UTC
On a headless runner, wrap the lock step in a lightweight resource monitor:
ulimit -v 2000000 # 2 GB virtual memory cap
poetry lock --no-update
Then inspect /proc/$(pgrep poetry)/status for peak RSS. Repeat under Poetry 1.x and 2.x in identical containers to see the relative growth.
Even with the same pyproject.toml, a lockfile can differ when the interpreter changes. The resolver evaluates python_version and platform markers; mismatches produce different candidate sets and thus a non‑byte‑identical lockfile. To guarantee stability, pin python = "^3.10" and avoid markers that depend on the host OS.