Skip to content

Commit f9bd05e

Browse files
authored
bpo-40521: Empty frozenset is no longer a singleton (GH-21085)
* Revert "bpo-40521: Make the empty frozenset per interpreter (GH-21068)" This reverts commit 261cfed. * bpo-40521: Empty frozensets are no longer singletons * Complete the removal of the frozenset singleton
1 parent 522691c commit f9bd05e

File tree

8 files changed

+8
-54
lines changed

8 files changed

+8
-54
lines changed

Include/internal/pycore_interp.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,6 @@ struct _is {
244244
/* Using a cache is very effective since typically only a single slice is
245245
created and then deleted again. */
246246
PySliceObject *slice_cache;
247-
// The empty frozenset is a singleton.
248-
PyObject *empty_frozenset;
249247

250248
struct _Py_tuple_state tuple;
251249
struct _Py_list_state list;

Include/internal/pycore_pylifecycle.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ extern void _PyFrame_Fini(PyThreadState *tstate);
6262
extern void _PyDict_Fini(PyThreadState *tstate);
6363
extern void _PyTuple_Fini(PyThreadState *tstate);
6464
extern void _PyList_Fini(PyThreadState *tstate);
65-
extern void _PySet_Fini(PyThreadState *tstate);
6665
extern void _PyBytes_Fini(PyThreadState *tstate);
6766
extern void _PyFloat_Fini(PyThreadState *tstate);
6867
extern void _PySlice_Fini(PyThreadState *tstate);

Lib/test/test_marshal.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,6 @@ def test_sets(self):
158158
for constructor in (set, frozenset):
159159
self.helper(constructor(self.d.keys()))
160160

161-
@support.cpython_only
162-
def test_empty_frozenset_singleton(self):
163-
# marshal.loads() must reuse the empty frozenset singleton
164-
obj = frozenset()
165-
obj2 = marshal.loads(marshal.dumps(obj))
166-
self.assertIs(obj2, obj)
167-
168161

169162
class BufferTestCase(unittest.TestCase, HelperMixin):
170163

Lib/test/test_set.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -661,15 +661,6 @@ def test_init(self):
661661
s.__init__(self.otherword)
662662
self.assertEqual(s, set(self.word))
663663

664-
def test_singleton_empty_frozenset(self):
665-
f = frozenset()
666-
efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
667-
frozenset(), frozenset([]), frozenset(()), frozenset(''),
668-
frozenset(range(0)), frozenset(frozenset()),
669-
frozenset(f), f]
670-
# All of the empty frozensets should have just one id()
671-
self.assertEqual(len(set(map(id, efs))), 1)
672-
673664
def test_constructor_identity(self):
674665
s = self.thetype(range(3))
675666
t = self.thetype(s)

Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ Each interpreter now its has own free lists, singletons and caches:
22

33
* Free lists: float, tuple, list, dict, frame, context,
44
asynchronous generator.
5-
* Singletons: empty tuple, empty frozenset, empty bytes string,
5+
* Singletons: empty tuple, empty bytes string,
66
single byte character.
77
* Slice cache.
88

99
They are no longer shared by all interpreters.
10+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Empty frozensets are no longer singletons.

Objects/setobject.c

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -978,38 +978,16 @@ make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
978978
static PyObject *
979979
make_new_frozenset(PyTypeObject *type, PyObject *iterable)
980980
{
981-
PyObject *res;
982-
983981
if (type != &PyFrozenSet_Type) {
984982
return make_new_set(type, iterable);
985983
}
986984

987-
if (iterable != NULL) {
988-
if (PyFrozenSet_CheckExact(iterable)) {
989-
/* frozenset(f) is idempotent */
990-
Py_INCREF(iterable);
991-
return iterable;
992-
}
993-
res = make_new_set((PyTypeObject *)type, iterable);
994-
if (res == NULL || PySet_GET_SIZE(res) != 0) {
995-
return res;
996-
}
997-
/* If the created frozenset is empty, return the empty frozenset singleton instead */
998-
Py_DECREF(res);
985+
if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
986+
/* frozenset(f) is idempotent */
987+
Py_INCREF(iterable);
988+
return iterable;
999989
}
1000-
1001-
// The empty frozenset is a singleton
1002-
PyInterpreterState *interp = _PyInterpreterState_GET();
1003-
res = interp->empty_frozenset;
1004-
if (res == NULL) {
1005-
interp->empty_frozenset = make_new_set((PyTypeObject *)type, NULL);
1006-
res = interp->empty_frozenset;
1007-
if (res == NULL) {
1008-
return NULL;
1009-
}
1010-
}
1011-
Py_INCREF(res);
1012-
return res;
990+
return make_new_set((PyTypeObject *)type, iterable);
1013991
}
1014992

1015993
static PyObject *
@@ -2304,12 +2282,6 @@ PySet_Add(PyObject *anyset, PyObject *key)
23042282
return set_add_key((PySetObject *)anyset, key);
23052283
}
23062284

2307-
void
2308-
_PySet_Fini(PyThreadState *tstate)
2309-
{
2310-
Py_CLEAR(tstate->interp->empty_frozenset);
2311-
}
2312-
23132285
int
23142286
_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
23152287
{

Python/pylifecycle.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,6 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp)
12531253
_PyAsyncGen_Fini(tstate);
12541254
_PyContext_Fini(tstate);
12551255

1256-
_PySet_Fini(tstate);
12571256
_PyDict_Fini(tstate);
12581257
_PyList_Fini(tstate);
12591258
_PyTuple_Fini(tstate);

0 commit comments

Comments
 (0)
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