I’m having difficulties understanding and implementing a few details of Python packaging using pip
and setuptools
.
Suppose I have three projects, A
and B
and C
each of which is its own package and hosted in its own code repo. They also depend on each other, i.e. A
is imported by B
, and B
is imported by C
. Each package has a set of direct dependencies (i.e. directly imported other packages) and a set of indirect dependencies (i.e. packages imported by the directly dependent packages). These dependencies are a graph, not a tree.
For package A
, should setup.py contain only the directly dependent packages? Same for package B
? When I then pip install C
I noticed that B
gets installed, but not A
. I suppose that is because A
is an indirect dependency for C
.
I don’t really like the idea of storing a pip freeze
in each package (inflexible and conflicts loom), but it seems that pip
does not resolve the dependency graph recursively (see here). The snakebasket
project attempted to address that problem, but is stale now; the dependency-links option has been deprecated.
What is the proper and recommended way of handling this?
Addendum I forgot to mention that none of the packages (A
, B
, C
) are available through the official PyPi repo, but live in private Github repos. Thus, for example B
’s setup.py contains
install_requires=(
…,
A==1.0.0,
…,
)
dependency_links=[
f"https://{github_token}@github.com/repo/A/archive/v1.0.0.tar.gz#egg=A-1.0.0",
],
and C
contains a similar setup for package B
.