8000 ENH: virtually support __buffer__ method for python <3.12 · Issue #26783 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: virtually support __buffer__ method for python <3.12 #26783

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
Andrej730 opened this issue Jun 22, 2024 · 0 comments
Open

ENH: virtually support __buffer__ method for python <3.12 #26783

Andrej730 opened this issue Jun 22, 2024 · 0 comments

Comments

@Andrej730
Copy link
Contributor
Andrej730 commented Jun 22, 2024

Proposed new feature or change:

Consider the snippet below.

from typing_extensions import Buffer

class ClassA:
    def accept_buffer2(self, buffer: Buffer):
        pass

a = ClassA()

from array import array
import numpy as np
array_buffer = array("l", [1, 2, 3, 4, 5])
np_buffer = np.array([1, 2, 3, 4, 5], dtype=np.int32)
print(memoryview(array_buffer))
# typing issue
print(memoryview(np_buffer))

a.accept_buffer2(array_buffer)
# Argument of type "NDArray[signedinteger[_32Bit]]" cannot be assigned to parameter "buffer" of type "Buffer" in function "accept_buffer2"
#   "ndarray[Any, dtype[signedinteger[_32Bit]]]" is incompatible with protocol "Buffer"
#     "__buffer__" is not present
a.accept_buffer2(np_buffer)

In Python 3.11 it will fail as __buffer__ in a stub file is only implemented for Python 3.12:

numpy/numpy/__init__.pyi

Lines 1462 to 1463 in 7687245

if sys.version_info >= (3, 12):
def __buffer__(self, flags: int, /) -> memoryview: ...

But technically it buffer protocol is implemented before Python 3.11 but it's just done internally, not using __buffer__.

__buffer__ dunder seems to be the way Buffer checks whether some class has implemented buffer protocol and Buffer is available not only in Python 3.12 with collections.abc.Buffer but for older python versions too using typing_extensions.Buffer.

In 3.12 np.ndarray.__buffer__ is indeed accessable and in <3.11 it isn't but standard library's array.array has a similar issue and they implement __buffer__ for convenience.

# Python 3.12+
> print(np_buffer.__buffer__)
<method-wrapper '__buffer__' of numpy.ndarray object at 0x7f152ba13f90>
> print(array_buffer.__buffer__)
<method-wrapper '__buffer__' of array.array object at 0x7fdba349f100>

# Python <3.12
> print(np_buffer.__buffer__)
AttributeError: 'numpy.ndarray' object has no attribute '__buffer__'
> print(array_buffer.__buffer__)
AttributeError: 'array.array' object has no attribute '__buffer__'

See array.array stub file and related PR python/typeshed#10225
https://github.com/python/typeshed/blob/434f6528b7607d9ae6c3d34329840a18922df925/stdlib/array.pyi#L87

I've submitted a small PR #26784 that resolves this.

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

No branches or pull requests

1 participant
0