Fix: issue #1297: datasaver does not work with __future__.annotations
Fixes issue #1297 by changing return_annotation retrieval function_modifiers.adapters.datasaver.validate.
Changes
- modified
datasaver.validateto check against__future__.annotationscompatible type hints
How I tested this
- added
from __future__ import annotationsto test_adapters - ran
pytest tests/function_modifiers→ test failed - made above changes
- ran
pytest tests/function_modifiers→ test succeeded
Notes
I do not understand why this is done in the tests and should, in theory, not impact "normal" use. Feedback on this is welcome.
Checklist
- [x] PR has an informative and human-readable title (this will be pulled into the release notes)
- [x] Changes are limited to a single goal (no scope creep)
- [x] Code passed the pre-commit check & code is left cleaner/nicer than when first encountered.
- [x] Any change in functionality is tested
- [x] New functions are documented (with a description, list of inputs, and expected output)
- [x] Placeholder code is flagged / future TODOs are captured in comments
- [x] Project documentation has been updated if adding/changing functionality.
The bot makes a good suggestion: instead of my change, it is better to change
# return_annotation = inspect.signature(fn).return_annotation to return_annotation = typing.get_type_hints(fn)["return"]
which does resolve "dict_" and "dict" to dict.
As a result, the block if return_annotation is inspect.Signature.empty can be replaced with if return_annotation is None.
I assume that's preferable and make the change
Thank you! This is great -- I've been meaning to make this change to everywhere in the codebase and new spots keep popping up in which it's needed.
Just checking -- does the change to test_adapters mean that this won't work if we don't use from __future__ import annotations?
Just checking -- does the change to
test_adaptersmean that this won't work if we don't usefrom __future__ import annotations?
Good point, did not test this.
--- a/tests/function_modifiers/test_adapters.py
+++ b/tests/function_modifiers/test_adapters.py
@@ -1,5 +1,3 @@
-from __future__ import annotations
-
pytest -s tests/function_modifiers/
======================================= 383 passed, 13 warnings in 3.21s =======================================
luckily same result.
Out of curiosity, I tried this example:
class B(dict):
pass
def func() -> B:
return B()
def func2() -> dict:
return dict()
import inspect
import typing
print(inspect.signature(func).return_annotation)
print(inspect.signature(func2).return_annotation)
print(typing.get_type_hints(func)["return"])
print(typing.get_type_hints(func2)["return"])
without annotations they are identical
inspect: <class '__main__.B'>
inspect: <class 'dict'>
typing: <class '__main__.B'>
typing: <class 'dict'>
with from __future__ import annotations the inspect ones turn to string:
inspect: B
inspect: dict
typing: <class '__main__.B'>
typing: <class 'dict'>
Hope this helps
@elijahbenizzy bump