| 931 | static PyObject *leancallable_repr(PyObject *self_) { |
| 932 | LeanCallableObject *self = (LeanCallableObject *)self_; |
| 933 | char buf[128]; |
| 934 | snprintf(buf, sizeof(buf), |
| 935 | "<LeanCallable%s @ %p>", |
| 936 | self->has_kw ? "Kw" : "", |
| 937 | (void *)self->closure); |
| 938 | return p_PyUnicode_DecodeUTF8(buf, (Py_ssize_t)strlen(buf), NULL); |
| 939 | } |
| 940 | |
| 941 | static PyObject *leancallable_call(PyObject *self_, PyObject *args, PyObject *kwds) { |
| 942 | LeanCallableObject *self = (LeanCallableObject *)self_; |
| 943 | if (!self->closure) { |
| 944 | if (p_PyErr_SetString && p_PyExc_RuntimeError) { |
| 945 | p_PyErr_SetString(p_PyExc_RuntimeError, |
| 946 | "LeanCallable: closure has been freed"); |
| 947 | } |
| 948 | return NULL; |
| 949 | } |
| 950 | |
| 951 | Py_ssize_t n = p_PyTuple_Size(args); |
| 952 | if (n < 0) return NULL; |
| 953 | |
| 954 | /* Build `Array Py` from positional args. */ |
| 955 | lean_object *arr = lean_alloc_array((size_t)n, (size_t)n); |
| 956 | for (Py_ssize_t i = 0; i < n; i++) { |
| 957 | PyObject *po = p_PyTuple_GetItem(args, i); /* borrowed */ |
| 958 | p_Py_IncRef(po); /* +1 for wrapper */ |
| 959 | lean_object *wrapped = wrap_pyobject(po); |
| 960 | lean_array_set_core(arr, (size_t)i, wrapped); |
| 961 | } |
| 962 | |
| 963 | /* Bump closure ref so the Lean apply consumer doesn't free our |
| 964 | * captured reference. */ |
| 965 | lean_inc(self->closure); |
| 966 | lean_object *result = NULL; |
| 967 | |
| 968 | if (self->has_kw) { |
| 969 | Py_ssize_t kn = (kwds && p_PyDict_Size) ? p_PyDict_Size(kwds) : 0; |
| 970 | if (kn < 0) kn = 0; |
| 971 | lean_object *kwarr = lean_alloc_array((size_t)kn, (size_t)kn); |
| 972 | if (kn > 0) { |
| 973 | Py_ssize_t pos = 0; |
| 974 | PyObject *k = NULL, *v = NULL; |
| 975 | size_t idx = 0; |
| 976 | while (p_PyDict_Next(kwds, &pos, &k, &v)) { |
| 977 | const char *cs = p_PyUnicode_AsUTF8(k); |
| 978 | if (!cs) cs = ""; |
| 979 | lean_object *key_str = lean_mk_string(cs); |
| 980 | p_Py_IncRef(v); |
| 981 | lean_object *val_py = wrap_pyobject(v); |
| 982 | lean_object *pair = lean_alloc_ctor(0, 2, 0); |
| 983 | lean_ctor_set(pair, 0, key_str); |
| 984 | lean_ctor_set(pair, 1, val_py); |
| 985 | lean_array_set_core(kwarr, idx++, pair); |
| 986 | } |
| 987 | } |
| 988 | result = lean_apply_3(self->closure, arr, kwarr, lean_box(0)); |
| 989 | } else { |
| 990 | result = lean_apply_2(self->closure, arr, lean_box(0)); |
nothing calls this directly
no test coverage detected