openapi-core
openapi-core copied to clipboard
Dependencies should have version specifiers
All dependencies except pytest and Django have no version specifiers. This is dangerous because dependency resolution may decide to use versions of dependencies with which openapi-core is not compatible. Also, breaking changes in dependencies (e.g. when a new major version of a dependency versioned according to Semantic Versioning is released) can lead to sudden malfunction of openapi-core.
I think all dependencies are versioned according to Semantic Versioning. Thus, their minimum versions should be identified and specified. Also, there should be an upper bound, i.e. the next major version should not be included by default unless explicitly tested to avoid sudden malfunction, e.g. django>=2.2,<3 (in case openapi-core does not work with Django 3.x) or django>=2.2,<4 (in case Django 3.x is fine, too). If Tox was used, it would be possible to run the test suite against both Django 2.x and 3.x automatically.
Agreed. That something to have before new major release. 👍
What's your take on the following?
Figuring out the minimum versions of dependencies seems to be quite tricky. I believe there are two questions to answer:
- What's the minimum version of a dependency that offers the API needed by
openapi-core? - Does the test suite of
openapi-corepass for all versions covered by the version specifier? (Just the fact that the API is compatible doesn't mean the behavior/implementation is correct.)
I don't know how to automate 1. correctly. So far, I've run an empirical analysis in which I pinned the version of one dependency and set all others to "*", so that Poetry can determine the compatible versions of the other dependencies, installed the project in a virtual environment and ran the test suite. This experiment resulted (with some manual postprocessing) in the following runtime dependency specification:
[tool.poetry.dependencies]
python = "^3.6.2"
dataclasses = {version = "*", python = "~3.6"}
dictpath = "^0.1"
django = {version = "^3.2", optional = true}
falcon = {version = "^3", optional = true}
flask = {version = ">=1.1.3,<3", optional = true}
isodate = ">=0.4.9,<0.7"
more-itertools = ">=1.1,<9"
parse = "^1.6"
openapi-schema-validator = "^0.1"
openapi-spec-validator = ">=0.2.7,<0.4"
requests = {version = "^2.18.2", optional = true}
werkzeug = ">=0.15,<3"
A couple of notes:
- The
dataclassesbackport library does not appear to be versioned using SemVer. Empirically, the test suite passed for all versions. That's why I think"*"might be reasonable. flaskbefore v1.1.3 is broken because they didn't specify an upper bound on the version ofwerkzeugand whenwerkzeugv2 was released,flaskbroke. In v1.1.3 they changed the version specifier forwerkzeugto exclude v2 and above. See https://github.com/pallets/flask/issues/4027 for more details.requestswas working for some versions before v2.18.2 as well, but there was a relatively large version range before it for which the test suite was failing. Since v2.18.2 was released about 4 years ago, I think we could stick with this version as the minimum required one instead of trying to investigate whether there is a way to support even older ones.
But how about the development dependencies?
- For dependencies related to running the test suite, I think the same rules as for the runtime dependencies apply, i.e. as long as the test suite passes (and, e.g., for
pytest-covas long as the minimum version ofcoveragecan read the configuration frompyproject.toml), the version should be supported. - What about code formatters? For
isortit might be fine to apply the same rules as for any other dependency because it uses SemVer and I assume a new minor release won't change formatting rules, the CLI, and the configuration format in an incompatible way.blackdoes not use SemVer though. - What about the docs-related dependencies? The documentation builds even for
sphinxv2.0 andsphinx-rtd-themev0.1.4, but it looks a bit different, e.g. code blocks have no syntax highlighting.
In general, I think the lock file also comes into play with regards to development dependencies because updating the lock file will typically lead to using more recent versions of those dependencies, e.g. also a more recent version of sphinx and sphinx-rtd-theme.
And finally, there is the general question about using upper bounds for version specifiers (at least for packages that use SemVer). Related to it is this tweet: https://twitter.com/codewithanthony/status/1362181541191766017?s=20
What do you think @p1c2u?