|
| 1 | +"""Demonstrate how passing a raw PyCapsule triggers the dataset fallback. |
| 2 | +
|
| 3 | +Run with ``python examples/raw_capsule_registration_failure.py``. |
| 4 | +
|
| 5 | +This mirrors integrations that construct a :class:`datafusion.Table` directly |
| 6 | +from the FFI PyCapsule returned by ``__datafusion_table_provider__``. After the |
| 7 | +refactor that routes all inputs through ``RawTable`` the capsule is no longer |
| 8 | +recognized, so the constructor falls back to the PyArrow dataset path and raises |
| 9 | +``ValueError: dataset argument must be a pyarrow.dataset.Dataset object``. |
| 10 | +""" |
| 11 | + |
| 12 | +from __future__ import annotations |
| 13 | + |
| 14 | +import ctypes |
| 15 | + |
| 16 | +from datafusion import SessionContext, Table |
| 17 | + |
| 18 | + |
| 19 | +# Keep the backing memory alive for the lifetime of the module so the capsule |
| 20 | +# always wraps a valid (non-null) pointer. The capsule content is irrelevant for |
| 21 | +# this regression example—we only need a non-null address. |
| 22 | +_DUMMY_CAPSULE_BYTES = ctypes.create_string_buffer(b"x") |
| 23 | + |
| 24 | + |
| 25 | +def make_table_provider_capsule() -> object: |
| 26 | + """Create a dummy PyCapsule with the expected table provider name.""" |
| 27 | + |
| 28 | + pycapsule_new = ctypes.pythonapi.PyCapsule_New |
| 29 | + pycapsule_new.restype = ctypes.py_object |
| 30 | + pycapsule_new.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p] |
| 31 | + dummy_ptr = ctypes.cast(_DUMMY_CAPSULE_BYTES, ctypes.c_void_p) |
| 32 | + return pycapsule_new(dummy_ptr, b"datafusion_table_provider", None) |
| 33 | + |
| 34 | + |
| 35 | +def main() -> None: |
| 36 | + """Attempt to use the capsule the same way existing callers do.""" |
| 37 | + |
| 38 | + ctx = SessionContext() |
| 39 | + capsule = make_table_provider_capsule() |
| 40 | + |
| 41 | + try: |
| 42 | + Table(capsule) |
| 43 | + except ValueError as err: |
| 44 | + print("Constructing Table(capsule) failed:", err) |
| 45 | + |
| 46 | + try: |
| 47 | + ctx.register_table("capsule", capsule) |
| 48 | + except ValueError as err: |
| 49 | + print("Registering capsule with SessionContext failed:", err) |
| 50 | + |
| 51 | + |
| 52 | +if __name__ == "__main__": |
| 53 | + main() |
0 commit comments