There is no standard in the Python community for versioning. From this, a lot of projects just never constrained their versions while a lot of other projects assume semver when specifying their version constraints, both wrong.
Then there is the problem of there not being a standard dependency management system. Your `setup.py` can specify version constraints. You either over-constrain in there or have to add a whole separate process for locking your constraint.
- You could use `pip-compile` to get a platform-specific locking of constraints, requiring you to run this for every platform and python version you support. At least, since you duplicate `setup.py` into a `requirements.in`, you can override transitive dependencies.
- You could use `pipenv` and just capture what you happened to install, from constraints or directly, from a specific machine
- You could use Poetry which solves most of these problems except they've put their heads in the sand regarding how bad versioning is within the Python ecosystem and refuse to support overriding transitive dependencies despite being modeled off of Rust's Cargo which does support it despite the Rust ecosystem being good with versioning [1]
It depends on how you want to pin. You probably always want the latest API compatible version for a package like cryptography. But as I read from that thread, it seems cryptography doesn't use semver, thus you doing something like `>=3,<4` is not really feasible. In addition, this change was introduced at 3.4.
I disagree. If the library follows semver, or has a predictable way of managing its versions, I would personally set it as broad as possible without breaking compatibility. Especially with something like cryptography. If a critical bug is found, you don't wanna be stuck at a version from a few years ago. Setting a broad pinned version allows you to update this as part of your day to day development.
Then there is the problem of there not being a standard dependency management system. Your `setup.py` can specify version constraints. You either over-constrain in there or have to add a whole separate process for locking your constraint.
- You could use `pip-compile` to get a platform-specific locking of constraints, requiring you to run this for every platform and python version you support. At least, since you duplicate `setup.py` into a `requirements.in`, you can override transitive dependencies.
- You could use `pipenv` and just capture what you happened to install, from constraints or directly, from a specific machine
- You could use Poetry which solves most of these problems except they've put their heads in the sand regarding how bad versioning is within the Python ecosystem and refuse to support overriding transitive dependencies despite being modeled off of Rust's Cargo which does support it despite the Rust ecosystem being good with versioning [1]
[1] https://github.com/python-poetry/poetry/issues/697