Poetry 1.5: Unresolved Circular Dependency Behavior in Plugin Architectures
0 reputation · 20 Dec 2021, 15:49 UTC
0 reputation · 20 Dec 2021, 15:49 UTC
Poetry 1.5 enforces deterministic dependency resolution using pyproject.toml as the sole configuration source and a poetry.lock file to pin exact versions. The resolver prefers the lockfile over the TOML to maintain parity across environments.
In plugin-based projects, the core package may depend on a plugin that, in turn, declares a dependency back on the core or on another plugin, creating a circular dependency loop. The current resolver can satisfy straightforward cycles, but the behavior for more complex, multi‑layered circular graphs is not fully documented.
Key constraints include the resolver’s reliance on a single source of truth, the necessity to keep the lockfile deterministic, and the fact that updates to one dependency may cascade to others if constraints allow.
Unresolved questions:
35275 reputation · 21 Dec 2021, 03:05 UTC
The documented behavior is that Poetry 1.5 will successfully resolve cycles only if the version constraints are mutually compatible. If the resolver can find versions of A and B that satisfy each other's requirements, it will generate a valid poetry.lock file. However, if the constraints are exclusive (e.g., A requires B>=2.0, but B requires A<=1.0), the resolver will fail with a SolverProblemError.
There is no native mechanism within Poetry to 'ignore' or 'break' a loop in the pyproject.toml file. The resolver is deterministic and requires a complete, valid graph before the lockfile can be finalized.
If you are encountering unresolved loops in a multi-layered architecture, follow these steps to resolve them:
pyproject.toml (e.g., using * or wider caret ranges) to allow the resolver to find an overlapping version set.optional = true flag for one leg of the cycle. This removes the dependency from the default resolution path unless the specific extra group is explicitly requested.To identify exactly where the circular constraint is failing, run the locking command with maximum verbosity to trace the PubGrub decision-making:
poetry lock -vvv
This output will show the specific versions being considered and the point where the circular constraint becomes unsatisfiable.
Note: Even if Poetry successfully locks a cycle, runtime ImportError may occur in Python if the code does not handle partial module initialization correctly.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 20 Dec 2021, 20:50 UTC
Poetry 1.5's resolver terminates resolution when a circular dependency spans multiple plugin layers, emitting a CircularDependency exception before lockfile generation.
A practical verification approach involves running poetry lock after adjusting pyproject.toml constraints and diffing the resulting lockfile to observe whether the resolver preserves or breaks the cycle based on updated version pins.
This recomputation treats the lockfile as the single source of truth, and constraint adjustments may influence the dependency graph's composition on subsequent lockfile generation.