Ensure that PySet_Add() operates on a newly created frozenset, like PyTuple_SetItem does.

Add PyFrozenSet_Check(), which was not needed before; The list of Py*Set_Check* macros seems to be complete now.

Add missing NEWS entries about all this.
This commit is contained in:
Amaury Forgeot d'Arc 2008-02-03 22:51:43 +00:00
parent e6a8074892
commit cab3d98ca1
4 changed files with 24 additions and 2 deletions

View File

@ -58,6 +58,13 @@ the constructor functions work with any iterable Python object.
.. versionadded:: 2.6
.. cfunction:: int PyFrozenSet_Check(PyObject *p)
Return true if *p* is a :class:`frozenset` object or an instance of a
subtype.
.. versionadded:: 2.6
.. cfunction:: int PyAnySet_Check(PyObject *p)
Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an

View File

@ -74,7 +74,11 @@ PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \
PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type))
#define PySet_Check(ob) \
(Py_TYPE(ob) == &PySet_Type || PyType_IsSubtype(Py_TYPE(ob), &PySet_Type))
(Py_TYPE(ob) == &PySet_Type || \
PyType_IsSubtype(Py_TYPE(ob), &PySet_Type))
#define PyFrozenSet_Check(ob) \
(Py_TYPE(ob) == &PyFrozenSet_Type || \\
PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type))
PyAPI_FUNC(PyObject *) PySet_New(PyObject *);
PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *);

View File

@ -1471,6 +1471,12 @@ Build
C API
-----
- ``PySet_Add()`` can now modify a newly created frozenset. Similarly to
``PyTuple_SetItem``, it can be used to populate a brand new frozenset; but
it does not steal a reference to the added item.
- Added ``PySet_Check()`` and ``PyFrozenSet_Check()`` to the set API.
- Backport of PyUnicode_FromString(), _FromStringAndSize(), _Format and
_FormatV from Python 3.0. Made PyLong_AsSsize_t and PyLong_FromSsize_t
public functions.

View File

@ -2188,7 +2188,8 @@ PySet_Discard(PyObject *set, PyObject *key)
int
PySet_Add(PyObject *anyset, PyObject *key)
{
if (!PyAnySet_Check(anyset)) {
if (!PySet_Check(anyset) &&
(!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
PyErr_BadInternalCall();
return -1;
}
@ -2306,6 +2307,10 @@ test_c_api(PySetObject *so)
f = PyFrozenSet_New(dup);
assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
assert(PySet_Add(f, elem) == 0);
Py_INCREF(f);
assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
Py_DECREF(f);
Py_DECREF(f);
/* Exercise direct iteration */