In Post-install script with Python setuptools, this answer shows how to make a post-install
command.
I want to make a post-install
command that checks for a version matchup between sub-packages from a mono-repo.
How can I get a list of packages being installed during a post-install
command?
Current Attempt
from pkg_resources import working_set
from setuptools import setup
from setuptools.command.install import install
class PostInstallCommand(install):
REPO_BASE_NAME = "foo"
def run(self) -> None:
install.run(self)
one_subpkg_name = f"{self.REPO_BASE_NAME}-one"
another_subpkg_name = f"{self.REPO_BASE_NAME}-another"
test_subpkg_name = f"{self.REPO_BASE_NAME}-test"
all_versions: list[str] = [
working_set.by_key[one_subpkg_name].version,
working_set.by_key[another_subpkg_name].version,
working_set.by_key[test_subpkg_name].version,
]
if len(set(all_versions)) != 1:
raise NotImplementedError(
f"test package {test_subpkg_name}'s installed versions "
f"{all_versions} have a mismatch."
)
setup(
...,
cmdclass={"install": PostInstallCommand}
)
This solution using pkg_resources.working_set
errors out, it seems working_set
doesn't function at install-time:
...
File "/private/var/folders/41/wlbjqvm94zn1_vbrg9fqff8m0000gn/T/pip-build-env-1iljhvso/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 1217, in run_command
super().run_command(command)
File "/private/var/folders/41/wlbjqvm94zn1_vbrg9fqff8m0000gn/T/pip-build-env-1iljhvso/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 987, in run_command
cmd_obj.run()
File "<string>", line 39, in run
KeyError: 'foo-one'
Further Information
Why can't we simply pin versions? Long story short we use setuptools_scm
's get_version
to dynamically synchronize versions housed in a requirements.txt
, so we don't have access to the versions up front.
I'm not sure if going down this path is best practice, but if you really wanted to you could just run a pip freeze
after installation, parse the outputs into an array of sets/dicts and do a Set.difference()
across the array items.
subpackage_deps = [
{"foo=1.1.0", "bar=1.0.0"},
{"foo=1.1.0", "baz=2.0.1"}
]
subpackage_deps[0] - sub package_deps[1]
I, however, don't see the purpose in doing this. Why not let setup tools do its job? If you are concerned about consistency between projects, why not write an automated test and enforce it using continuous integration to ensure parity of dependency versions between sub-projects (ie: by comparing dependency versions accross setup.py
)?