C-API PySet_Add fails on frozenset
Here's a relatively simple C function that demonstrates this
PyObject* make_and_fill_frozenset() {
PyObject* fr_set = PyFrozenSet_New(NULL);
if (!fr_set) return NULL;
for (int i=0; i<10; ++i) {
PyObject* i_py = PyLong_FromLong(i);
if (!i_py) {
Py_DECREF(fr_set);
return NULL;
}
int res = PySet_Add(fr_set, i_py);
Py_DECREF(i_py);
if (res == -1) {
Py_DECREF(fr_set);
return NULL;
}
}
return fr_set;
}
When run it reports SystemError: Bad internal call!
The documentation for PySet_Add
implies that it should work. Similarly the documentation for PyFrozenSet_New
says:
Now guaranteed to return a brand-new frozenset. Formerly, frozensets of zero-length were a singleton. This got in the way of building-up new frozensets with PySet_Add().
which is specific to PyPy and implies that it did work once.
For ease of testing the C code can be put into a short Cython program to generate the wrapper module around it:
cdef extern from "c_code_filename.cpp":
object make_and_fill_frozenset()
def make_and_fill_frozenset_wrapper():
return make_and_fill_frozenset()