xref: /petsc/src/binding/petsc4py/src/cython.h (revision a6ca03fe5be29a717112d4c77a20563fc288dd1f)
1 static
Cython_ImportFunction(PyObject * module,const char * funcname,const char * signature)2 void *Cython_ImportFunction(PyObject   *module,
3                             const char *funcname,
4                             const char *signature)
5 {
6   PyObject *capi = NULL, *capsule = NULL; void *p = NULL;
7   capi = PyObject_GetAttrString(module, (char *)"__pyx_capi__");
8   if (!capi)
9     goto bad;
10   capsule = PyDict_GetItemString(capi, (char *)funcname);
11   if (!capsule) {
12     PyErr_Format(PyExc_ImportError,
13                  "%s does not export expected C function %s",
14                  PyModule_GetName(module), funcname);
15     goto bad;
16   }
17 #if PY_VERSION_HEX < 0x03020000
18   if (PyCObject_Check(capsule)) {
19     const char *desc, *s1, *s2;
20     desc = (const char *)PyCObject_GetDesc(capsule);
21     if (!desc)
22       goto bad;
23     s1 = desc; s2 = signature;
24     while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
25     if (*s1 != *s2) {
26       PyErr_Format(PyExc_TypeError,
27                    "C function %s.%s has wrong signature "
28                    "(expected %s, got %s)",
29                    PyModule_GetName(module), funcname, signature, desc);
30       goto bad;
31     }
32     p = PyCObject_AsVoidPtr(capsule);
33   }
34 #endif
35 #if PY_VERSION_HEX >= 0x02070000
36   if (PyCapsule_CheckExact(capsule)) {
37     if (!PyCapsule_IsValid(capsule, signature)) {
38       const char *desc = PyCapsule_GetName(capsule);
39       PyErr_Format(PyExc_TypeError,
40                    "C function %s.%s has wrong signature "
41                    "(expected %s, got %s)",
42                    PyModule_GetName(module), funcname, signature, desc);
43       goto bad;
44     }
45     p = PyCapsule_GetPointer(capsule, signature);
46   }
47 #endif
48   Py_DECREF(capi);
49   return p;
50  bad:
51   Py_XDECREF(capi);
52   return NULL;
53 }
54 
55 /*
56   Local variables:
57   c-basic-offset: 2
58   indent-tabs-mode: nil
59   End:
60 */
61