dbrattli/Expression

Type aliases using Union syntax incompatible with Python 3.9

aiq-kgielow opened this issue · 4 comments

Describe the bug
A basic Python script bombs when importing from expression.collections.

To Reproduce

  1. Install expression into Python 3.9 virtual environment using pip install.
  2. Create a basic top-level script that imports expression.collections.
  3. Run script with Python 3.9 from virtual environment.

Expected behavior
Python script runs without issue.

Code or Screenshots
Here is the code from my Python script:

from expression.collections import seq, Seq

if __name__ == '__main__':
    print("All done!")

Here is the traceback I get:

Traceback (most recent call last):
  File "/home/atonally/develop/sandbox-py39/main.py", line 3, in <module>
    from expression.collections import seq, Seq
  File "/home/atonally/develop/sandbox-py39/.venv/lib/python3.9/site-packages/expression/__init__.py", line 11, in <module>
    from . import collections, core, effect
  File "/home/atonally/develop/sandbox-py39/.venv/lib/python3.9/site-packages/expression/collections/__init__.py", line 4, in <module>
    from . import array, asyncseq, block, map, seq
  File "/home/atonally/develop/sandbox-py39/.venv/lib/python3.9/site-packages/expression/collections/array.py", line 28, in <module>
    from expression.core import (
  File "/home/atonally/develop/sandbox-py39/.venv/lib/python3.9/site-packages/expression/core/__init__.py", line 20, in <module>
    from .fn import TailCall, TailCallResult, tailrec, tailrec_async
  File "/home/atonally/develop/sandbox-py39/.venv/lib/python3.9/site-packages/expression/core/fn.py", line 24, in <module>
    TailCallResult = _TResult | TailCall[_P]
TypeError: unsupported operand type(s) for |: 'TypeVar' and '_GenericAlias'

Additional context

  • Kubuntu 22.04
  • Expression 4.2.2
  • Python 3.9.16

I can't make a pull request, but here's the patch that I'm applying locally to get expression 4.2.2 to work with Python 3.9:

diff --git a/expression/collections/array.py b/expression/collections/array.py
index d1f27f6..399f57b 100644
--- a/expression/collections/array.py
+++ b/expression/collections/array.py
@@ -23,6 +23,7 @@ from typing import (
     Tuple,
     TypeVar,
     cast,
+    Union
 )
 
 from expression.core import (
@@ -44,7 +45,7 @@ _TState = TypeVar("_TState")
 _TSourceSortable = TypeVar("_TSourceSortable", bound=SupportsLessThan)
 
 _TSourceSum = TypeVar("_TSourceSum", bound=SupportsSum)
-_Array = List[_TSource] | MutableSequence[_TSource]
+_Array = Union[List[_TSource], MutableSequence[_TSource]]
 
 
 class int8(int):
diff --git a/expression/core/fn.py b/expression/core/fn.py
index 4461f27..80a75b9 100644
--- a/expression/core/fn.py
+++ b/expression/core/fn.py
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import functools
-from typing import Awaitable, Callable, Generic, TypeVar
+from typing import Awaitable, Callable, Generic, TypeVar, Union
 
 from typing_extensions import ParamSpec
 
@@ -21,7 +21,7 @@ class TailCall(Generic[_P]):
         self.kw = kw
 
 
-TailCallResult = _TResult | TailCall[_P]
+TailCallResult = Union[_TResult, TailCall[_P]]
 
 
 def tailrec(fn: Callable[_P, TailCallResult[_TResult, _P]]) -> Callable[_P, _TResult]:

Just curious if you're abandoning support for Python 3.9. Your documentation still states support for Python 3.9+

So the break started from version 4.2.0 (in #77). Haven't seen any discussion or content in documentation about dropping python 3.9.

Hope the compatibility is fixed as I'm using Anaconda which supports python 3.9 (version 2022.10).

Closing this issue since the issue was fixed in #117. However, just giving a heads-up that Expression v5 just took a hard dependency on dataclass_transforms in Python 3.11, so we are now Python 3.11+.