Skip to content

Subtype for memoryview required to pass mypy checks but triggersTypeError in Python #18053

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

Closed
lgautier opened this issue Oct 26, 2024 · 4 comments
Labels
bug mypy got something wrong

Comments

@lgautier
Copy link

Bug Report

Specifying a subtype for memoryview is required to pass mypy checks, but this create a TypeError in Python.

To Reproduce

This fails mypy checks:

import typing

def foo(m: memoryview) -> memoryview:
    return m

def bar(n: int, t: typing.Literal['i', 'd']) -> memoryview:
    return memoryview(bytes(n)).cast(t)

res = foo(bar(8, 'i'))
$ mypy test-type-hints.py 
test-type-hints.py:7: error: Incompatible return value type (got "memoryview[int] | memoryview[float]", expected "memoryview[int]")  [return-value]
Found 1 error in 1 file (checked 1 source file)
$ python test-type-hints.py 

Fixing mypy checks triggers Python error:

import typing

def foo(m: memoryview[int]) -> memoryview[int]:
    return m

@typing.overload
def bar(n: int, t: typing.Literal['i']) -> memoryview[int]: ...

@typing.overload
def bar(n: int, t: typing.Literal['d']) -> memoryview[float]: ...

    
def bar(n: int, t: typing.Literal['i', 'd']) -> memoryview[int] | memoryview[float]:
    return memoryview(bytes(n)).cast(t)

res = foo(bar(8, 'i'))
$ mypy test-type-hints.py 
Success: no issues found in 1 source file
$ python test-type-hints.py 
Traceback (most recent call last):
  File "/some/path/test-type-hints.py", line 3, in <module>
    def foo(m: memoryview[int]) -> memoryview[int]:
               ~~~~~~~~~~^^^^^
TypeError: type 'memoryview' is not subscriptable

Expected Behavior

$ mypy test-type-hints.py
Success: no issues found in 1 source file
$ python test-type-hints.py 

Actual Behavior

Either mypy fails but Python can run the code, or mypy passes but Python doesn't run.

Your Environment

$ mypy --version
mypy 1.13.0 (compiled: yes)
$ python --version
Python 3.12.3
@lgautier lgautier added the bug mypy got something wrong label Oct 26, 2024
@brianschubert
Copy link
Collaborator

Hi! This is https://mypy.readthedocs.io/en/stable/runtime_troubles.html#using-classes-that-are-generic-in-stubs-but-not-at-runtime

Try using from __future__ import annotations, string literal annotations (memoryview[int] -> "memoryview[int]"), or an if TYPE_CHECKING: alias.

@brianschubert
Copy link
Collaborator

brianschubert commented Oct 26, 2024

(memoryview was made generic in typeshed only recently in python/typeshed#12247. I don't know the background here, but it seems that if memoryview is going to be generic in the stubs, we should eventually add memoryview.__class_getitem__ upstream? I couldn't find an existing CPython issue for this)

@lgautier
Copy link
Author

Thanks. Adding from __future__ import annotations does solve the issue. I had understood from the doc page you mentioned that this was only for Python 3.8 or earlier.

@brianschubert
Copy link
Collaborator

FR: Support for subscripting memoryview at runtime was merged in python/cpython#126013, and should be released with Python 3.14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants