Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Unreleased

- Add `typing_extensions.Buffer`, a marker class for buffer types, as proposed
by PEP 688. Equivalent to `collections.abc.Buffer` in Python 3.12. Patch by
Jelle Zijlstra.

# Release 4.5.0 (February 14, 2023)

- Runtime support for PEP 702, adding `typing_extensions.deprecated`. Patch
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ This module currently contains the following:

- Experimental features

- `override` (see [PEP 698](https://peps.python.org/pep-0698/))
- The `default=` argument to `TypeVar`, `ParamSpec`, and `TypeVarTuple` (see [PEP 696](https://peps.python.org/pep-0696/))
- The `infer_variance=` argument to `TypeVar` (see [PEP 695](https://peps.python.org/pep-0695/))
- The `@deprecated` decorator (see [PEP 702](https://peps.python.org/pep-0702/))

- In the standard library since Python 3.12

- `override` (equivalent to `typing.override`; see [PEP 698](https://peps.python.org/pep-0698/))
- `Buffer` (equivalent to `collections.abc.Buffer`; see [PEP 688](https://peps.python.org/pep-0688/))

- In `typing` since Python 3.11

- `assert_never`
Expand Down Expand Up @@ -159,4 +163,4 @@ These types are only guaranteed to work for static type checking.
## Running tests

To run tests, navigate into the appropriate source directory and run
`test_typing_extensions.py`.
`test_typing_extensions.py`.
32 changes: 31 additions & 1 deletion src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from typing_extensions import assert_type, get_type_hints, get_origin, get_args
from typing_extensions import clear_overloads, get_overloads, overload
from typing_extensions import NamedTuple
from typing_extensions import override, deprecated
from typing_extensions import override, deprecated, Buffer
from _typed_dict_test_helper import Foo, FooGeneric
import warnings

Expand Down Expand Up @@ -3677,5 +3677,35 @@ def test_pickle(self):
self.assertEqual(z.__infer_variance__, typevar.__infer_variance__)


class BufferTests(BaseTestCase):
def test(self):
self.assertIsInstance(memoryview(b''), Buffer)
self.assertIsInstance(bytearray(), Buffer)
self.assertIsInstance(b"x", Buffer)
self.assertNotIsInstance(1, Buffer)

self.assertIsSubclass(bytearray, Buffer)
self.assertIsSubclass(memoryview, Buffer)
self.assertIsSubclass(bytes, Buffer)
self.assertNotIsSubclass(int, Buffer)

class MyRegisteredBuffer:
def __buffer__(self, flags: int) -> memoryview:
return memoryview(b'')

self.assertNotIsInstance(MyRegisteredBuffer(), Buffer)
self.assertNotIsSubclass(MyRegisteredBuffer, Buffer)
Buffer.register(MyRegisteredBuffer)
self.assertIsInstance(MyRegisteredBuffer(), Buffer)
self.assertIsSubclass(MyRegisteredBuffer, Buffer)

class MySubclassedBuffer(Buffer):
def __buffer__(self, flags: int) -> memoryview:
return memoryview(b'')

self.assertIsInstance(MySubclassedBuffer(), Buffer)
self.assertIsSubclass(MySubclassedBuffer, Buffer)


if __name__ == '__main__':
main()
30 changes: 30 additions & 0 deletions src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
'Coroutine',
'AsyncGenerator',
'AsyncContextManager',
'Buffer',
'ChainMap',

# Concrete collection types.
Expand Down Expand Up @@ -2310,3 +2311,32 @@ def _namedtuple_mro_entries(bases):
return (_NamedTuple,)

NamedTuple.__mro_entries__ = _namedtuple_mro_entries


if hasattr(collections.abc, "Buffer"):
Buffer = collections.abc.Buffer
else:
class Buffer(abc.ABC):
"""Base class for classes that implement the buffer protocol.

The buffer protocol allows Python objects to expose a low-level
memory buffer interface. Before Python 3.12, it is not possible
to implement the buffer protocol in pure Python code, or even
to check whether a class implements the buffer protocol. In
Python 3.12 and higher, the ``__buffer__`` method allows access
to the buffer protocol from Python code, and the
``collections.abc.Buffer`` ABC allows checking whether a class
implements the buffer protocol.

To indicate support for the buffer protocol in earlier versions,
inherit from this ABC, either in a stub file or at runtime,
or use ABC registration. This ABC provides no methods, because
there is no Python-accessible methods shared by pre-3.12 buffer
classes. It is useful primarily for static checks.

"""

# As a courtesy, register the most common stdlib buffer classes.
Buffer.register(memoryview)
Buffer.register(bytearray)
Buffer.register(bytes)