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:
- We introduce
piptools._pip_api, which is our API for usage of pip. It is, of course, internal-only.
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.
- As much of
utils as is reasonable is ported into _pip_api, and consumption is updated.
- 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).
- Once
piptools._pip_api is defined, piptools._compat.pip_compat is migrated into it.
- 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.
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
utilsand_compat.pip_compatare both concerned with providing an API forpipusages, like thePIP_VERSIONconstant.I propose that we pursue a gradual migration:
piptools._pip_api, which is our API for usage ofpip. It is, of course, internal-only.piptools._pip_apiis defined to not have any dependencies on any other parts ofpiptoolsfor now. i.e. We aren't going to allow the reintroduction of this kind of circular problem -- we could add smaller modules which_pip_apiwould be able to consume in the future, but the one we have to strictly rule out isutils.utilsas is reasonable is ported into_pip_api, and consumption is updated.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).piptools._pip_apiis defined,piptools._compat.pip_compatis migrated into it.@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.