
You can create a frozenset from any iterable using PyFrozenSet_New(). If you don't have an iterable and want to build-up the frozenset one element at a time, the approach is to create a regular set (or some other mutable container), add to it, then convert it to a frozenset when you're done: s = PySet_New(NULL); PySet_Add(s, obj1); PySet_Add(s, obj2); PySet_Add(s, obj3); f = PyFrozenSet_New(s); Py_DECREF(s); That approach is similar to what you do with tuples in pure python. You either build them from an iterable "t = tuple(iterable)" or your build-up a mutable object one element at a time and convert it all at once: s = [] s.append(obj1) s.append(obj2) t = tuple(s) The API you propose doesn't work because sets and frozensets are not indexed like tuples and lists. Accordingly, sets and frozensets have a C API that is more like dictionaries. Since dictionaries are not indexable, they also cannot have an API like the one you propose: PyDict_NEW(int) => PySetObject * PyDict_SET_ITEM(s, index, key, value) If you find all this really annoying and need to fashion a small frozenset with a few known objects, consider using the abstract API: f = PyObject_CallFunction(&PyFrozenSet_Type, "(OOO)", obj1, obj2, obj3); That will roll the whole process up into one line. Hope this was helpful, Raymond --------------------------------------------------------------- Bill Janssen <janssen@parc.com>Add To Address Book|This is Spam Subject:[Python-Dev] frozenset C API? To:python-dev@python.org I'm looking at building a "frozenset" instance as a return value from a C function, and the C API seems ridiculously clumsy. Maybe I'm misunderstanding it. Apparently, I need to create a list object, then pass that to PyFrozenSet_New(), then decref the list object. Is that correct? What I'd like is something more like PyFrozenSet_NEW(int) => PySetObject * PyFrozenSet_SET_ITEM(s, i, v) Any idea why these aren't part of the API?

Raymond, thanks for the note.
This is essentially the same thing I mentioned, except using a set instead of a list as the iterable. I'm just a tad annoyed at the fact that I know at set creation time exactly how many elements it's going to have, and this procedure strikes me as a somewhat inefficient way to create that set. Just tickles my "C inefficiency" funnybone a bit :-).
Didn't really mean to propose "PyDict_SET_ITEM(s, index, key, value)", should have been PyDict_SET_ITEM(s, index, value) But your point is still well taken. How about this one, though: PyDict_NEW(int) => PySetObject * PyDict_ADD(s, value) ADD would just stick value in the next empty slot (and steal its reference). Bill
participants (2)
-
Bill Janssen
-
Raymond Hettinger