Skip to content

Conversation

@dbnicholson
Copy link
Member

Working on #25 dropped me into dependency hell, so I decided to just slog through the whole thing. After this, the only non-current dependency is aioredis (see #26). The two most non-trivial changes are:

  • Run flake8 and mypy directly instead of using pytest plugins. Not required, but pytest-flake8 is dead upstream and broken with newer flake8.
  • Update to Pydantic 2. Also not required, but there's some unfriendly interactions with mypy in the later 1.x series.

This instructs pipenv to sort entries when adding packages with
`install`. The lists are already sorted, but it's nice to have the tool
honor that choice. This requires pipenv 2023.10.24.
There's no reason we need pytest to be driving this and it results in
less usable output. More importantly, it allows updating flake8 as
pytest-flake8 uses internal flake8 API and does not work with recent
versions of flake8.
Prior to mypy 1.0, `Optional` would be implicitly added to any argument
that defaulted to `None`. Add them explicitly to avoid errors on later
mypy upgrade.
Mypy doesn't check functions with untyped definitions. This is common in
the tests since pytest doesn't support typing, and it's why the mypy
configuration for the tests has `disallow_untyped_defs = False`.

However, newer mypy will notify you if you have type hints in the body
of an untyped function under the assumption that you forgot to make the
function typed. You can also set `check_untyped_defs = True`, but that
fails here on external packages like freezegun. Just remove the `Redis`
type hint since mypy isn't validating it anyways.

1. https://mypy.readthedocs.io/en/latest/error_code_list.html#notify-about-an-annotation-in-an-unchecked-function-annotation-unchecked
This adds the type definitions for the toml package, which will be
necessary when upgrading mypy.
Pydantic 2 changes requires migration[1]. For now, pin to Pydantic 1 to
keep using the existing syntax. Unfortunately, Pydantic 1.9 introduces a
new type for error details that breaks our type checking. Also
unfortunately, Pydantic 1.8.2 breaks with mypy 0.920, so also pin that.
Both will be cleaned up in a subsequent update to Pydantic 2.

1. https://docs.pydantic.dev/latest/migration/
Running async tests requires explicit handling in pytest 8. Pin these
for now so the tests continue to work. This will be fixed in a
subsequent commit.
This matches what's currently used in Endless OS and Debian stable. Note
that specifying `python_version` in `Pipfile` will cause pipenv to try
to use Python 3.11 if it's available. It will fallback to the default
Python on the system with a warning if that's not available.
With the pins in place, update all the dependencies so they're separated
from any explicit upgrades.
Newer pytest requires a plugin to run async test functions.
pytest-asyncio will be installed as a dependency of newer
pytest-aiohttp, but the tests aren't automatically marked for use with
pytest-asyncio. Explicitly add pytest-asyncio and configure it for auto
mode[1] so it does that.

1. https://pytest-asyncio.readthedocs.io/en/latest/concepts.html#auto-mode
The pydantic usage here is pretty light, so the changes needed aren't
that dramatic.

* The dataclass `__post_init_post_parse__` method is no longer supported
  and simply `__post_init__` should be used.

* `TypeError` is no longer converted to `ValidationError` in validators,
  so just use `ValueError`.

* The `@validator` decorator has changed to `@field_decorator` with a
  minor change in parameters.

* Validator error messages now include the error type, which means
  `Value error` for all of our validators.

* The `ValidationError.errors()` detail list now has a custom
  `ErrorDetail` type. This exposes the fact that the `loc` attribute is
  actually a tuple of `str` and `int`. Mypy flags that as an issue if an
  `int` is passed to `str.join`. We don't actually have any cases where
  an `int` would occur, but copy a converter from the documentation so
  it's handled correctly in case that does happen.

This also allows dropping the mypy upper version pin as updated Pydantic
contains the necessary compatibility fix.

https://docs.pydantic.dev/2.7/migration/
@wjt wjt merged commit b8803b4 into master May 23, 2024
@wjt wjt deleted the python-3.11 branch May 23, 2024 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants