-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use it #11
Comments
Hello @SylvainGuieu, When it comes to using As for now, you might use my (a bit worse) solution https://github.com/bswck/modern_types which simply requires |
@bswck Thanks, |
Thanks @bswck for responding. Merging pydantic/pydantic#8209 is indeed the main thing that needs to happen. Once that's released you shouldn't need to do anything from pydantic as long as this package is installed.
I think the fact that you can't do this should be considered a bug. It'd also be good for this package to expose some API which does this for you. Then this can easily be used both before whatever version of pydantic releases this and outside pydantic. |
The pydantic PR is merged, and pydantic 2.6.0 beta should be released soon. |
Hey @bswck (@alexmojaki), I see you wanted to improve the docs? May I send a quick PR here to show in the README how to use this? I was confused too and thought it would override |
Huh actually I'm still not managing to use it correctly 🤔 With eval_type( # noqa: PGH001,S307
param.annotation,
exec_globals,
{},
try_default=False,
) ... def _eval_direct(
value: typing.ForwardRef,
globalns: dict[str, Any] | None = None,
localns: dict[str, Any] | None = None,
):
> tree = ast.parse(value.__forward_arg__, mode='eval')
E AttributeError: 'str' object has no attribute '__forward_arg__' I suppose I should manually wrap any string annotation into a forward ref? |
Yep, this seems to work: eval_type( # noqa: PGH001,S307
ForwardRef(param.annotation) if isinstance(param.annotation, str) else param.annotation,
exec_globals,
{},
) With this I can also drop try:
from eval_type_backport import eval_type_backport as eval_type
except ImportError:
from typing import _eval_type
def eval_type(*args, **kwargs):
kwargs.pop("try_default", None)
return _eval_type(*args, **kwargs) 👍 Would be nice though it eval-type-backport would cast strings to forward refs automatically (if that makes sense) 🙂 |
def eval_type_backport(
value: Any, globalns: dict[str, Any] | None = None, localns: dict[str, Any] | None = None
) -> Any:
"""Like `typing._eval_type`, but falls back to the `eval_type_backport` package if it's
installed to let older Python versions use newer typing features.
Specifically, this transforms `X | Y` into `typing.Union[X, Y]`
and `list[X]` into `typing.List[X]` etc. (for all the types made generic in PEP 585)
if the original syntax is not supported in the current Python version.
"""
try:
return typing._eval_type( # type: ignore
value, globalns, localns
)
except TypeError as e:
if not (isinstance(value, typing.ForwardRef) and is_backport_fixable_error(e)):
raise
try:
from eval_type_backport import eval_type_backport
except ImportError:
raise TypeError(
f'You have a type annotation {value.__forward_arg__!r} '
f'which makes use of newer typing features than are supported in your version of Python. '
f'To handle this error, you should either remove the use of new syntax '
f'or install the `eval_type_backport` package.'
) from e
return eval_type_backport(value, globalns, localns, try_default=False)
def is_backport_fixable_error(e: TypeError) -> bool:
msg = str(e)
return msg.startswith('unsupported operand type(s) for |: ') or "' object is not subscriptable" in msg Notice how a bunch of code is almost identical to eval_type_backport itself so that it only suggests installing the package if it might be useful. It probably would have been better to just use
That would make it behave differently from |
Thanks for your quick reply 🙂 Here's how I now use eval-type-backport: pawamoy/duty@e8ca7c1. Let me know if you'd like me to send a PR to show quick usage in the readme. |
Wanted to chime in that this "just worked" after updating pydantic. Excerpt from pyproject.toml [tool.poetry.dependencies]
python = ">=3.9, <3.13"
pydantic = "^2.6"
eval-type-backport = { version = "^0.2.0", python = "<3.10"} |
Hi,
I fill very stupid but ... I followed the issues on pydantic I end-up here, I installed it, but I have no idea how to use it !
What should I do with the
eval_type_backport
to make it work with pydantic ?I though I could replace
typing._eval_type
method to this one by I end up with cycling calls.Could you drop a few lines in the Readme ?
cheers,
Sylvain
The text was updated successfully, but these errors were encountered: