From 08e48690196c5257bab8ca9eaf57703671c07882 Mon Sep 17 00:00:00 2001 From: fatelei Date: Tue, 14 Oct 2025 16:12:38 +0800 Subject: [PATCH 01/19] fix: gh-140025 queue.SimpleQueue.__sizeof__() ignores the underlying data structure --- Lib/test/test_queue.py | 54 +++++++++++++++++++++++++++++++++ Modules/_queuemodule.c | 19 ++++++++++++ Modules/clinic/_queuemodule.c.h | 30 +++++++++++++++++- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index c855fb8fe2b05a..fb29ab6d551587 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1009,6 +1009,60 @@ class C: gc_collect() # For PyPy or other GCs. self.assertIsNone(wr()) + def test_sizeof(self): + # Test that __sizeof__() accounts for underlying data structure + q = self.q + + # Get the size of an empty queue + empty_size = q.__sizeof__() + self.assertGreater(empty_size, 0, "Empty queue should have non-zero size") + + # Size should include basic object structure + # For C implementation, this includes the ring buffer array + # For Python implementation, this includes the underlying list + + # Add items within initial capacity (if applicable) + # For C SimpleQueue, initial capacity is 8 items + for i in range(8): + q.put(object()) + + size_after_8 = q.__sizeof__() + # Size may or may not change depending on implementation + # C implementation: no change (still within initial ring buffer capacity) + # Python implementation: may change (list growth) + + # Add one more item to potentially trigger growth + q.put(object()) # Now 9 items + + size_after_9 = q.__sizeof__() + self.assertGreaterEqual(size_after_9, size_after_8, + "Size should not decrease when adding items") + + # Test with a larger number of items + large_q = self.type2test() + for i in range(1000): + large_q.put(object()) + + large_size = large_q.__sizeof__() + + # For C implementation, size should grow with capacity + # For Python implementation, __sizeof__ may not account for underlying list + # (this is a known limitation of the Python implementation) + if self.__class__.__name__ == 'CSimpleQueueTest': + # This is the C implementation + self.assertGreater(large_size, empty_size, + "C SimpleQueue with many items should be larger than empty queue") + + # Verify size is reasonable (should be proportional to capacity) + # For very large queues, size should be significantly larger + self.assertGreater(large_size, empty_size * 2, + "Large C SimpleQueue should be at least 2x size of empty queue") + else: + # This is the Python implementation + # The Python implementation doesn't properly implement __sizeof__ + # but we can at least verify it returns a positive number + self.assertGreater(large_size, 0, "Python SimpleQueue should have positive size") + class PySimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 01235c77bd7db8..39f472d6f62e57 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -500,6 +500,24 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) return RingBuf_Len(&self->buf); } +/*[clinic input] +_queue.SimpleQueue.__sizeof__ -> Py_ssize_t + +Return size of queue in bytes, including underlying data structure. +[clinic start generated code]*/ + +static Py_ssize_t +_queue_SimpleQueue___sizeof___impl(simplequeueobject *self) +/*[clinic end generated code: output=58ce4e3bbc078fd4 input=7b9d000cdcb71b7d]*/ +{ + Py_ssize_t size = Py_TYPE(self)->tp_basicsize; + // Add size of the ring buffer items array + size += self->buf.items_cap * sizeof(PyObject *); + return size; +} + + + static int queue_traverse(PyObject *m, visitproc visit, void *arg) { @@ -534,6 +552,7 @@ static PyMethodDef simplequeue_methods[] = { _QUEUE_SIMPLEQUEUE_PUT_METHODDEF _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF + _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 1751d68716ba5f..ce0dbf8a128955 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -358,4 +358,32 @@ _queue_SimpleQueue_qsize(PyObject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=1d3efe9df89997cf input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_queue_SimpleQueue___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Return size of queue in bytes, including underlying data structure."); + +#define _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_queue_SimpleQueue___sizeof__, METH_NOARGS, _queue_SimpleQueue___sizeof____doc__}, + +static Py_ssize_t +_queue_SimpleQueue___sizeof___impl(simplequeueobject *self); + +static PyObject * +_queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _queue_SimpleQueue___sizeof___impl((simplequeueobject *)self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=dc7b32ca422336a2 input=a9049054013a1b77]*/ From 62cd1410c6015ca36a4c576986f7c78c10fbfd8c Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:07:10 +0000 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst diff --git a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst new file mode 100644 index 00000000000000..47c421d7d470e1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst @@ -0,0 +1 @@ +fix queue.SimpleQueue.__sizeof__() computation From a0a23b1e0c9f74ef3fba599e477ec5731f1f419a Mon Sep 17 00:00:00 2001 From: fatelei Date: Tue, 14 Oct 2025 22:11:22 +0800 Subject: [PATCH 03/19] chore: remove empty line --- Modules/_queuemodule.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 39f472d6f62e57..476f79bf16a818 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -516,8 +516,6 @@ _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) return size; } - - static int queue_traverse(PyObject *m, visitproc visit, void *arg) { From be61a227649899bc21d1814fab12d78e3c4995bf Mon Sep 17 00:00:00 2001 From: fatelei Date: Tue, 14 Oct 2025 22:17:53 +0800 Subject: [PATCH 04/19] chore: add @critical_section --- Modules/_queuemodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 476f79bf16a818..3976a29287a8e7 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -501,6 +501,7 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) } /*[clinic input] +@critical_section _queue.SimpleQueue.__sizeof__ -> Py_ssize_t Return size of queue in bytes, including underlying data structure. From dc4b475e0efd165ccbb8c831ec199ec16e22cd10 Mon Sep 17 00:00:00 2001 From: fatelei Date: Tue, 14 Oct 2025 22:30:13 +0800 Subject: [PATCH 05/19] chore: remove comment --- Modules/_queuemodule.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 3976a29287a8e7..9ee7dbf768f54d 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -501,7 +501,6 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) } /*[clinic input] -@critical_section _queue.SimpleQueue.__sizeof__ -> Py_ssize_t Return size of queue in bytes, including underlying data structure. @@ -512,7 +511,6 @@ _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) /*[clinic end generated code: output=58ce4e3bbc078fd4 input=7b9d000cdcb71b7d]*/ { Py_ssize_t size = Py_TYPE(self)->tp_basicsize; - // Add size of the ring buffer items array size += self->buf.items_cap * sizeof(PyObject *); return size; } From d3e633e184cf0280f35e3c9b78e338000d6464d4 Mon Sep 17 00:00:00 2001 From: fatelei Date: Wed, 15 Oct 2025 09:39:51 +0800 Subject: [PATCH 06/19] chore: resolve comment --- .../Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst | 2 +- Modules/_queuemodule.c | 4 +--- Modules/clinic/_queuemodule.c.h | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst index 47c421d7d470e1..39c5a688961e3c 100644 --- a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst +++ b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst @@ -1 +1 @@ -fix queue.SimpleQueue.__sizeof__() computation +fix ``queue.SimpleQueue.__sizeof__()`` computation diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 9ee7dbf768f54d..02f311451fbe89 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -502,13 +502,11 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) /*[clinic input] _queue.SimpleQueue.__sizeof__ -> Py_ssize_t - -Return size of queue in bytes, including underlying data structure. [clinic start generated code]*/ static Py_ssize_t _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) -/*[clinic end generated code: output=58ce4e3bbc078fd4 input=7b9d000cdcb71b7d]*/ +/*[clinic end generated code: output=58ce4e3bbc078fd4 input=6661f95bc010c7c5]*/ { Py_ssize_t size = Py_TYPE(self)->tp_basicsize; size += self->buf.items_cap * sizeof(PyObject *); diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index ce0dbf8a128955..1feae1869bcd5a 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -362,8 +362,7 @@ _queue_SimpleQueue_qsize(PyObject *self, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(_queue_SimpleQueue___sizeof____doc__, "__sizeof__($self, /)\n" "--\n" -"\n" -"Return size of queue in bytes, including underlying data structure."); +"\n"); #define _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_queue_SimpleQueue___sizeof__, METH_NOARGS, _queue_SimpleQueue___sizeof____doc__}, @@ -386,4 +385,4 @@ _queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=dc7b32ca422336a2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=64f86d4983c06225 input=a9049054013a1b77]*/ From 192bb61df0bac7ab359058b5bc0b5e07e630ccbf Mon Sep 17 00:00:00 2001 From: fatelei Date: Wed, 15 Oct 2025 10:02:40 +0800 Subject: [PATCH 07/19] chore: update comment in test_queue --- Lib/test/test_queue.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index fb29ab6d551587..2069fe2d83326d 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1019,7 +1019,7 @@ def test_sizeof(self): # Size should include basic object structure # For C implementation, this includes the ring buffer array - # For Python implementation, this includes the underlying list + # For Python implementation, this includes the underlying deque # Add items within initial capacity (if applicable) # For C SimpleQueue, initial capacity is 8 items @@ -1059,8 +1059,8 @@ def test_sizeof(self): "Large C SimpleQueue should be at least 2x size of empty queue") else: # This is the Python implementation - # The Python implementation doesn't properly implement __sizeof__ - # but we can at least verify it returns a positive number + # The Python implementation doesn't override __sizeof__ + # so it only accounts for the object itself, not the underlying deque self.assertGreater(large_size, 0, "Python SimpleQueue should have positive size") From 97ee255d13ae858c419e03955cfeb563cbdbfd6c Mon Sep 17 00:00:00 2001 From: fatelei Date: Wed, 15 Oct 2025 23:11:08 +0800 Subject: [PATCH 08/19] fix: fix misc content --- .../next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst index 39c5a688961e3c..918b99ed2e8be3 100644 --- a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst +++ b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst @@ -1 +1 @@ -fix ``queue.SimpleQueue.__sizeof__()`` computation +Fix ``queue.SimpleQueue.__sizeof__()`` computation From 7db68218b5c631998e9fabab4921a63351f5bc9f Mon Sep 17 00:00:00 2001 From: fatelei Date: Wed, 15 Oct 2025 23:18:12 +0800 Subject: [PATCH 09/19] chore: update comment --- Lib/test/test_queue.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 2069fe2d83326d..2c8bc267076584 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1022,14 +1022,13 @@ def test_sizeof(self): # For Python implementation, this includes the underlying deque # Add items within initial capacity (if applicable) - # For C SimpleQueue, initial capacity is 8 items for i in range(8): q.put(object()) size_after_8 = q.__sizeof__() # Size may or may not change depending on implementation # C implementation: no change (still within initial ring buffer capacity) - # Python implementation: may change (list growth) + # Python implementation: may change (deque growth, but __sizeof__ may not reflect it) # Add one more item to potentially trigger growth q.put(object()) # Now 9 items @@ -1046,8 +1045,8 @@ def test_sizeof(self): large_size = large_q.__sizeof__() # For C implementation, size should grow with capacity - # For Python implementation, __sizeof__ may not account for underlying list - # (this is a known limitation of the Python implementation) + # For Python implementation, __sizeof__ will not account for underlying deque + # (this is documented behavior on CPython; PyPy doesn't support __sizeof__ at all) if self.__class__.__name__ == 'CSimpleQueueTest': # This is the C implementation self.assertGreater(large_size, empty_size, From 18869ebd293161b428ee7b9a44b71282c3242657 Mon Sep 17 00:00:00 2001 From: fatelei Date: Wed, 15 Oct 2025 23:30:01 +0800 Subject: [PATCH 10/19] chore: add @critical_section --- Modules/_queuemodule.c | 3 ++- Modules/clinic/_queuemodule.c.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 02f311451fbe89..d9f2c509838e6d 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -501,12 +501,13 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) } /*[clinic input] +@critical_section _queue.SimpleQueue.__sizeof__ -> Py_ssize_t [clinic start generated code]*/ static Py_ssize_t _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) -/*[clinic end generated code: output=58ce4e3bbc078fd4 input=6661f95bc010c7c5]*/ +/*[clinic end generated code: output=58ce4e3bbc078fd4 input=40a793cdf1c78c30]*/ { Py_ssize_t size = Py_TYPE(self)->tp_basicsize; size += self->buf.items_cap * sizeof(PyObject *); diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 1feae1869bcd5a..f15ae6bcd24b0f 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -376,7 +376,9 @@ _queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) PyObject *return_value = NULL; Py_ssize_t _return_value; + Py_BEGIN_CRITICAL_SECTION(self); _return_value = _queue_SimpleQueue___sizeof___impl((simplequeueobject *)self); + Py_END_CRITICAL_SECTION(); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -385,4 +387,4 @@ _queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=64f86d4983c06225 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a27a14c5f640799e input=a9049054013a1b77]*/ From f3e6e1892a31820472938fd5e5fea17d654a6bac Mon Sep 17 00:00:00 2001 From: fatelei Date: Wed, 15 Oct 2025 23:40:54 +0800 Subject: [PATCH 11/19] chore: update misc news --- .../next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst index 918b99ed2e8be3..f086e70746946a 100644 --- a/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst +++ b/Misc/NEWS.d/next/Library/2025-10-14-14-07-08.gh-issue-140025.zQ_Fhe.rst @@ -1 +1 @@ -Fix ``queue.SimpleQueue.__sizeof__()`` computation +Fix ``queue.SimpleQueue.__sizeof__()`` computation. From b2207aa2d4d34babcf8afc9fe5679febc7d83041 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 11:38:40 +0800 Subject: [PATCH 12/19] chore: using _PyObject_SIZE --- Modules/_queuemodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index d9f2c509838e6d..ec9dcfc75b04da 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -509,7 +509,7 @@ static Py_ssize_t _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) /*[clinic end generated code: output=58ce4e3bbc078fd4 input=40a793cdf1c78c30]*/ { - Py_ssize_t size = Py_TYPE(self)->tp_basicsize; + Py_ssize_t size = _PyObject_SIZE(Py_TYPE(self)); size += self->buf.items_cap * sizeof(PyObject *); return size; } From 5547af481b7ca7980fb083f13643ac9213626a42 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 11:59:51 +0800 Subject: [PATCH 13/19] chore: resolve comment issue --- Lib/test/test_queue.py | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 2c8bc267076584..7d6a789186349f 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1010,18 +1010,11 @@ class C: self.assertIsNone(wr()) def test_sizeof(self): - # Test that __sizeof__() accounts for underlying data structure q = self.q - # Get the size of an empty queue empty_size = q.__sizeof__() self.assertGreater(empty_size, 0, "Empty queue should have non-zero size") - # Size should include basic object structure - # For C implementation, this includes the ring buffer array - # For Python implementation, this includes the underlying deque - - # Add items within initial capacity (if applicable) for i in range(8): q.put(object()) @@ -1034,8 +1027,7 @@ def test_sizeof(self): q.put(object()) # Now 9 items size_after_9 = q.__sizeof__() - self.assertGreaterEqual(size_after_9, size_after_8, - "Size should not decrease when adding items") + self.assertGreaterEqual(size_after_9, size_after_8) # Test with a larger number of items large_q = self.type2test() @@ -1070,6 +1062,22 @@ def setUp(self): self.type2test = self.queue._PySimpleQueue super().setUp() + def test_equality(self): + # Test that SimpleQueue uses object identity, not value equality + q1 = self.type2test() + q2 = self.type2test() + + # Different instances should not be equal + self.assertNotEqual(q1, q2) + + # Same instance should be equal to itself + self.assertEqual(q1, q1) + + # Even with same content, instances should not be equal + q1.put('test') + q2.put('test') + self.assertNotEqual(q1, q2) + @need_c_queue class CSimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): @@ -1084,6 +1092,22 @@ def test_is_default(self): self.assertIs(self.type2test, self.queue.SimpleQueue) self.assertIs(self.type2test, self.queue.SimpleQueue) + def test_equality(self): + # Test that SimpleQueue uses object identity, not value equality + q1 = self.type2test() + q2 = self.type2test() + + # Different instances should not be equal + self.assertNotEqual(q1, q2) + + # Same instance should be equal to itself + self.assertEqual(q1, q1) + + # Even with same content, instances should not be equal + q1.put('test') + q2.put('test') + self.assertNotEqual(q1, q2) + def test_reentrancy(self): # bpo-14976: put() may be called reentrantly in an asynchronous # callback. From faf79d42b2b8a7eb6d5c3353c1121c18804b23a8 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 12:08:12 +0800 Subject: [PATCH 14/19] fix: fix lint issue --- Lib/test/test_queue.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 7d6a789186349f..d26ddd9d8aadf3 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1066,13 +1066,13 @@ def test_equality(self): # Test that SimpleQueue uses object identity, not value equality q1 = self.type2test() q2 = self.type2test() - + # Different instances should not be equal self.assertNotEqual(q1, q2) - + # Same instance should be equal to itself self.assertEqual(q1, q1) - + # Even with same content, instances should not be equal q1.put('test') q2.put('test') @@ -1096,13 +1096,13 @@ def test_equality(self): # Test that SimpleQueue uses object identity, not value equality q1 = self.type2test() q2 = self.type2test() - + # Different instances should not be equal self.assertNotEqual(q1, q2) - + # Same instance should be equal to itself self.assertEqual(q1, q1) - + # Even with same content, instances should not be equal q1.put('test') q2.put('test') From 9339f3725c333e423b4d06d5103cee7bb59058b3 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 13:19:52 +0800 Subject: [PATCH 15/19] chore: py queue and c queue size of --- Lib/test/test_queue.py | 145 ++++++++++++----------------------------- 1 file changed, 43 insertions(+), 102 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index d26ddd9d8aadf3..4b8db95358fde0 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1009,74 +1009,38 @@ class C: gc_collect() # For PyPy or other GCs. self.assertIsNone(wr()) - def test_sizeof(self): - q = self.q - empty_size = q.__sizeof__() - self.assertGreater(empty_size, 0, "Empty queue should have non-zero size") - for i in range(8): - q.put(object()) - size_after_8 = q.__sizeof__() - # Size may or may not change depending on implementation - # C implementation: no change (still within initial ring buffer capacity) - # Python implementation: may change (deque growth, but __sizeof__ may not reflect it) +class PySimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): - # Add one more item to potentially trigger growth - q.put(object()) # Now 9 items + queue = py_queue + def setUp(self): + self.type2test = self.queue._PySimpleQueue + super().setUp() + def test_sizeof(self): + q = self.type2test() + + empty_size = q.__sizeof__() + self.assertGreater(empty_size, 0) + + for i in range(8): + q.put(object()) + + size_after_8 = q.__sizeof__() + + q.put(object()) size_after_9 = q.__sizeof__() self.assertGreaterEqual(size_after_9, size_after_8) - - # Test with a larger number of items + large_q = self.type2test() for i in range(1000): large_q.put(object()) - + large_size = large_q.__sizeof__() + self.assertGreater(large_size, 0) - # For C implementation, size should grow with capacity - # For Python implementation, __sizeof__ will not account for underlying deque - # (this is documented behavior on CPython; PyPy doesn't support __sizeof__ at all) - if self.__class__.__name__ == 'CSimpleQueueTest': - # This is the C implementation - self.assertGreater(large_size, empty_size, - "C SimpleQueue with many items should be larger than empty queue") - - # Verify size is reasonable (should be proportional to capacity) - # For very large queues, size should be significantly larger - self.assertGreater(large_size, empty_size * 2, - "Large C SimpleQueue should be at least 2x size of empty queue") - else: - # This is the Python implementation - # The Python implementation doesn't override __sizeof__ - # so it only accounts for the object itself, not the underlying deque - self.assertGreater(large_size, 0, "Python SimpleQueue should have positive size") - - -class PySimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): - - queue = py_queue - def setUp(self): - self.type2test = self.queue._PySimpleQueue - super().setUp() - - def test_equality(self): - # Test that SimpleQueue uses object identity, not value equality - q1 = self.type2test() - q2 = self.type2test() - - # Different instances should not be equal - self.assertNotEqual(q1, q2) - - # Same instance should be equal to itself - self.assertEqual(q1, q1) - - # Even with same content, instances should not be equal - q1.put('test') - q2.put('test') - self.assertNotEqual(q1, q2) @need_c_queue @@ -1088,53 +1052,30 @@ def setUp(self): self.type2test = self.queue.SimpleQueue super().setUp() - def test_is_default(self): - self.assertIs(self.type2test, self.queue.SimpleQueue) - self.assertIs(self.type2test, self.queue.SimpleQueue) - - def test_equality(self): - # Test that SimpleQueue uses object identity, not value equality - q1 = self.type2test() - q2 = self.type2test() - - # Different instances should not be equal - self.assertNotEqual(q1, q2) - - # Same instance should be equal to itself - self.assertEqual(q1, q1) - - # Even with same content, instances should not be equal - q1.put('test') - q2.put('test') - self.assertNotEqual(q1, q2) - - def test_reentrancy(self): - # bpo-14976: put() may be called reentrantly in an asynchronous - # callback. - q = self.q - gen = itertools.count() - N = 10000 - results = [] - - # This test exploits the fact that __del__ in a reference cycle - # can be called any time the GC may run. - - class Circular(object): - def __init__(self): - self.circular = self - - def __del__(self): - q.put(next(gen)) - - while True: - o = Circular() - q.put(next(gen)) - del o - results.append(q.get()) - if results[-1] >= N: - break + def test_sizeof(self): + q = self.type2test() + + empty_size = q.__sizeof__() + self.assertGreater(empty_size, 0, "Empty C SimpleQueue should have non-zero size") + + for i in range(8): + q.put(object()) + + size_after_8 = q.__sizeof__() - self.assertEqual(results, list(range(N + 1))) + q.put(object()) + size_after_9 = q.__sizeof__() + self.assertGreaterEqual(size_after_9, size_after_8) + + large_q = self.type2test() + for i in range(1000): + large_q.put(object()) + + large_size = large_q.__sizeof__() + + self.assertGreater(large_size, empty_size) + + self.assertGreater(large_size, empty_size * 2) if __name__ == "__main__": From b05e1380a38e8578dfc64d30414755a7f2fed82f Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 13:38:11 +0800 Subject: [PATCH 16/19] chore: resolve comment issue --- Lib/test/test_queue.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 4b8db95358fde0..ca6dbea7e0098f 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1010,8 +1010,6 @@ class C: self.assertIsNone(wr()) - - class PySimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase): queue = py_queue @@ -1030,7 +1028,7 @@ def test_sizeof(self): size_after_8 = q.__sizeof__() - q.put(object()) + q.put(object()) # Now 9 items size_after_9 = q.__sizeof__() self.assertGreaterEqual(size_after_9, size_after_8) @@ -1041,6 +1039,9 @@ def test_sizeof(self): large_size = large_q.__sizeof__() self.assertGreater(large_size, 0) + def test_is_default(self): + self.assertIsNot(self.type2test, self.queue.SimpleQueue) + self.assertIs(self.type2test, self.queue._PySimpleQueue) @need_c_queue @@ -1056,16 +1057,16 @@ def test_sizeof(self): q = self.type2test() empty_size = q.__sizeof__() - self.assertGreater(empty_size, 0, "Empty C SimpleQueue should have non-zero size") + self.assertGreater(empty_size, 0) for i in range(8): q.put(object()) size_after_8 = q.__sizeof__() - q.put(object()) + q.put(object()) # Now 9 items - should trigger ring buffer growth size_after_9 = q.__sizeof__() - self.assertGreaterEqual(size_after_9, size_after_8) + self.assertGreater(size_after_9, size_after_8) large_q = self.type2test() for i in range(1000): From a7353670031a516e8e9015faaac7090d4a108f27 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 13:45:08 +0800 Subject: [PATCH 17/19] fix: fix lint issue --- Lib/test/test_queue.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index ca6dbea7e0098f..cff88f7e544345 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1,6 +1,5 @@ # Some simple queue module tests, plus some failure conditions # to ensure the Queue locks remain stable. -import itertools import random import threading import time @@ -1019,23 +1018,23 @@ def setUp(self): def test_sizeof(self): q = self.type2test() - + empty_size = q.__sizeof__() self.assertGreater(empty_size, 0) - + for i in range(8): q.put(object()) - + size_after_8 = q.__sizeof__() - + q.put(object()) # Now 9 items size_after_9 = q.__sizeof__() self.assertGreaterEqual(size_after_9, size_after_8) - + large_q = self.type2test() for i in range(1000): large_q.put(object()) - + large_size = large_q.__sizeof__() self.assertGreater(large_size, 0) @@ -1055,27 +1054,27 @@ def setUp(self): def test_sizeof(self): q = self.type2test() - + empty_size = q.__sizeof__() self.assertGreater(empty_size, 0) - + for i in range(8): q.put(object()) - + size_after_8 = q.__sizeof__() q.put(object()) # Now 9 items - should trigger ring buffer growth size_after_9 = q.__sizeof__() self.assertGreater(size_after_9, size_after_8) - + large_q = self.type2test() for i in range(1000): large_q.put(object()) - + large_size = large_q.__sizeof__() - + self.assertGreater(large_size, empty_size) - + self.assertGreater(large_size, empty_size * 2) From 3b228f8e684537e7bf1235c2630b3f0051bfca72 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 14:14:21 +0800 Subject: [PATCH 18/19] fix: fix ut --- Lib/test/test_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index cff88f7e544345..ac13975b887477 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1039,7 +1039,7 @@ def test_sizeof(self): self.assertGreater(large_size, 0) def test_is_default(self): - self.assertIsNot(self.type2test, self.queue.SimpleQueue) + self.assertIs(self.type2test, self.queue.SimpleQueue) self.assertIs(self.type2test, self.queue._PySimpleQueue) From 121d6809e89fd8bfeb0544f8249bfc5609d353c9 Mon Sep 17 00:00:00 2001 From: fatelei Date: Thu, 16 Oct 2025 14:21:42 +0800 Subject: [PATCH 19/19] chore: remove test_is_default --- Lib/test/test_queue.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index ac13975b887477..5cc1503bb64667 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1038,10 +1038,6 @@ def test_sizeof(self): large_size = large_q.__sizeof__() self.assertGreater(large_size, 0) - def test_is_default(self): - self.assertIs(self.type2test, self.queue.SimpleQueue) - self.assertIs(self.type2test, self.queue._PySimpleQueue) - @need_c_queue class CSimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase):