Personalmente no me gusta el acercamiento que sigue, es tratar de seguir otras ‘formas’ que se usan con otros lenguajes y meterlo con calzador en Python. He usado rbenv, bundler, npm, composer, y en esos casos si tienen sentido los ficheros .lock, en Python creo que choca un poco contra la propia filosofía del lenguaje.
El no poder tener varias versiones de la misma dependencia, y el usar un único namespace plano, hace que fijar las dependencias concretas sea mucho más difícil en Python. La respuesta de la comunidad a esto ha sido hacer librerías donde se respeta el interfaz a lo largo de diferentes versiones, y usar ciclos de deprecación largos, por eso de la ‘una única manera obvia’.
Esto al final lleva a usar siempre la última versión, lo cual es una ventaja en términos de seguridad y mantenibilidad del código, pero tiene sus desventajas cuando uno se enfrenta a cambios que rompen la retrocompatibilidad.
Todavía queda mucho camino en la gestión de dependencias en Python. Yo creo que Poetry va más encaminado, aunque hace falta una definición estándar (están en ello).