activitysim
activitysim copied to clipboard
Implement dependency lock for stability, consistency, and reproducibility
ActivitySim relies on numerous third-party Python packages, i.e., its dependencies. ActivitySim users occasionally report installation and/or runtime failures due to these dependencies (#919, #921). This typically happens when one or more of the dependencies is updated to a new version. Unless explicitly specified, ActivitySim looks for and installs the latest versions of its dependencies. The latest versions of dependencies can conflict with each other and/or have API updates that are no longer backward compatible with ActivitySim.
ActivitySim’s current solution is to specify version ranges for select dependencies, see here for an example. When conflicts arise, additional dependencies are added to this list. This approach has been effective, but is passive and sub-optimal: new conflicts are bound to arise. Recently, users have not been able to install and run ActivitySim because one of its second order dependencies (i.e., a dependency of a dependency), “multimethod”, has a new version that is not compatible with ActivitySim (#919). Therefore, the ActivitySim Consortium desires a more proactive solution.
This is a common problem in Python and a common solution is to “lock” Python dependencies to create “deterministic” builds (i.e., specify versions of each dependency, including dependencies of dependencies, used by ActivitySim). Locking Python dependencies improves consistency, reproducibility, and stability across environments for development, testing, and production.
There are many tools available for locking Python dependencies. With tools like uv, pdm, or poetry, the exact versions of all dependencies ActivitySim requires are specified, reducing the chances of unexpected issues caused by updates or version mismatches.