diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 64e891f9f6eb4d..c22bea75d2795c 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -244,8 +244,6 @@ struct _is { /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ PySliceObject *slice_cache; - // The empty frozenset is a singleton. - PyObject *empty_frozenset; struct _Py_tuple_state tuple; struct _Py_list_state list; diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 9a3063aa2775f0..30ba48423f9ec4 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -62,7 +62,6 @@ extern void _PyFrame_Fini(PyThreadState *tstate); extern void _PyDict_Fini(PyThreadState *tstate); extern void _PyTuple_Fini(PyThreadState *tstate); extern void _PyList_Fini(PyThreadState *tstate); -extern void _PySet_Fini(PyThreadState *tstate); extern void _PyBytes_Fini(PyThreadState *tstate); extern void _PyFloat_Fini(PyThreadState *tstate); extern void _PySlice_Fini(PyThreadState *tstate); diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index ace1593999d4eb..b7f4dbb98e36d4 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -158,13 +158,6 @@ def test_sets(self): for constructor in (set, frozenset): self.helper(constructor(self.d.keys())) - @support.cpython_only - def test_empty_frozenset_singleton(self): - # marshal.loads() must reuse the empty frozenset singleton - obj = frozenset() - obj2 = marshal.loads(marshal.dumps(obj)) - self.assertIs(obj2, obj) - class BufferTestCase(unittest.TestCase, HelperMixin): diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 9851a998983f83..68d494213e5870 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -661,15 +661,6 @@ def test_init(self): s.__init__(self.otherword) self.assertEqual(s, set(self.word)) - def test_singleton_empty_frozenset(self): - f = frozenset() - efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), - frozenset(), frozenset([]), frozenset(()), frozenset(''), - frozenset(range(0)), frozenset(frozenset()), - frozenset(f), f] - # All of the empty frozensets should have just one id() - self.assertEqual(len(set(map(id, efs))), 1) - def test_constructor_identity(self): s = self.thetype(range(3)) t = self.thetype(s) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index 95fab369748f0a..a62383d2093ecd 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -2,8 +2,9 @@ Each interpreter now its has own free lists, singletons and caches: * Free lists: float, tuple, list, dict, frame, context, asynchronous generator. -* Singletons: empty tuple, empty frozenset, empty bytes string, +* Singletons: empty tuple, empty bytes string, single byte character. * Slice cache. They are no longer shared by all interpreters. + diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst new file mode 100644 index 00000000000000..25f146e35ef439 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-07-35-11.bpo-40521.dMNA6k.rst @@ -0,0 +1 @@ +Empty frozensets are no longer singletons. diff --git a/Objects/setobject.c b/Objects/setobject.c index 69bfc7d0a58fb2..b2711495b657bd 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -978,38 +978,16 @@ make_new_set_basetype(PyTypeObject *type, PyObject *iterable) static PyObject * make_new_frozenset(PyTypeObject *type, PyObject *iterable) { - PyObject *res; - if (type != &PyFrozenSet_Type) { return make_new_set(type, iterable); } - if (iterable != NULL) { - if (PyFrozenSet_CheckExact(iterable)) { - /* frozenset(f) is idempotent */ - Py_INCREF(iterable); - return iterable; - } - res = make_new_set((PyTypeObject *)type, iterable); - if (res == NULL || PySet_GET_SIZE(res) != 0) { - return res; - } - /* If the created frozenset is empty, return the empty frozenset singleton instead */ - Py_DECREF(res); + if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) { + /* frozenset(f) is idempotent */ + Py_INCREF(iterable); + return iterable; } - - // The empty frozenset is a singleton - PyInterpreterState *interp = _PyInterpreterState_GET(); - res = interp->empty_frozenset; - if (res == NULL) { - interp->empty_frozenset = make_new_set((PyTypeObject *)type, NULL); - res = interp->empty_frozenset; - if (res == NULL) { - return NULL; - } - } - Py_INCREF(res); - return res; + return make_new_set((PyTypeObject *)type, iterable); } static PyObject * @@ -2304,12 +2282,6 @@ PySet_Add(PyObject *anyset, PyObject *key) return set_add_key((PySetObject *)anyset, key); } -void -_PySet_Fini(PyThreadState *tstate) -{ - Py_CLEAR(tstate->interp->empty_frozenset); -} - int _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index f0770727f4de71..09945a8f7a6a07 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1253,7 +1253,6 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) _PyAsyncGen_Fini(tstate); _PyContext_Fini(tstate); - _PySet_Fini(tstate); _PyDict_Fini(tstate); _PyList_Fini(tstate); _PyTuple_Fini(tstate); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy