Add typing_extensions.Buffer (#125)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d330a0f..d4bc032 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/README.md b/README.md
index 6da36c3..b29378b 100644
--- a/README.md
+++ b/README.md
@@ -35,11 +35,15 @@
- 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`
@@ -159,4 +163,4 @@
## Running tests
To run tests, navigate into the appropriate source directory and run
-`test_typing_extensions.py`.
\ No newline at end of file
+`test_typing_extensions.py`.
diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py
index 7f9e59a..b4e21d6 100644
--- a/src/test_typing_extensions.py
+++ b/src/test_typing_extensions.py
@@ -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
@@ -3677,5 +3677,35 @@
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()
diff --git a/src/typing_extensions.py b/src/typing_extensions.py
index 71d2a7a..b29e37c 100644
--- a/src/typing_extensions.py
+++ b/src/typing_extensions.py
@@ -33,6 +33,7 @@
'Coroutine',
'AsyncGenerator',
'AsyncContextManager',
+ 'Buffer',
'ChainMap',
# Concrete collection types.
@@ -2318,3 +2319,32 @@
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)