- Compatibility with older Python versions
- use `Optional` and `Union` instead of `... | None` and `a | b`
- use `typing_extensions.Protocol` instead of `typing.Protocol`
- use `typing.Dict`, `typing.List`, etc. instead of the concrete types.
- Fix backend `.get()` annotations; not all were marked as `Optional[str]`
- Don't return anything from `Backend.set()` methods.
- The `Coder.decode_as_type()` type parameter must be a type to be
compatible with `ModelField(..., type_=...)`.
- Clean up `Optional[]` use, remove where it is not needed.
- Clean up variable use in decorator, keeping the raw cached value
separate from the return value from the wrapped endpoint.
- Annotate the wrapper as returning either the original type _or_ a
Response (returning a 304 Not Modified response).
- Clean up small edge-case where `response` could be `None`.
- Correct type annotation on `JsonCoder.decode()` to match `Coder.decode()`.
This is, for the majority of backends, the native format anyway, and so
we save encoding and decoding when using the PickleCodec or if (in future)
a orjson Coder was to be added.
For the JsonCodec, the only thing that changed is the location where the
JSON data is encoded to bytes and decoded back again to a string.
Use the return annotation to decode cached data to the correct type.
This follows the same logic FastAPI uses to JSON request bodies.
For the PickleCoder, this is a no-op as pickle already stores type
information in the serialised data.