Skip to content

Instantly share code, notes, and snippets.

@JamesTheAwesomeDude
Last active April 11, 2024 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesTheAwesomeDude/01afe6bf78fd334f8a8ec95eb57f24fb to your computer and use it in GitHub Desktop.
Save JamesTheAwesomeDude/01afe6bf78fd334f8a8ec95eb57f24fb to your computer and use it in GitHub Desktop.
Buffer (ABC type) ponyfill for Python 3.11 and older
"""*BufferLike*, a quasi-ponyfill for collections.abc.Buffer
When collections.abc.Buffer is available, exports it directly.
Otherwise, crudely constructs an Abstract Base Class via mass ABC.register().
May not be suitable for all use-cases."""
try:
# version_info >= (3, 12)
from collections.abc import Buffer as BufferLike
except ImportError:
# version_info < (3, 12)
import abc
import array
import collections.abc
import ctypes
import mmap
class BufferLike(collections.abc.ByteString):
pass
BufferLike.register(array.array)
BufferLike.register(ctypes.Array)
BufferLike.register(memoryview)
BufferLike.register(mmap.mmap)
# Bonus Library Support:
# * CFFI:
try:
import cffi
except ImportError:
pass
else:
if hasattr(cffi.FFI, 'buffer') and isinstance(cffi.FFI.buffer, type):
BufferLike.register(cffi.FFI.buffer)
else:
_ffi = cffi.FFI()
if isinstance(_ffi.buffer, type):
BufferLike.register(_ffi.buffer)
else:
with _ffi.new('uint8_t[0]') as _cdata:
_cdata_buf = _ffi.buffer(_cdata)
_ffi_buffer = _cdata_buf.__class__
BufferLike.register(_ffi_buffer)
# * NumPy:
try:
import numpy
except ImportError:
pass
else:
BufferLike.register(numpy.ndarray)
# * bitarray
try:
import bitarray
except ImportError:
pass
else:
BufferLike.register(bitarray.bitarray)
__all__ = ['BufferLike']
"""*BufferLike*, a quasi-ponyfill for collections.abc.Buffer
When collections.abc.Buffer is available, exports it directly.
Otherwise, crudely constructs an Abstract Base Class via mass typing.Union[].
May not be suitable for all use-cases."""
try:
# version_info >= (3, 12)
from collections.abc import Buffer as BufferLike
except ImportError:
# version_info < (3, 12)
import abc
import array
import collections.abc
import ctypes
import mmap
from typing import Union
BufferLike = Union[collections.abc.ByteString, array.array, ctypes.Array, memoryview, mmap.mmap]
# Bonus Library Support:
# * CFFI:
try:
import cffi
except ImportError:
pass
else:
if hasattr(cffi.FFI, 'buffer') and isinstance(cffi.FFI.buffer, type):
BufferLike = Union[BufferLike, cffi.FFI.buffer]
else:
_ffi = cffi.FFI()
if isinstance(_ffi.buffer, type):
BufferLike = Union[BufferLike, _ffi.buffer]
else:
with _ffi.new('uint8_t[0]') as _cdata:
_cdata_buf = _ffi.buffer(_cdata)
_ffi_buffer = _cdata_buf.__class__
BufferLike = Union[BufferLike, _ffi_buffer]
# * NumPy:
try:
import numpy
except ImportError:
pass
else:
BufferLike = Union[BufferLike, numpy.ndarray]
# * bitarray
try:
import bitarray
except ImportError:
pass
else:
BufferLike = Union[BufferLike, bitarray.bitarray]
__all__ = ['BufferLike']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment