Terry said:
If we interpret 'should' as 'preferably by me', ok.
It will take some programmer's time to add the special case check and run
the test suite, and check in the changes. Yours? And perhaps some
execution time for each frozenset call. Since frozenset is not much used,
and multiple empty frozensets very rare, and the difference mostly
invisible, the frozenset implementor probably went on to other things.
I read 'not much used' and 'very rare' as 'I rarely use them'. Others may.
It does not take much additional execution time, I just checked, a partial
test is already in there that should be enough for the 'frozenset()' case.
Additional tests for empty iterables would however be more costly and
therefore not necessarily worth doing. Up to the maintainers.
I don't have any experience in writing extension modules for the standard
library and 'running the test suite'. Implementing the check is trivial,
though. Could anyone please 'run the test suite' ?
I tested it a bit, though, seems to work, including subclassing.
Stefan
--- Objects/setobject.c.ORIG 2005-02-12 14:04:54.000000000 +0100
+++ Objects/setobject.c 2005-02-12 14:41:04.000000000 +0100
@@ -76,6 +76,8 @@
return (PyObject *)so;
}
+PyObject *frozen_empty_set = NULL;
+
static PyObject *
frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -83,7 +85,14 @@
if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
return NULL;
- if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
+ if (iterable == NULL) {
+ if (type == &PyFrozenSet_Type) {
+ if (frozen_empty_set == NULL)
+ frozen_empty_set = make_new_set(type, NULL);
+ Py_INCREF(frozen_empty_set);
+ return frozen_empty_set;
+ }
+ } else if (PyFrozenSet_CheckExact(iterable)) {
Py_INCREF(iterable);
return iterable;
}
--- Objects/setobject.c.ORIG 2005-02-12 14:04:54.000000000 +0100
+++ Objects/setobject.c 2005-02-12 14:41:04.000000000 +0100
@@ -76,6 +76,8 @@
return (PyObject *)so;
}
+PyObject *frozen_empty_set = NULL;
+
static PyObject *
frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -83,7 +85,14 @@
if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
return NULL;
- if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
+ if (iterable == NULL) {
+ if (type == &PyFrozenSet_Type) {
+ if (frozen_empty_set == NULL)
+ frozen_empty_set = make_new_set(type, NULL);
+ Py_INCREF(frozen_empty_set);
+ return frozen_empty_set;
+ }
+ } else if (PyFrozenSet_CheckExact(iterable)) {
Py_INCREF(iterable);
return iterable;
}