Skip to content

Reduce circular dependencies between utils.py and _compat/ by migrating pip-related utilities into a new _pip_api #2285

@sirosen

Description

@sirosen

I've been bitten a couple of times by the circular relationship between "utils" and "_compat", and we have some old PRs which got snagged on it as well. (I was trying to port the changes in #2108 forward.) The current module structure is not right in terms of defining dependencies between components -- if you try to migrate any component from "utils" into "compat", you create cycles.
"utils" is also a generally disliked component name, since it doesn't contain important information about its contents.

Tinkering a bit in the repo today, and trying to decide on a path forward, I started to focus on the fact that utils and _compat.pip_compat are both concerned with providing an API for pip usages, like the PIP_VERSION constant.

I propose that we pursue a gradual migration:

  1. We introduce piptools._pip_api, which is our API for usage of pip. It is, of course, internal-only.
  2. piptools._pip_api is defined to not have any dependencies on any other parts of piptools for now. i.e. We aren't going to allow the reintroduction of this kind of circular problem -- we could add smaller modules which _pip_api would be able to consume in the future, but the one we have to strictly rule out is utils.
  3. As much of utils as is reasonable is ported into _pip_api, and consumption is updated.
  4. Testing is also dir structured, into tests/pip_api/test_{module_name}.py (we have too many tests in a flat dir at present, IMO. I want some better organization to the testsuite so that I can find things).
  5. Once piptools._pip_api is defined, piptools._compat.pip_compat is migrated into it.
  6. Celebrate! Then reassess and look for more ways to reduce circularity and improve module structure.

@webknjaz, looking for your feedback on this in particular. I have some initial work I'll turn into a draft PR to demo the idea.

Metadata

Metadata

Assignees

Labels

refactorRefactoring code

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions