8000 ENH: Virtually implement __buffer__ for Python < 3.12 by Andrej730 · Pull Request #26784 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Virtually implement __buffer__ for Python < 3.12 #26784

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
wants to merge 3 commits into from
Closed

ENH: Virtually implement __buffer__ for Python < 3.12 #26784

wants to merge 3 commits into from

Conversation

Andrej730
Copy link
Contributor
@Andrej730 Andrej730 commented Jun 22, 2024

See #26783 for the details

Note that there is also __release_buffer__ part of the buffer protocol -

numpy/numpy/__init__.pyi

Lines 2843 to 2844 in 7687245

if sys.version_info >= (3, 12):
def __release_buffer__(self, buffer: memoryview, /) -> None: ...

I've kept it Python 3.12+ only as it's optional part of the protocol and it's Buffer is using just __buffer__ to detect whether class supports the protocol. So, there is no need to virtually implement it for <3.12.
image

@Andrej730 Andrej730 changed the title Virtually implement __buffer__ for Python <3.11 to support typing #26783 Virtually implement __buffer__ for Python <3.12 to support typing #26783 Jun 23, 2024
@Andrej730
Copy link
Contributor Author

@BvB93 can you please take a look?

@Andrej730
Copy link
Contributor Author

@rgommers @jorenham Hi! Could you please let me know who I can ask for a PR review?

@jorenham jorenham self-requested a review August 26, 2024 05:47
@charris charris changed the title Virtually implement __buffer__ for Python <3.12 to support typing #26783 ENH: Virtually implement __buffer__ for Python < 3.12 Aug 30, 2024
Copy link
Member
@jorenham jorenham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

I totally agree that it's annoying that opn Python <3.12 static type-checkers mark e.g. memoryview(my_ndarray) as an error.
And PEP 688 was (in part) proposed to solve this issue, which it did, but that requires at least Python 3.12.

In typeshed they have "backported" this by adding a __buffer__ to the builtin typing stubs, ignoring the fact that this isn't the case at runtime. But static stub-checkers (e.g. mypy's stubtest or pyright --verifytypes) report this as a "hard" error, making this fall into the category of bugs.

An although I fully understand why this is practical, and that it could make static typing easier in several situations, I don't think it's a good idea to (knowingly) have the typing stubs deviate from the (true) runtime.
And that's not only because it's wrong, or because "bugs are bad". It's mostly because I know from experience that things like these can (and will) lead to very tricky and significant problems , and many confused users (myself included).
I could list several major problems such deviations have caused if you want, but that'll probably become a huge rant 😅 (and is unrelated to this PR).

In this case, I think that especially for ndarray subclasses this could cause many typing issues, e.g. in 3rd party libraries, most of which are unforeseeable "unknown unknowns".

So to make a long story short: As far as I'm concerned, I don't think this is worth the risk.

ELet me conclude by quoting Tim Peters wise words from PEP 20 (even though this probably makes me sound like a total wise-ass):

Special cases aren't special enough to break the rules.
Although practicality beats purity.

dtype[Any],
Union[bool, int, float, complex, str, bytes],
]
from typing_extensions import Buffer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typing_extensions isn't a required dependency; it can only be used in stubs or if typing.TYPE_CHECKING

@Andrej730
Copy link
Contributor Author

Sad but makes sense, though it is inconsistent with the decision made in typeshed.

I guess will be stuck with those warnings for a couple years more since VFX Platform CY2025 is also currently planning to use Python 3.11 :\

@jorenham
Copy link
Member
jorenham commented Sep 4, 2024

For what it's worth; perhaps you could work around it with a custom memoryview wrapper, e.g.

from typing import cast
from typing_extensions import Buffer

import numpy as np
import numpy.typing as npt

def better_memoryview(x: Buffer | npt.NDArray[np.generic], /) -> memoryview:
    # alternatively, you could also use `# type: ignore[arg-type]` (with mypy)
    return memoryview(cast(Buffer, x))

You could (but probably shouldn't) even go as far as replace builtins.memoryview:

import builtins
builtins.memoryview = better_memoryview

... but that'll probably get you fired 😅

@jorenham jorenham added the 57 - Close? Issues which may be closable unless discussion continued label Sep 4, 2024
@Andrej730 Andrej730 closed this Sep 24, 2024
@Andrej730 Andrej730 deleted the virtual_buffer_dunder branch September 24, 2024 16:47
@jorenham jorenham removed the 57 - Close? Issues which may be closable unless discussion continued label Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

4 participants
0