Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.9 use OR | operator for Union types?

Since Python version 3.10, Unions can be writte as X | Y which is equivalent to Union[X, Y]. Is there some way/workaround to easily use (or just ignore) the X | Y syntax on Python 3.9?

I have a bigger Python package that is making exentsie use of the X | Y syntax for type annotations. It was originally developed for Python 3.10+.

Now there is a new requirement for the software to run on Raspberry Pi, but the latest Raspberry Pi OS release (bullseye) has only Python 3.9.2 integrated which does not support this syntax.

Debian Bookworm has been released recently. It has Python 3.11 integrated. I expect the release of a Bookworm based Raspberry Pi OS within the next few month. So there's really just a small time window where I would really need Python 3.9 support.

EDIT: I have already added the from __future__ import annotations import. The software uses the pydantic package and the exception occurs when pydantic is trying to parse the type annotations:

Traceback (most recent call last):
  File "/home/michael/margintest/./margin.py", line 6, in <module>
    from vtcontrol.apps.margintest.app import App
  File "/home/michael/margintest/vtcontrol/apps/margintest/app.py", line 16, in <module>
    from .widgets.steps import StepsDetailView, TestProgressbar
  File "/home/michael/margintest/vtcontrol/apps/margintest/widgets/steps.py", line 6, in <module>
    from ..runner import Runner
  File "/home/michael/margintest/vtcontrol/apps/margintest/runner.py", line 11, in <module>
    from .models.config import Config
  File "/home/michael/margintest/vtcontrol/apps/margintest/models/config.py", line 76, in <module>
    class StepConfig(BaseModel):
  File "/home/michael/margintest/venv/lib/python3.9/site-packages/pydantic/main.py", line 178, in __new__
    annotations = resolve_annotations(namespace.get('__annotations__', {}), namespace.get('__module__', None))
  File "/home/michael/margintest/venv/lib/python3.9/site-packages/pydantic/typing.py", line 400, in resolve_annotations
    value = _eval_type(value, base_globals, None)
  File "/usr/lib/python3.9/typing.py", line 283, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/lib/python3.9/typing.py", line 539, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
like image 289
slarag Avatar asked Jun 18 '26 08:06

slarag


1 Answers

You can add

from __future__ import annotations

at the beginning of your python files to use the new X | Y syntax in Python 3.9. This also enable other features, you can find more information about this in PEP 563 – Postponed Evaluation of Annotations.

like image 133
Noé Duruz Avatar answered Jun 19 '26 21:06

Noé Duruz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!