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-core
pass 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
dataclasses
backport 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. -
flask
before v1.1.3 is broken because they didn't specify an upper bound on the version ofwerkzeug
and whenwerkzeug
v2 was released,flask
broke. In v1.1.3 they changed the version specifier forwerkzeug
to exclude v2 and above. See https://github.com/pallets/flask/issues/4027 for more details. -
requests
was 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-cov
as long as the minimum version ofcoverage
can read the configuration frompyproject.toml
), the version should be supported. - What about code formatters? For
isort
it 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.black
does not use SemVer though. - What about the docs-related dependencies? The documentation builds even for
sphinx
v2.0 andsphinx-rtd-theme
v0.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?