https://github.com/python/cpython/commit/75f38af7810af1c3ca567d6224a975f85aef970f
commit: 75f38af7810af1c3ca567d6224a975f85aef970f
branch: main
author: Sam Gross <[email protected]>
committer: colesbury <[email protected]>
date: 2025-02-28T16:57:48-05:00
summary:
Revert "gh-128942: make `array` module thread safe (#128943)" (#130707)
The change regressed performance on scimark benchmarks from the
pyperformance benchmark suite.
This reverts commit 8ba0d7bbc295781bf27902380521db97a272c442.
files:
D Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
M Lib/test/test_array.py
M Modules/arraymodule.c
M Modules/clinic/arraymodule.c.h
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index bc3eeef8000190..58ea89c4fac833 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -3,21 +3,16 @@
"""
import collections.abc
-import io
import unittest
from test import support
from test.support import import_helper
from test.support import os_helper
-from test.support import threading_helper
from test.support import _2G
import weakref
import pickle
import operator
-import random
import struct
import sys
-import sysconfig
-import threading
import warnings
import array
@@ -1678,266 +1673,5 @@ def test_gh_128961(self):
self.assertRaises(StopIteration, next, it)
-class FreeThreadingTest(unittest.TestCase):
- # Test pretty much everything that can break under free-threading.
- # Non-deterministic, but at least one of these things will fail if
- # array module is not free-thread safe.
-
- @unittest.skipUnless(support.Py_GIL_DISABLED, 'this test can only possibly
fail with GIL disabled')
- @threading_helper.reap_threads
- @threading_helper.requires_working_threading()
- def test_free_threading(self):
- def pop1(b, a): # MODIFIES!
- b.wait()
- try: a.pop()
- except IndexError: pass
-
- def append1(b, a): # MODIFIES!
- b.wait()
- a.append(2)
-
- def insert1(b, a): # MODIFIES!
- b.wait()
- a.insert(0, 2)
-
- def extend(b, a): # MODIFIES!
- c = array.array('i', [2])
- b.wait()
- a.extend(c)
-
- def extend2(b, a, c): # MODIFIES!
- b.wait()
- a.extend(c)
-
- def inplace_concat(b, a): # MODIFIES!
- c = array.array('i', [2])
- b.wait()
- a += c
-
- def inplace_concat2(b, a, c): # MODIFIES!
- b.wait()
- a += c
-
- def inplace_repeat2(b, a): # MODIFIES!
- b.wait()
- a *= 2
-
- def clear(b, a, *args): # MODIFIES!
- b.wait()
- a.clear()
-
- def clear2(b, a, c): # MODIFIES c!
- b.wait()
- try: c.clear()
- except BufferError: pass
-
- def remove1(b, a): # MODIFIES!
- b.wait()
- try: a.remove(1)
- except ValueError: pass
-
- def fromunicode(b, a): # MODIFIES!
- b.wait()
- a.fromunicode('test')
-
- def frombytes(b, a): # MODIFIES!
- b.wait()
- a.frombytes(b'0000')
-
- def frombytes2(b, a, c): # MODIFIES!
- b.wait()
- a.frombytes(c)
-
- def fromlist(b, a): # MODIFIES!
- n = random.randint(0, 100)
- b.wait()
- a.fromlist([2] * n)
-
- def ass_subscr2(b, a, c): # MODIFIES!
- b.wait()
- a[:] = c
-
- def ass0(b, a): # modifies inplace
- b.wait()
- try: a[0] = 0
- except IndexError: pass
-
- def byteswap(b, a): # modifies inplace
- b.wait()
- a.byteswap()
-
- def tounicode(b, a):
- b.wait()
- a.tounicode()
-
- def tobytes(b, a):
- b.wait()
- a.tobytes()
-
- def tolist(b, a):
- b.wait()
- a.tolist()
-
- def tofile(b, a):
- f = io.BytesIO()
- b.wait()
- a.tofile(f)
-
- def reduce_ex2(b, a):
- b.wait()
- a.__reduce_ex__(2)
-
- def reduce_ex3(b, a):
- b.wait()
- c = a.__reduce_ex__(3)
- assert not c[1] or 0xdd not in c[1][3]
-
- def copy(b, a):
- b.wait()
- c = a.__copy__()
- assert not c or 0xdd not in c
-
- def repr1(b, a):
- b.wait()
- repr(a)
-
- def repeat2(b, a):
- b.wait()
- a * 2
-
- def count1(b, a):
- b.wait()
- a.count(1)
-
- def index1(b, a):
- b.wait()
- try: a.index(1)
- except ValueError: pass
-
- def contains1(b, a):
- b.wait()
- try: 1 in a
- except ValueError: pass
-
- def subscr0(b, a):
- b.wait()
- try: a[0]
- except IndexError: pass
-
- def concat(b, a):
- b.wait()
- a + a
-
- def concat2(b, a, c):
- b.wait()
- a + c
-
- def richcmplhs(b, a):
- c = a[:]
- b.wait()
- a == c
-
- def richcmprhs(b, a):
- c = a[:]
- b.wait()
- c == a
-
- def new(b, a):
- tc = a.typecode
- b.wait()
- array.array(tc, a)
-
- def repr_(b, a):
- b.wait()
- repr(a)
-
- def irepeat(b, a): # MODIFIES!
- b.wait()
- a *= 2
-
- def newi(b, l):
- b.wait()
- array.array('i', l)
-
- def fromlistl(b, a, l): # MODIFIES!
- b.wait()
- a.fromlist(l)
-
- def fromlistlclear(b, a, l): # MODIFIES LIST!
- b.wait()
- l.clear()
-
- def iter_next(b, a, it): # MODIFIES ITERATOR!
- b.wait()
- list(it)
-
- def iter_reduce(b, a, it):
- b.wait()
- c = it.__reduce__()
- assert not c[1] or 0xdd not in c[1][0]
-
- def check(funcs, a=None, *args):
- if a is None:
- a = array.array('i', [1])
-
- barrier = threading.Barrier(len(funcs))
- threads = []
-
- for func in funcs:
- thread = threading.Thread(target=func, args=(barrier, a,
*args))
-
- threads.append(thread)
-
- with threading_helper.start_threads(threads):
- pass
-
- check([pop1] * 10)
- check([pop1] + [subscr0] * 10)
- check([append1] * 10)
- check([insert1] * 10)
- check([pop1] + [index1] * 10)
- check([pop1] + [contains1] * 10)
- check([insert1] + [repeat2] * 10)
- check([pop1] + [repr1] * 10)
- check([inplace_repeat2] * 10)
- check([byteswap] * 10)
- check([insert1] + [clear] * 10)
- check([pop1] + [count1] * 10)
- check([remove1] * 10)
- check([clear] + [copy] * 10, array.array('B', b'0' * 0x400000))
- check([pop1] + [reduce_ex2] * 10)
- check([clear] + [reduce_ex3] * 10, array.array('B', b'0' * 0x400000))
- check([pop1] + [tobytes] * 10)
- check([pop1] + [tolist] * 10)
- check([clear, tounicode] * 10, array.array('w', 'a'*10000))
- check([clear, tofile] * 10, array.array('w', 'a'*10000))
- check([clear] + [extend] * 10)
- check([clear] + [inplace_concat] * 10)
- check([clear] + [concat] * 10, array.array('w', 'a'*10000))
- check([fromunicode] * 10, array.array('w', 'a'))
- check([frombytes] * 10)
- check([fromlist] * 10)
- check([clear] + [richcmplhs] * 10, array.array('i', [1]*10000))
- check([clear] + [richcmprhs] * 10, array.array('i', [1]*10000))
- check([clear, ass0] * 10, array.array('i', [1]*10000)) # to test
array_ass_item must disable Py_mp_ass_subscript
- check([clear] + [new] * 10, array.array('w', 'a'*10000))
- check([clear] + [repr_] * 10, array.array('B', b'0' * 0x40000))
- check([clear] + [repr_] * 10, array.array('B', b'0' * 0x40000))
- check([clear] + [irepeat] * 10, array.array('B', b'0' * 0x40000))
- check([clear] + [iter_reduce] * 10, a := array.array('B', b'0' *
0x400), iter(a))
-
- # make sure we handle non-self objects correctly
- check([clear] + [newi] * 10, [2] * random.randint(0, 100))
- check([fromlistlclear] + [fromlistl] * 10, array.array('i', [1]), [2]
* random.randint(0, 100))
- check([clear2] + [concat2] * 10, array.array('w', 'a'*10000),
array.array('w', 'a'*10000))
- check([clear2] + [inplace_concat2] * 10, array.array('w', 'a'*10000),
array.array('w', 'a'*10000))
- check([clear2] + [extend2] * 10, array.array('w', 'a'*10000),
array.array('w', 'a'*10000))
- check([clear2] + [ass_subscr2] * 10, array.array('w', 'a'*10000),
array.array('w', 'a'*10000))
- check([clear2] + [frombytes2] * 10, array.array('w', 'a'*10000),
array.array('B', b'a'*10000))
-
- # iterator stuff
- check([clear] + [iter_next] * 10, a := array.array('i', [1] * 10),
iter(a))
-
-
if __name__ == "__main__":
unittest.main()
diff --git
a/Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
b/Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
deleted file mode 100644
index 2b5eb581f1ffa1..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
+++ /dev/null
@@ -1 +0,0 @@
-Make the :mod:`array` module safe under :term:`free threading`.
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 0775b26e1d68ed..5b86ec98393e48 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -13,7 +13,6 @@
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_modsupport.h" // _PyArg_NoKeywords()
#include "pycore_moduleobject.h" // _PyModule_GetState()
-#include "pycore_pyatomic_ft_wrappers.h"
#include <stddef.h> // offsetof()
#include <stdbool.h>
@@ -69,19 +68,6 @@ typedef struct {
PyObject *str_iter;
} array_state;
-static inline Py_ssize_t Pyarrayobject_GET_SIZE(PyObject *op) {
- arrayobject *ao = (arrayobject *)op;
-#ifdef Py_GIL_DISABLED
- return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(ao)->ob_size));
-#else
- return Py_SIZE(ao);
-#endif
-}
-#define Pyarrayobject_GET_SIZE(op) Pyarrayobject_GET_SIZE(_PyObject_CAST(op))
-
-/* Forward declaration. */
-static PyObject *array_array_frombytes(PyObject *self, PyObject *bytes);
-
static array_state *
get_array_state(PyObject *module)
{
@@ -147,7 +133,6 @@ enum machine_format_code {
static int
array_resize(arrayobject *self, Py_ssize_t newsize)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
char *items;
size_t _new_size;
@@ -173,7 +158,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
PyMem_Free(self->ob_item);
self->ob_item = NULL;
Py_SET_SIZE(self, 0);
- FT_ATOMIC_STORE_SSIZE_RELAXED(self->allocated, 0);
+ self->allocated = 0;
return 0;
}
@@ -203,7 +188,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
}
self->ob_item = items;
Py_SET_SIZE(self, newsize);
- FT_ATOMIC_STORE_SSIZE_RELAXED(self->allocated, _new_size);
+ self->allocated = _new_size;
return 0;
}
@@ -687,7 +672,6 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const
struct arraydescr *des
static PyObject *
getarrayitem(PyObject *op, Py_ssize_t i)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
#ifndef NDEBUG
array_state *state = find_array_state_by_type(Py_TYPE(op));
assert(array_Check(op, state));
@@ -701,7 +685,6 @@ getarrayitem(PyObject *op, Py_ssize_t i)
static int
ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
char *items;
Py_ssize_t n = Py_SIZE(self);
if (v == NULL) {
@@ -745,11 +728,6 @@ array_dealloc(PyObject *op)
PyObject_GC_UnTrack(op);
arrayobject *self = arrayobject_CAST(op);
- if (self->ob_exports > 0) {
- PyErr_SetString(PyExc_SystemError,
- "deallocated array object has exported buffers");
- PyErr_Print();
- }
if (self->weakreflist != NULL) {
PyObject_ClearWeakRefs(op);
}
@@ -761,10 +739,8 @@ array_dealloc(PyObject *op)
}
static PyObject *
-array_richcompare_lock_held(PyObject *v, PyObject *w, int op)
+array_richcompare(PyObject *v, PyObject *w, int op)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v);
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(w);
array_state *state = find_array_state_by_type(Py_TYPE(v));
arrayobject *va, *wa;
PyObject *vi = NULL;
@@ -872,27 +848,15 @@ array_richcompare_lock_held(PyObject *v, PyObject *w, int
op)
return res;
}
-static PyObject *
-array_richcompare(PyObject *v, PyObject *w, int op)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION2(v, w);
- ret = array_richcompare_lock_held(v, w, op);
- Py_END_CRITICAL_SECTION2();
- return ret;
-}
-
static Py_ssize_t
array_length(PyObject *op)
{
- arrayobject *self = arrayobject_CAST(op);
- return Pyarrayobject_GET_SIZE(self);
+ return Py_SIZE(op);
}
static PyObject *
-array_item_lock_held(PyObject *op, Py_ssize_t i)
+array_item(PyObject *op, Py_ssize_t i)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
if (i < 0 || i >= Py_SIZE(op)) {
PyErr_SetString(PyExc_IndexError, "array index out of range");
return NULL;
@@ -900,20 +864,9 @@ array_item_lock_held(PyObject *op, Py_ssize_t i)
return getarrayitem(op, i);
}
-static PyObject *
-array_item(PyObject *op, Py_ssize_t i)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_item_lock_held(op, i);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static PyObject *
array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(a);
array_state *state = find_array_state_by_type(Py_TYPE(a));
arrayobject *np;
@@ -938,7 +891,6 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t
ihigh)
}
/*[clinic input]
-@critical_section
array.array.clear
Remove all items from the array.
@@ -946,7 +898,7 @@ Remove all items from the array.
static PyObject *
array_array_clear_impl(arrayobject *self)
-/*[clinic end generated code: output=5efe0417062210a9 input=1c9dfcc80f5b6731]*/
+/*[clinic end generated code: output=5efe0417062210a9 input=5dffa30e94e717a4]*/
{
if (array_resize(self, 0) == -1) {
return NULL;
@@ -955,7 +907,6 @@ array_array_clear_impl(arrayobject *self)
}
/*[clinic input]
-@critical_section
array.array.__copy__
Return a copy of the array.
@@ -963,13 +914,12 @@ Return a copy of the array.
static PyObject *
array_array___copy___impl(arrayobject *self)
-/*[clinic end generated code: output=dec7c3f925d9619e input=7622f8f9489472d5]*/
+/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/
{
return array_slice(self, 0, Py_SIZE(self));
}
/*[clinic input]
-@critical_section
array.array.__deepcopy__
unused: object
@@ -979,17 +929,15 @@ Return a copy of the array.
[clinic start generated code]*/
static PyObject *
-array_array___deepcopy___impl(arrayobject *self, PyObject *unused)
-/*[clinic end generated code: output=703b4c412feaaf31 input=1a29f718f5b8a1dc]*/
+array_array___deepcopy__(arrayobject *self, PyObject *unused)
+/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/
{
return array_array___copy___impl(self);
}
static PyObject *
-array_concat_lock_held(PyObject *op, PyObject *bb)
+array_concat(PyObject *op, PyObject *bb)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(bb);
arrayobject *a = arrayobject_CAST(op);
array_state *state = find_array_state_by_type(Py_TYPE(a));
Py_ssize_t size;
@@ -1025,19 +973,8 @@ array_concat_lock_held(PyObject *op, PyObject *bb)
}
static PyObject *
-array_concat(PyObject *op, PyObject *bb)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION2(op, bb);
- ret = array_concat_lock_held(op, bb);
- Py_END_CRITICAL_SECTION2();
- return ret;
-}
-
-static PyObject *
-array_repeat_lock_held(PyObject *op, Py_ssize_t n)
+array_repeat(PyObject *op, Py_ssize_t n)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
arrayobject *a = arrayobject_CAST(op);
array_state *state = find_array_state_by_type(Py_TYPE(a));
@@ -1061,20 +998,9 @@ array_repeat_lock_held(PyObject *op, Py_ssize_t n)
return (PyObject *)np;
}
-static PyObject *
-array_repeat(PyObject *op, Py_ssize_t n)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_repeat_lock_held(op, n);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static int
array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(a);
char *item;
Py_ssize_t d; /* Change in size */
if (ilow < 0)
@@ -1108,9 +1034,8 @@ array_del_slice(arrayobject *a, Py_ssize_t ilow,
Py_ssize_t ihigh)
}
static int
-setarrayitem(PyObject *op, Py_ssize_t i, PyObject *v)
+array_ass_item(PyObject *op, Py_ssize_t i, PyObject *v)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
arrayobject *a = arrayobject_CAST(op);
if (i < 0 || i >= Py_SIZE(a)) {
PyErr_SetString(PyExc_IndexError,
@@ -1123,20 +1048,18 @@ setarrayitem(PyObject *op, Py_ssize_t i, PyObject *v)
}
static int
-array_ass_item(PyObject *op, Py_ssize_t i, PyObject *v)
+setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
{
- int ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = setarrayitem(op, i, v);
- Py_END_CRITICAL_SECTION();
- return ret;
+#ifndef NDEBUG
+ array_state *state = find_array_state_by_type(Py_TYPE(a));
+ assert(array_Check(a, state));
+#endif
+ return array_ass_item(a, i, v);
}
static int
array_iter_extend(arrayobject *self, PyObject *bb)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(bb);
PyObject *it, *v;
it = PyObject_GetIter(bb);
@@ -1158,10 +1081,8 @@ array_iter_extend(arrayobject *self, PyObject *bb)
}
static int
-array_do_extend_lock_held(array_state *state, arrayobject *self, PyObject *bb)
+array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(bb);
Py_ssize_t size, oldsize, bbsize;
if (!array_Check(bb, state))
@@ -1192,16 +1113,6 @@ array_do_extend_lock_held(array_state *state,
arrayobject *self, PyObject *bb)
#undef b
}
-static int
-array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
-{
- int ret;
- Py_BEGIN_CRITICAL_SECTION2(self, bb);
- ret = array_do_extend_lock_held(state, self, bb);
- Py_END_CRITICAL_SECTION2();
- return ret;
-}
-
static PyObject *
array_inplace_concat(PyObject *op, PyObject *bb)
{
@@ -1220,9 +1131,8 @@ array_inplace_concat(PyObject *op, PyObject *bb)
}
static PyObject *
-array_inplace_repeat_lock_held(PyObject *op, Py_ssize_t n)
+array_inplace_repeat(PyObject *op, Py_ssize_t n)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
arrayobject *self = arrayobject_CAST(op);
const Py_ssize_t array_size = Py_SIZE(self);
@@ -1245,19 +1155,16 @@ array_inplace_repeat_lock_held(PyObject *op, Py_ssize_t
n)
return Py_NewRef(self);
}
+
static PyObject *
-array_inplace_repeat(PyObject *op, Py_ssize_t n)
+ins(arrayobject *self, Py_ssize_t where, PyObject *v)
{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_inplace_repeat_lock_held(op, n);
- Py_END_CRITICAL_SECTION();
- return ret;
+ if (ins1(self, where, v) != 0)
+ return NULL;
+ Py_RETURN_NONE;
}
-
/*[clinic input]
-@critical_section
array.array.count
v: object
@@ -1267,8 +1174,8 @@ Return number of occurrences of v in the array.
[clinic start generated code]*/
static PyObject *
-array_array_count_impl(arrayobject *self, PyObject *v)
-/*[clinic end generated code: output=93ead26a2affb739 input=c12c0042c1d0e27e]*/
+array_array_count(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/
{
Py_ssize_t count = 0;
Py_ssize_t i;
@@ -1292,7 +1199,6 @@ array_array_count_impl(arrayobject *self, PyObject *v)
/*[clinic input]
-@critical_section
array.array.index
v: object
@@ -1308,7 +1214,7 @@ Raise ValueError if the value is not present.
static PyObject *
array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,
Py_ssize_t stop)
-/*[clinic end generated code: output=c45e777880c99f52 input=fa32ac8ec22175d6]*/
+/*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/
{
if (start < 0) {
start += Py_SIZE(self);
@@ -1341,34 +1247,22 @@ array_array_index_impl(arrayobject *self, PyObject *v,
Py_ssize_t start,
}
static int
-array_contains_lock_held(PyObject *op, PyObject *v)
+array_contains(PyObject *self, PyObject *v)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
Py_ssize_t i;
int cmp;
- for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(op); i++) {
- PyObject *opi = getarrayitem(op, i);
- if (opi == NULL)
+ for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
+ PyObject *selfi = getarrayitem(self, i);
+ if (selfi == NULL)
return -1;
- cmp = PyObject_RichCompareBool(opi, v, Py_EQ);
- Py_DECREF(opi);
+ cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+ Py_DECREF(selfi);
}
return cmp;
}
-static int
-array_contains(PyObject *op, PyObject *v)
-{
- int ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_contains_lock_held(op, v);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
/*[clinic input]
-@critical_section
array.array.remove
v: object
@@ -1378,8 +1272,8 @@ Remove the first occurrence of v in the array.
[clinic start generated code]*/
static PyObject *
-array_array_remove_impl(arrayobject *self, PyObject *v)
-/*[clinic end generated code: output=f2a24e288ecb2a35 input=78bef3fd40e62f7a]*/
+array_array_remove(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/
{
Py_ssize_t i;
@@ -1405,7 +1299,6 @@ array_array_remove_impl(arrayobject *self, PyObject *v)
}
/*[clinic input]
-@critical_section
array.array.pop
i: Py_ssize_t = -1
@@ -1418,7 +1311,7 @@ i defaults to -1.
static PyObject *
array_array_pop_impl(arrayobject *self, Py_ssize_t i)
-/*[clinic end generated code: output=bc1f0c54fe5308e4 input=c69a7f1f8c570e2f]*/
+/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/
{
PyObject *v;
@@ -1465,7 +1358,6 @@ array_array_extend_impl(arrayobject *self, PyTypeObject
*cls, PyObject *bb)
}
/*[clinic input]
-@critical_section
array.array.insert
i: Py_ssize_t
@@ -1477,15 +1369,12 @@ Insert a new item v into the array before position i.
static PyObject *
array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v)
-/*[clinic end generated code: output=5a3648e278348564 input=3c922bbd81462978]*/
+/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/
{
- if (ins1(self, i, v) != 0)
- return NULL;
- Py_RETURN_NONE;
+ return ins(self, i, v);
}
/*[clinic input]
-@critical_section
array.array.buffer_info
Return a tuple (address, length) giving the current memory address and the
length in items of the buffer used to hold array's contents.
@@ -1496,7 +1385,7 @@ the buffer length in bytes.
static PyObject *
array_array_buffer_info_impl(arrayobject *self)
-/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=9d0dc1ff0e6542e8]*/
+/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/
{
PyObject *retval = NULL, *v;
@@ -1522,7 +1411,6 @@ array_array_buffer_info_impl(arrayobject *self)
}
/*[clinic input]
-@critical_section
array.array.append
v: object
@@ -1532,16 +1420,13 @@ Append new value v to the end of the array.
[clinic start generated code]*/
static PyObject *
-array_array_append_impl(arrayobject *self, PyObject *v)
-/*[clinic end generated code: output=2f1e8cbad70c2a8b input=9cdd897c66a40c3f]*/
+array_array_append(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/
{
- if (ins1(self, Py_SIZE(self), v) != 0)
- return NULL;
- Py_RETURN_NONE;
+ return ins(self, Py_SIZE(self), v);
}
/*[clinic input]
-@critical_section
array.array.byteswap
Byteswap all items of the array.
@@ -1552,7 +1437,7 @@ raised.
static PyObject *
array_array_byteswap_impl(arrayobject *self)
-/*[clinic end generated code: output=5f8236cbdf0d90b5 input=e691b6eff94d8b2e]*/
+/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/
{
char *p;
Py_ssize_t i;
@@ -1602,7 +1487,6 @@ array_array_byteswap_impl(arrayobject *self)
}
/*[clinic input]
-@critical_section
array.array.reverse
Reverse the order of the items in the array.
@@ -1610,7 +1494,7 @@ Reverse the order of the items in the array.
static PyObject *
array_array_reverse_impl(arrayobject *self)
-/*[clinic end generated code: output=c04868b36f6f4089 input=e3947e98aed068ed]*/
+/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/
{
Py_ssize_t itemsize = self->ob_descr->itemsize;
char *p, *q;
@@ -1700,7 +1584,6 @@ array_array_fromfile_impl(arrayobject *self, PyTypeObject
*cls, PyObject *f,
}
/*[clinic input]
-@critical_section
array.array.tofile
cls: defining_class
@@ -1712,7 +1595,7 @@ Write all items (as machine values) to the file object f.
static PyObject *
array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)
-/*[clinic end generated code: output=4560c628d9c18bc2 input=a26bc66df57864dd]*/
+/*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52]*/
{
Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
/* Write 64K blocks at a time */
@@ -1745,12 +1628,11 @@ array_array_tofile_impl(arrayobject *self, PyTypeObject
*cls, PyObject *f)
Py_DECREF(res); /* drop write result */
}
-done:
+ done:
Py_RETURN_NONE;
}
/*[clinic input]
-@critical_section self list
array.array.fromlist
list: object
@@ -1760,8 +1642,8 @@ Append items to array from list.
[clinic start generated code]*/
static PyObject *
-array_array_fromlist_impl(arrayobject *self, PyObject *list)
-/*[clinic end generated code: output=6c23733a68dd68df input=c7c056aaf85d997a]*/
+array_array_fromlist(arrayobject *self, PyObject *list)
+/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/
{
Py_ssize_t n;
@@ -1794,7 +1676,6 @@ array_array_fromlist_impl(arrayobject *self, PyObject
*list)
}
/*[clinic input]
-@critical_section
array.array.tolist
Convert array to an ordinary list with the same items.
@@ -1802,7 +1683,7 @@ Convert array to an ordinary list with the same items.
static PyObject *
array_array_tolist_impl(arrayobject *self)
-/*[clinic end generated code: output=00b60cc9eab8ef89 input=4543fdbac475c52c]*/
+/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
{
PyObject *list = PyList_New(Py_SIZE(self));
Py_ssize_t i;
@@ -1822,29 +1703,19 @@ array_array_tolist_impl(arrayobject *self)
return NULL;
}
-
-/*[clinic input]
-@critical_section
-array.array.frombytes
-
- buffer: Py_buffer
- /
-
-Appends items from the string, interpreting it as an array of machine values,
as if it had been read from a file using the fromfile() method.
-[clinic start generated code]*/
-
static PyObject *
-array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
-/*[clinic end generated code: output=d9842c8f7510a516 input=2245f9ea58579960]*/
+frombytes(arrayobject *self, Py_buffer *buffer)
{
int itemsize = self->ob_descr->itemsize;
Py_ssize_t n;
if (buffer->itemsize != 1) {
+ PyBuffer_Release(buffer);
PyErr_SetString(PyExc_TypeError, "a bytes-like object is required");
return NULL;
}
n = buffer->len;
if (n % itemsize != 0) {
+ PyBuffer_Release(buffer);
PyErr_SetString(PyExc_ValueError,
"bytes length not a multiple of item size");
return NULL;
@@ -1854,19 +1725,37 @@ array_array_frombytes_impl(arrayobject *self, Py_buffer
*buffer)
Py_ssize_t old_size = Py_SIZE(self);
if ((n > PY_SSIZE_T_MAX - old_size) ||
((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
+ PyBuffer_Release(buffer);
return PyErr_NoMemory();
}
if (array_resize(self, old_size + n) == -1) {
+ PyBuffer_Release(buffer);
return NULL;
}
memcpy(self->ob_item + old_size * itemsize,
buffer->buf, n * itemsize);
}
+ PyBuffer_Release(buffer);
Py_RETURN_NONE;
}
/*[clinic input]
-@critical_section
+array.array.frombytes
+
+ buffer: Py_buffer
+ /
+
+Appends items from the string, interpreting it as an array of machine values,
as if it had been read from a file using the fromfile() method.
+[clinic start generated code]*/
+
+static PyObject *
+array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
+/*[clinic end generated code: output=d9842c8f7510a516 input=378db226dfac949e]*/
+{
+ return frombytes(self, buffer);
+}
+
+/*[clinic input]
array.array.tobytes
Convert the array to an array of machine values and return the bytes
representation.
@@ -1874,7 +1763,7 @@ Convert the array to an array of machine values and
return the bytes representat
static PyObject *
array_array_tobytes_impl(arrayobject *self)
-/*[clinic end generated code: output=87318e4edcdc2bb6 input=c4d44d5499d2320f]*/
+/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
{
if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
return PyBytes_FromStringAndSize(self->ob_item,
@@ -1885,7 +1774,6 @@ array_array_tobytes_impl(arrayobject *self)
}
/*[clinic input]
-@critical_section
array.array.fromunicode
ustr: unicode
@@ -1900,7 +1788,7 @@ some other type.
static PyObject *
array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
-/*[clinic end generated code: output=24359f5e001a7f2b input=01e2a776cee82011]*/
+/*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/
{
int typecode = self->ob_descr->typecode;
if (typecode != 'u' && typecode != 'w') {
@@ -1948,7 +1836,6 @@ array_array_fromunicode_impl(arrayobject *self, PyObject
*ustr)
}
/*[clinic input]
-@critical_section
array.array.tounicode
Extends this array with data from the unicode string ustr.
@@ -1960,7 +1847,7 @@ unicode string from an array of some other type.
static PyObject *
array_array_tounicode_impl(arrayobject *self)
-/*[clinic end generated code: output=08e442378336e1ef input=6c69dfe81a279b91]*/
+/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
{
int typecode = self->ob_descr->typecode;
if (typecode != 'u' && typecode != 'w') {
@@ -1989,8 +1876,7 @@ array_array___sizeof___impl(arrayobject *self)
/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
{
size_t res = _PyObject_SIZE(Py_TYPE(self));
- res += (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(self->allocated)
- * (size_t)self->ob_descr->itemsize;
+ res += (size_t)self->allocated * (size_t)self->ob_descr->itemsize;
return PyLong_FromSize_t(res);
}
@@ -2385,7 +2271,6 @@ array__array_reconstructor_impl(PyObject *module,
PyTypeObject *arraytype,
}
/*[clinic input]
-@critical_section
array.array.__reduce_ex__
cls: defining_class
@@ -2398,7 +2283,7 @@ Return state information for pickling.
static PyObject *
array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls,
PyObject *value)
-/*[clinic end generated code: output=4958ee5d79452ad5 input=18c90a4cad7ac527]*/
+/*[clinic end generated code: output=4958ee5d79452ad5 input=19968cf0f91d3eea]*/
{
PyObject *dict;
PyObject *result;
@@ -2526,9 +2411,8 @@ static PyMethodDef array_methods[] = {
};
static PyObject *
-array_repr_lock_held(PyObject *op)
+array_repr(PyObject *op)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
char typecode;
PyObject *s, *v = NULL;
Py_ssize_t len;
@@ -2554,20 +2438,9 @@ array_repr_lock_held(PyObject *op)
return s;
}
-static PyObject *
-array_repr(PyObject *op)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_repr_lock_held(op);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static PyObject*
-array_subscr_lock_held(PyObject *op, PyObject *item)
+array_subscr(PyObject *op, PyObject *item)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
arrayobject *self = arrayobject_CAST(op);
array_state *state = find_array_state_by_type(Py_TYPE(self));
@@ -2629,28 +2502,12 @@ array_subscr_lock_held(PyObject *op, PyObject *item)
}
}
-static PyObject *
-array_subscr(PyObject *op, PyObject *item)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_subscr_lock_held(op, item);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static int
-array_ass_subscr_lock_held(PyObject *op, PyObject* item, PyObject* value)
+array_ass_subscr(PyObject *op, PyObject *item, PyObject *value)
{
- array_state* state = find_array_state_by_type(Py_TYPE(op));
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
-#ifdef Py_DEBUG
- if (value != NULL && array_Check(value, state)) {
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(value);
- }
-#endif
- arrayobject *self = arrayobject_CAST(op);
Py_ssize_t start, stop, step, slicelength, needed;
+ arrayobject *self = arrayobject_CAST(op);
+ array_state* state = find_array_state_by_type(Py_TYPE(self));
arrayobject* other;
int itemsize;
@@ -2701,7 +2558,7 @@ array_ass_subscr_lock_held(PyObject *op, PyObject* item,
PyObject* value)
value = array_slice(other, 0, needed);
if (value == NULL)
return -1;
- ret = array_ass_subscr_lock_held(op, item, value);
+ ret = array_ass_subscr(op, item, value);
Py_DECREF(value);
return ret;
}
@@ -2804,38 +2661,19 @@ array_ass_subscr_lock_held(PyObject *op, PyObject*
item, PyObject* value)
}
}
-static int
-array_ass_subscr(PyObject *op, PyObject* item, PyObject* value)
-{
- int ret;
- array_state* state = find_array_state_by_type(Py_TYPE(op));
- if (value != NULL && array_Check(value, state)) {
- Py_BEGIN_CRITICAL_SECTION2(op, value);
- ret = array_ass_subscr_lock_held(op, item, value);
- Py_END_CRITICAL_SECTION2();
- }
- else {
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_ass_subscr_lock_held(op, item, value);
- Py_END_CRITICAL_SECTION();
- }
- return ret;
-}
-
static const void *emptybuf = "";
static int
-array_buffer_getbuf_lock_held(PyObject *op, Py_buffer *view, int flags)
+array_buffer_getbuf(PyObject *op, Py_buffer *view, int flags)
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
- arrayobject *self = arrayobject_CAST(op);
if (view == NULL) {
PyErr_SetString(PyExc_BufferError,
"array_buffer_getbuf: view==NULL argument is obsolete");
return -1;
}
+ arrayobject *self = arrayobject_CAST(op);
view->buf = (void *)self->ob_item;
view->obj = Py_NewRef(self);
if (view->buf == NULL)
@@ -2867,39 +2705,61 @@ array_buffer_getbuf_lock_held(PyObject *op, Py_buffer
*view, int flags)
return 0;
}
-static int
-array_buffer_getbuf(PyObject *op, Py_buffer *view, int flags)
-{
- int ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = array_buffer_getbuf_lock_held(op, view, flags);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static void
array_buffer_relbuf(PyObject *op, Py_buffer *Py_UNUSED(view))
{
- Py_BEGIN_CRITICAL_SECTION(op);
arrayobject *self = arrayobject_CAST(op);
self->ob_exports--;
- assert(self->ob_exports >= 0);
- Py_END_CRITICAL_SECTION();
}
static PyObject *
-array_new_internal_lock_held(PyTypeObject *type, PyObject *initial, int c)
+array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
-#ifdef Py_DEBUG
- if (initial != NULL) {
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(initial);
- }
-#endif
array_state *state = find_array_state_by_type(type);
- PyObject *it = NULL;
+ int c;
+ PyObject *initial = NULL, *it = NULL;
const struct arraydescr *descr;
+
+ if ((type == state->ArrayType ||
+ type->tp_init == state->ArrayType->tp_init) &&
+ !_PyArg_NoKeywords("array.array", kwds))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
+ return NULL;
+
+ if (PySys_Audit("array.__new__", "CO",
+ c, initial ? initial : Py_None) < 0) {
+ return NULL;
+ }
+
+ if (c == 'u') {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "The 'u' type code is deprecated and "
+ "will be removed in Python 3.16",
+ 1)) {
+ return NULL;
+ }
+ }
+
bool is_unicode = c == 'u' || c == 'w';
+ if (initial && !is_unicode) {
+ if (PyUnicode_Check(initial)) {
+ PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
+ "an array with typecode '%c'", c);
+ return NULL;
+ }
+ else if (array_Check(initial, state)) {
+ int ic = ((arrayobject*)initial)->ob_descr->typecode;
+ if (ic == 'u' || ic == 'w') {
+ PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
+ "initialize an array with typecode '%c'", c);
+ return NULL;
+ }
+ }
+ }
+
if (!(initial == NULL || PyList_Check(initial)
|| PyByteArray_Check(initial)
|| PyBytes_Check(initial)
@@ -3017,69 +2877,6 @@ array_new_internal_lock_held(PyTypeObject *type,
PyObject *initial, int c)
return NULL;
}
-static PyObject *
-array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- array_state *state = find_array_state_by_type(type);
- int c;
- PyObject *initial = NULL;
-
- if ((type == state->ArrayType ||
- type->tp_init == state->ArrayType->tp_init) &&
- !_PyArg_NoKeywords("array.array", kwds)) {
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) {
- return NULL;
- }
-
- if (PySys_Audit("array.__new__", "CO",
- c, initial ? initial : Py_None) < 0) {
- return NULL;
- }
-
- if (c == 'u') {
- if (PyErr_WarnEx(PyExc_DeprecationWarning,
- "The 'u' type code is deprecated and "
- "will be removed in Python 3.16",
- 1)) {
- return NULL;
- }
- }
-
- bool is_unicode = c == 'u' || c == 'w';
-
- if (initial && !is_unicode) {
- if (PyUnicode_Check(initial)) {
- PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
- "an array with typecode '%c'", c);
- return NULL;
- }
- else if (array_Check(initial, state)) {
- int ic = ((arrayobject*)initial)->ob_descr->typecode;
- if (ic == 'u' || ic == 'w') {
- PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
- "initialize an array with typecode '%c'", c);
- return NULL;
- }
- }
- }
-
- PyObject *ret;
-
- if (initial == NULL) {
- ret = array_new_internal_lock_held(type, initial, c);
- }
- else {
- Py_BEGIN_CRITICAL_SECTION(initial);
- ret = array_new_internal_lock_held(type, initial, c);
- Py_END_CRITICAL_SECTION();
- }
-
- return ret;
-}
-
PyDoc_STRVAR(module_doc,
"This module defines an object type which can efficiently represent\n\
@@ -3222,7 +3019,7 @@ array_iter(PyObject *op)
return NULL;
it->ao = (arrayobject*)Py_NewRef(ao);
- it->index = 0; // -1 indicates exhausted
+ it->index = 0;
it->getitem = ao->ob_descr->getitem;
PyObject_GC_Track(it);
return (PyObject *)it;
@@ -3233,37 +3030,23 @@ arrayiter_next(PyObject *op)
{
arrayiterobject *it = arrayiterobject_CAST(op);
assert(it != NULL);
- Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->index);
- if (index < 0) {
- return NULL;
- }
- PyObject *ret;
- arrayobject *ao = it->ao;
#ifndef NDEBUG
array_state *state = find_array_state_by_type(Py_TYPE(it));
assert(PyObject_TypeCheck(it, state->ArrayIterType));
- assert(array_Check(ao, state));
#endif
-
- Py_BEGIN_CRITICAL_SECTION(ao);
- if (index < Py_SIZE(ao)) {
- ret = (*it->getitem)(ao, index);
- }
- else {
- ret = NULL;
- }
- Py_END_CRITICAL_SECTION();
-
- if (ret != NULL) {
- FT_ATOMIC_STORE_SSIZE_RELAXED(it->index, index + 1);
+ arrayobject *ao = it->ao;
+ if (ao == NULL) {
+ return NULL;
}
- else {
- FT_ATOMIC_STORE_SSIZE_RELAXED(it->index, -1);
-#ifndef Py_GIL_DISABLED
- Py_CLEAR(it->ao);
+#ifndef NDEBUG
+ assert(array_Check(ao, state));
#endif
+ if (it->index < Py_SIZE(ao)) {
+ return (*it->getitem)(ao, it->index++);
}
- return ret;
+ it->ao = NULL;
+ Py_DECREF(ao);
+ return NULL;
}
static void
@@ -3299,14 +3082,14 @@ static PyObject *
array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls)
/*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e]*/
{
+
array_state *state = get_array_state_by_class(cls);
assert(state != NULL);
PyObject *func = _PyEval_GetBuiltin(state->str_iter);
- Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->index);
- if (index >= 0) {
- return Py_BuildValue("N(O)n", func, self->ao, index);
+ if (self->ao == NULL) {
+ return Py_BuildValue("N(())", func);
}
- return Py_BuildValue("N(())", func);
+ return Py_BuildValue("N(O)n", func, self->ao, self->index);
}
/*[clinic input]
@@ -3323,20 +3106,17 @@ array_arrayiterator___setstate__(arrayiterobject *self,
PyObject *state)
/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/
{
Py_ssize_t index = PyLong_AsSsize_t(state);
- if (index == -1 && PyErr_Occurred()) {
+ if (index == -1 && PyErr_Occurred())
return NULL;
- }
- if (FT_ATOMIC_LOAD_SSIZE_RELAXED(self->index) >= 0) {
- if (index < -1) {
- index = -1;
+ arrayobject *ao = self->ao;
+ if (ao != NULL) {
+ if (index < 0) {
+ index = 0;
}
- else {
- Py_ssize_t size = Pyarrayobject_GET_SIZE(self->ao);
- if (index > size) {
- index = size; /* iterator at end */
- }
+ else if (index > Py_SIZE(ao)) {
+ index = Py_SIZE(ao); /* iterator exhausted */
}
- FT_ATOMIC_STORE_SSIZE_RELAXED(self->index, index);
+ self->index = index;
}
Py_RETURN_NONE;
}
diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h
index 3816bb7709658e..c5b62b16699d06 100644
--- a/Modules/clinic/arraymodule.c.h
+++ b/Modules/clinic/arraymodule.c.h
@@ -6,7 +6,6 @@ preserve
# include "pycore_runtime.h" // _Py_SINGLETON()
#endif
#include "pycore_abstract.h" // _PyNumber_Index()
-#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
PyDoc_STRVAR(array_array_clear__doc__,
@@ -24,13 +23,7 @@ array_array_clear_impl(arrayobject *self);
static PyObject *
array_array_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_clear_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_clear_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array___copy____doc__,
@@ -48,13 +41,7 @@ array_array___copy___impl(arrayobject *self);
static PyObject *
array_array___copy__(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array___copy___impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array___copy___impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array___deepcopy____doc__,
@@ -66,21 +53,6 @@ PyDoc_STRVAR(array_array___deepcopy____doc__,
#define ARRAY_ARRAY___DEEPCOPY___METHODDEF \
{"__deepcopy__", (PyCFunction)array_array___deepcopy__, METH_O,
array_array___deepcopy____doc__},
-static PyObject *
-array_array___deepcopy___impl(arrayobject *self, PyObject *unused);
-
-static PyObject *
-array_array___deepcopy__(arrayobject *self, PyObject *unused)
-{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array___deepcopy___impl((arrayobject *)self, unused);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
-}
-
PyDoc_STRVAR(array_array_count__doc__,
"count($self, v, /)\n"
"--\n"
@@ -90,21 +62,6 @@ PyDoc_STRVAR(array_array_count__doc__,
#define ARRAY_ARRAY_COUNT_METHODDEF \
{"count", (PyCFunction)array_array_count, METH_O,
array_array_count__doc__},
-static PyObject *
-array_array_count_impl(arrayobject *self, PyObject *v);
-
-static PyObject *
-array_array_count(arrayobject *self, PyObject *v)
-{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_count_impl((arrayobject *)self, v);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
-}
-
PyDoc_STRVAR(array_array_index__doc__,
"index($self, v, start=0, stop=sys.maxsize, /)\n"
"--\n"
@@ -145,9 +102,7 @@ array_array_index(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
goto exit;
}
skip_optional:
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array_index_impl((arrayobject *)self, v, start, stop);
- Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -162,21 +117,6 @@ PyDoc_STRVAR(array_array_remove__doc__,
#define ARRAY_ARRAY_REMOVE_METHODDEF \
{"remove", (PyCFunction)array_array_remove, METH_O,
array_array_remove__doc__},
-static PyObject *
-array_array_remove_impl(arrayobject *self, PyObject *v);
-
-static PyObject *
-array_array_remove(arrayobject *self, PyObject *v)
-{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_remove_impl((arrayobject *)self, v);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
-}
-
PyDoc_STRVAR(array_array_pop__doc__,
"pop($self, i=-1, /)\n"
"--\n"
@@ -216,9 +156,7 @@ array_array_pop(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
i = ival;
}
skip_optional:
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array_pop_impl((arrayobject *)self, i);
- Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -303,9 +241,7 @@ array_array_insert(PyObject *self, PyObject *const *args,
Py_ssize_t nargs)
i = ival;
}
v = args[1];
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array_insert_impl((arrayobject *)self, i, v);
- Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -329,13 +265,7 @@ array_array_buffer_info_impl(arrayobject *self);
static PyObject *
array_array_buffer_info(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_buffer_info_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_buffer_info_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array_append__doc__,
@@ -347,21 +277,6 @@ PyDoc_STRVAR(array_array_append__doc__,
#define ARRAY_ARRAY_APPEND_METHODDEF \
{"append", (PyCFunction)array_array_append, METH_O,
array_array_append__doc__},
-static PyObject *
-array_array_append_impl(arrayobject *self, PyObject *v);
-
-static PyObject *
-array_array_append(arrayobject *self, PyObject *v)
-{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_append_impl((arrayobject *)self, v);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
-}
-
PyDoc_STRVAR(array_array_byteswap__doc__,
"byteswap($self, /)\n"
"--\n"
@@ -380,13 +295,7 @@ array_array_byteswap_impl(arrayobject *self);
static PyObject *
array_array_byteswap(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_byteswap_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_byteswap_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array_reverse__doc__,
@@ -404,13 +313,7 @@ array_array_reverse_impl(arrayobject *self);
static PyObject *
array_array_reverse(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_reverse_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_reverse_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array_fromfile__doc__,
@@ -509,9 +412,7 @@ array_array_tofile(PyObject *self, PyTypeObject *cls,
PyObject *const *args, Py_
goto exit;
}
f = args[0];
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array_tofile_impl((arrayobject *)self, cls, f);
- Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -526,21 +427,6 @@ PyDoc_STRVAR(array_array_fromlist__doc__,
#define ARRAY_ARRAY_FROMLIST_METHODDEF \
{"fromlist", (PyCFunction)array_array_fromlist, METH_O,
array_array_fromlist__doc__},
-static PyObject *
-array_array_fromlist_impl(arrayobject *self, PyObject *list);
-
-static PyObject *
-array_array_fromlist(arrayobject *self, PyObject *list)
-{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION2(self, list);
- return_value = array_array_fromlist_impl((arrayobject *)self, list);
- Py_END_CRITICAL_SECTION2();
-
- return return_value;
-}
-
PyDoc_STRVAR(array_array_tolist__doc__,
"tolist($self, /)\n"
"--\n"
@@ -556,13 +442,7 @@ array_array_tolist_impl(arrayobject *self);
static PyObject *
array_array_tolist(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_tolist_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_tolist_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array_frombytes__doc__,
@@ -586,9 +466,7 @@ array_array_frombytes(PyObject *self, PyObject *arg)
if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) {
goto exit;
}
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array_frombytes_impl((arrayobject *)self, &buffer);
- Py_END_CRITICAL_SECTION();
exit:
/* Cleanup for buffer */
@@ -614,13 +492,7 @@ array_array_tobytes_impl(arrayobject *self);
static PyObject *
array_array_tobytes(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_tobytes_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_tobytes_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array_fromunicode__doc__,
@@ -650,9 +522,7 @@ array_array_fromunicode(PyObject *self, PyObject *arg)
goto exit;
}
ustr = arg;
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array_fromunicode_impl((arrayobject *)self, ustr);
- Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -677,13 +547,7 @@ array_array_tounicode_impl(arrayobject *self);
static PyObject *
array_array_tounicode(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- PyObject *return_value = NULL;
-
- Py_BEGIN_CRITICAL_SECTION(self);
- return_value = array_array_tounicode_impl((arrayobject *)self);
- Py_END_CRITICAL_SECTION();
-
- return return_value;
+ return array_array_tounicode_impl((arrayobject *)self);
}
PyDoc_STRVAR(array_array___sizeof____doc__,
@@ -795,9 +659,7 @@ array_array___reduce_ex__(PyObject *self, PyTypeObject
*cls, PyObject *const *ar
goto exit;
}
value = args[0];
- Py_BEGIN_CRITICAL_SECTION(self);
return_value = array_array___reduce_ex___impl((arrayobject *)self, cls,
value);
- Py_END_CRITICAL_SECTION();
exit:
return return_value;
@@ -833,4 +695,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
#define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \
{"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O,
array_arrayiterator___setstate____doc__},
-/*[clinic end generated code: output=c9219e074c62e0c8 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8120dc5c4fa414b9 input=a9049054013a1b77]*/
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]