| 1891 | }; |
| 1892 | |
| 1893 | PyMODINIT_FUNC PyInit_stringzillas(void) { |
| 1894 | PyObject *m; |
| 1895 | |
| 1896 | // Try to import NumPy |
| 1897 | #if defined(NPY_VERSION) |
| 1898 | import_array(); |
| 1899 | numpy_available = 1; |
| 1900 | sz_unused_(numpy_module); |
| 1901 | #else |
| 1902 | // Try to import numpy module dynamically |
| 1903 | numpy_module = PyImport_ImportModule("numpy"); |
| 1904 | if (numpy_module) { numpy_available = 1; } |
| 1905 | else { |
| 1906 | PyErr_Clear(); // Clear the import error |
| 1907 | PyErr_SetString(PyExc_ImportError, "NumPy is required but not available"); |
| 1908 | return NULL; |
| 1909 | } |
| 1910 | #endif |
| 1911 | |
| 1912 | // Try to import StringZilla and get the C API functions |
| 1913 | PyObject *stringzilla_module = PyImport_ImportModule("stringzilla"); |
| 1914 | if (!stringzilla_module) { |
| 1915 | PyErr_SetString(PyExc_ImportError, "StringZilla module is required but not available"); |
| 1916 | return NULL; |
| 1917 | } |
| 1918 | |
| 1919 | // Import the C API struct from the single capsule |
| 1920 | PyObject *capsule = PyObject_GetAttrString(stringzilla_module, "_sz_py_api"); |
| 1921 | if (!capsule || !PyCapsule_CheckExact(capsule)) { |
| 1922 | Py_XDECREF(capsule); |
| 1923 | Py_DECREF(stringzilla_module); |
| 1924 | PyErr_SetString(PyExc_ImportError, "Failed to import StringZilla C API capsule"); |
| 1925 | return NULL; |
| 1926 | } |
| 1927 | |
| 1928 | // Get the PyAPI struct from the capsule |
| 1929 | PyAPI *api = (PyAPI *)PyCapsule_GetPointer(capsule, "_sz_py_api"); |
| 1930 | if (!api) { |
| 1931 | Py_DECREF(capsule); |
| 1932 | Py_DECREF(stringzilla_module); |
| 1933 | PyErr_SetString(PyExc_ImportError, "Failed to get StringZilla C API pointer from capsule"); |
| 1934 | return NULL; |
| 1935 | } |
| 1936 | |
| 1937 | // Extract the function pointers from the struct |
| 1938 | sz_py_export_string_like = api->sz_py_export_string_like; |
| 1939 | sz_py_export_strings_as_sequence = api->sz_py_export_strings_as_sequence; |
| 1940 | sz_py_export_strings_as_u32tape = api->sz_py_export_strings_as_u32tape; |
| 1941 | sz_py_export_strings_as_u64tape = api->sz_py_export_strings_as_u64tape; |
| 1942 | sz_py_replace_strings_allocator = api->sz_py_replace_strings_allocator; |
| 1943 | |
| 1944 | Py_DECREF(capsule); |
| 1945 | Py_DECREF(stringzilla_module); |
| 1946 | |
| 1947 | // Check that all functions were loaded |
| 1948 | if (!sz_py_export_string_like || !sz_py_export_strings_as_sequence || !sz_py_export_strings_as_u32tape || |
| 1949 | !sz_py_export_strings_as_u64tape || !sz_py_replace_strings_allocator) { |
| 1950 | PyErr_SetString(PyExc_ImportError, "Failed to import required StringZilla C API functions"); |
nothing calls this directly
no test coverage detected
searching dependent graphs…