Skip to content

TypeError: '|' not supported between instances of '_CallableGenericAlias' and 'NoneType' #5711

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

Open
starpit opened this issue Apr 17, 2025 · 7 comments · May be fixed by #5753
Open

TypeError: '|' not supported between instances of '_CallableGenericAlias' and 'NoneType' #5711

starpit opened this issue Apr 17, 2025 · 7 comments · May be fixed by #5753
Labels
C-compat A discrepancy between RustPython and CPython

Comments

@starpit
Copy link

starpit commented Apr 17, 2025

Feature

The following fails on rustpython but succeeds on cpython3.12

from collections.abc import Awaitable, Callable
from typing import TypeVar

T = TypeVar("T")

async def abort_signal_handler(
    fn: Callable[[], Awaitable[T]], on_abort: Callable[[], None] | None = None
) -> T:
    pass

Traceback (most recent call last):
File "/tmp/foo.py", line 7, in
fn: Callable[[], Awaitable[T]], on_abort: Callable[[], None] | None = None
TypeError: '|' not supported between instances of '_CallableGenericAlias' and 'NoneType'

Python Documentation or reference to CPython source code

I'm not sure. I have tried comparing RustPython's typing.py to cpython's. There are differences in the treatment of Callable.

https://github.com/python/cpython/blob/main/Lib/typing.py

@starpit starpit added the C-compat A discrepancy between RustPython and CPython label Apr 17, 2025
@arihant2math
Copy link
Collaborator

RustPython's typing.py is out of date by 5 minor versions or so (3.9 or 3.10 or something). #5590 should fix it, but there is some ast that needs to be updated as well.

@starpit
Copy link
Author

starpit commented Apr 18, 2025

Thanks for the attention. I tested the #5590 branch, and still see this error.

on ref:

* 0f5af3586 - (9 hours ago) implement more of ParamSpec - Ashwin Naren (HEAD -> typing-unpack, ari/typing-unpack)
cargo run -- <(echo 'from collections.abc import Awaitable, Callable
from typing import TypeVar
T = TypeVar("T")
async def abort_signal_handler(
    fn: Callable[[], Awaitable[T]], on_abort: Callable[[], None] | None = None
) -> T:
    pass')

which results in

Traceback (most recent call last):
File "/dev/fd/63", line 7, in
TypeError: '|' not supported between instances of '_CallableGenericAlias' and 'NoneType'

Pulling in the latest Lib/typing.py and I see that RustPython does not yet implement Pattern::MatchOr.

@arihant2math
Copy link
Collaborator

arihant2math commented Apr 19, 2025

Isn't Pattern::MatchOr for match statements (it's implemented now, as per #5628)? This is BinaryOperation::Or

Disassembly $ ./target/debug/rustpython -m dis tmp.py 1 0 LoadConst (0) 1 LoadConst (("Awaitable", "Callable")) 2 ImportName (0, collections.abc) 3 ImportFrom (1, Awaitable) 4 StoreLocal (1, Awaitable) 5 ImportFrom (2, Callable) 6 StoreLocal (2, Callable) 7 Pop

2 8 LoadConst (0)
9 LoadConst (("TypeVar"))
10 ImportName (3, typing)
11 ImportFrom (4, TypeVar)
12 StoreLocal (4, TypeVar)
13 Pop

4 14 LoadNameAny (4, TypeVar)
15 LoadConst ("T")
16 CallFunctionPositional(1)
17 StoreLocal (5, T)

7 18 LoadConst (None)
19 BuildTuple (1)

9 20 LoadConst ("return")

8 21 LoadNameAny (5, T)
22 LoadConst ("fn")

7 23 LoadNameAny (2, Callable)
24 BuildList (0)
25 LoadNameAny (1, Awaitable)
26 LoadNameAny (5, T)
27 Subscript
28 BuildTuple (2)
29 Subscript
30 LoadConst ("on_abort")
31 LoadNameAny (2, Callable)
32 BuildList (0)
33 LoadConst (None)
34 BuildTuple (2)
35 Subscript
36 LoadConst (None)
37 BinaryOperation (Or)
38 BuildMap (3)
39 LoadConst (<code object abort_signal_handler at ??? file "tmp.py", line 7>)
40 LoadConst ("abort_signal_handler")
41 MakeFunction (MakeFunctionFlags(ANNOTATIONS | DEFAULTS))
42 StoreLocal (6, abort_signal_handler)
43 ReturnConst (None)

Disassembly of <code object abort_signal_handler at ??? file "tmp.py", line 7>
9 0 ReturnConst (None)

The main issue is that | is not implemented for Generic + NoneType. Shouldn't be too hard seeing that we already have regular union types.

@arihant2math
Copy link
Collaborator

Seems to be a bigger issue, #3746 or similar needs to be merged for this to be fixed.

@starpit
Copy link
Author

starpit commented Apr 19, 2025

Interesting. I'm not sure. I did a quick experiment of pulling in the very latest typing.py, and got an unimplemented exception for PatternMatch::MatchOr

@arihant2math
Copy link
Collaborator

Interesting. I'm not sure. I did a quick experiment of pulling in the very latest typing.py, and got an unimplemented exception for PatternMatch::MatchOr

If on the new branch, I believe it wasn't rebased at that time, so the match statements upgrade wasn't there.

I'll see if I can get the bigger issue fixed since it affects a lot of things.

@arihant2math
Copy link
Collaborator

arihant2math commented Apr 27, 2025

I think I could just patch this issue specifically, since it happens elsewhere.

@arihant2math arihant2math linked a pull request Apr 27, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-compat A discrepancy between RustPython and CPython
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants