Skip to content

Inspection errors on valid union syntax for Python < 3.10 #737

Closed

Description

@ofek

Description

The following code:

from __future__ import annotations
from msgspec import Struct, inspect

class Bug(Struct):
    field: str | int = 0

inspect.type_info(Bug)

produces the following:

Traceback (most recent call last):
  File "C:\Users\ofek\Desktop\rf\m.py", line 7, in <module>
    inspect.type_info(Bug)
  File "C:\Users\ofek\AppData\Local\Programs\Python\Python39\lib\site-packages\msgspec\inspect.py", line 629, in type_info
    return multi_type_info([type])[0]
  File "C:\Users\ofek\AppData\Local\Programs\Python\Python39\lib\site-packages\msgspec\inspect.py", line 598, in multi_type_info
    return _Translator(types).run()
  File "C:\Users\ofek\AppData\Local\Programs\Python\Python39\lib\site-packages\msgspec\inspect.py", line 744, in run
    MsgpackDecoder(Tuple[self.types])
  File "C:\Users\ofek\AppData\Local\Programs\Python\Python39\lib\site-packages\msgspec\_utils.py", line 130, in get_class_annotations
    value = typing._eval_type(value, cls_locals, cls_globals)
  File "C:\Users\ofek\AppData\Local\Programs\Python\Python39\lib\typing.py", line 292, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "C:\Users\ofek\AppData\Local\Programs\Python\Python39\lib\typing.py", line 554, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'type' and 'type'

The following code is a workaround but limits what users are allowed to do when providing a library that extends msgspec:

from __future__ import annotations
from typing import Union
from msgspec import Struct, inspect

class Bug(Struct):
    field: Union[str, int] = 0

inspect.type_info(Bug)

Activity

  1. chuckwondo commented on Sep 18, 2024

    @chuckwondo

    Using a pipe for type unions was introduced in Python 3.10, so anybody running an earlier version of Python shouldn't be surprised by this. If you want to "extend" msgspec and use the pipe syntax, then your extension must require python >= 3.10. If you want to support use of earlier versions of Python, then you must use the Union syntax, not the pipe syntax.

  2. ofek commented on Sep 18, 2024

    @ofek
    MemberAuthor

    Doesn't from __future__ import annotations allow for that syntax though?

  3. ofek commented on Sep 18, 2024

    @ofek
    MemberAuthor

    It looks like the reason the syntax error goes away is only due to the lazy computation. Thanks Chuck!

  4. chuckwondo commented on Sep 18, 2024

    @chuckwondo

    Doesn't from __future__ import annotations allow for that syntax though?

    No, that only allows for postponed evaluation of annotations.

  5. ofek commented on Sep 19, 2024

    @ofek
    MemberAuthor
  6. ashb commented on Nov 12, 2024

    @ashb
    Contributor

    Pydantic handles this via https://github.com/alexmojaki/eval_type_backport -- is there any appetite for doing the same in msgspec? Happy to PR it if that it'd be supported.

    @jcrist What would your appetite for it be?

  7. jcrist commented on Nov 15, 2024

    @jcrist
    Member

    Thanks for the comment - I'd be open to doing something like that. I've opened #771 to track this, lets continue discussion there :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions