← 输入框|github.com|刷新
Skip to content

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

Closed

Description

@starpit

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

Activity

  1. added
    C-compatA discrepancy between RustPython and CPython
    on Apr 17, 2025
  2. arihant2math commented on Apr 18, 2025

    @arihant2math
    Contributor

    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.

  3. starpit commented on Apr 18, 2025

    @starpit
    Author

    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.

  4. arihant2math commented on Apr 19, 2025

    @arihant2math
    Contributor

    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.

  5. arihant2math commented on Apr 19, 2025

    @arihant2math
    Contributor

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

  6. starpit commented on Apr 19, 2025

    @starpit
    Author

    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

  7. arihant2math commented on Apr 19, 2025

    @arihant2math
    Contributor

    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.

  8. arihant2math commented on Apr 27, 2025

    @arihant2math
    Contributor

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

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

    C-compatA discrepancy between RustPython and CPython

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions