Skip to content

Commit fb6212a

Browse files
committed
test and tsan stuff
1 parent a3e6004 commit fb6212a

File tree

2 files changed

+60
-45
lines changed

2 files changed

+60
-45
lines changed

Lib/test/test_array.py

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import collections.abc
66
import io
7+
import os
78
import unittest
89
from test import support
910
from test.support import import_helper
@@ -104,7 +105,10 @@ def test_empty(self):
104105
class ArrayReconstructorTest(unittest.TestCase):
105106

106107
def setUp(self):
107-
self.enterContext(warnings.catch_warnings())
108+
if (not support.Py_GIL_DISABLED or
109+
any('"parallel_threads": null' in a for a in sys.argv) or
110+
all('parallel_threads' not in a for a in sys.argv)):
111+
self.enterContext(warnings.catch_warnings())
108112
warnings.filterwarnings(
109113
"ignore",
110114
message="The 'u' type code is deprecated and "
@@ -220,7 +224,10 @@ class BaseTest:
220224
# minitemsize: the minimum guaranteed itemsize
221225

222226
def setUp(self):
223-
self.enterContext(warnings.catch_warnings())
227+
if (not support.Py_GIL_DISABLED or
228+
any('"parallel_threads": null' in a for a in sys.argv) or
229+
all('parallel_threads' not in a for a in sys.argv)):
230+
self.enterContext(warnings.catch_warnings())
224231
warnings.filterwarnings(
225232
"ignore",
226233
message="The 'u' type code is deprecated and "
@@ -472,54 +479,59 @@ def test_insert(self):
472479
def test_tofromfile(self):
473480
a = array.array(self.typecode, 2*self.example)
474481
self.assertRaises(TypeError, a.tofile)
475-
os_helper.unlink(os_helper.TESTFN)
476-
f = open(os_helper.TESTFN, 'wb')
477-
try:
478-
a.tofile(f)
479-
f.close()
480-
b = array.array(self.typecode)
481-
f = open(os_helper.TESTFN, 'rb')
482-
self.assertRaises(TypeError, b.fromfile)
483-
b.fromfile(f, len(self.example))
484-
self.assertEqual(b, array.array(self.typecode, self.example))
485-
self.assertNotEqual(a, b)
486-
self.assertRaises(EOFError, b.fromfile, f, len(self.example)+1)
487-
self.assertEqual(a, b)
488-
f.close()
489-
finally:
490-
if not f.closed:
482+
with os_helper.temp_dir() as temp_dir:
483+
temp_path = os.path.join(temp_dir, os_helper.TESTFN)
484+
f = open(temp_path, 'wb')
485+
try:
486+
a.tofile(f)
491487
f.close()
492-
os_helper.unlink(os_helper.TESTFN)
488+
b = array.array(self.typecode)
489+
f = open(temp_path, 'rb')
490+
self.assertRaises(TypeError, b.fromfile)
491+
b.fromfile(f, len(self.example))
492+
self.assertEqual(b, array.array(self.typecode, self.example))
493+
self.assertNotEqual(a, b)
494+
self.assertRaises(EOFError, b.fromfile, f, len(self.example)+1)
495+
self.assertEqual(a, b)
496+
f.close()
497+
finally:
498+
if not f.closed:
499+
f.close()
500+
os_helper.unlink(temp_path)
493501

494502
def test_fromfile_ioerror(self):
495503
# Issue #5395: Check if fromfile raises a proper OSError
496504
# instead of EOFError.
497505
a = array.array(self.typecode)
498-
f = open(os_helper.TESTFN, 'wb')
499-
try:
500-
self.assertRaises(OSError, a.fromfile, f, len(self.example))
501-
finally:
502-
f.close()
503-
os_helper.unlink(os_helper.TESTFN)
506+
with os_helper.temp_dir() as temp_dir:
507+
temp_path = os.path.join(temp_dir, os_helper.TESTFN)
508+
f = open(temp_path, 'wb')
509+
try:
510+
self.assertRaises(OSError, a.fromfile, f, len(self.example))
511+
finally:
512+
f.close()
513+
os_helper.unlink(temp_path)
504514

505515
def test_filewrite(self):
506516
a = array.array(self.typecode, 2*self.example)
507-
f = open(os_helper.TESTFN, 'wb')
508-
try:
509-
f.write(a)
510-
f.close()
511-
b = array.array(self.typecode)
512-
f = open(os_helper.TESTFN, 'rb')
513-
b.fromfile(f, len(self.example))
514-
self.assertEqual(b, array.array(self.typecode, self.example))
515-
self.assertNotEqual(a, b)
516-
b.fromfile(f, len(self.example))
517-
self.assertEqual(a, b)
518-
f.close()
519-
finally:
520-
if not f.closed:
517+
with os_helper.temp_dir() as temp_dir:
518+
temp_path = os.path.join(temp_dir, os_helper.TESTFN)
519+
f = open(temp_path, 'wb')
520+
try:
521+
f.write(a)
522+
f.close()
523+
b = array.array(self.typecode)
524+
f = open(temp_path, 'rb')
525+
b.fromfile(f, len(self.example))
526+
self.assertEqual(b, array.array(self.typecode, self.example))
527+
self.assertNotEqual(a, b)
528+
b.fromfile(f, len(self.example))
529+
self.assertEqual(a, b)
521530
f.close()
522-
os_helper.unlink(os_helper.TESTFN)
531+
finally:
532+
if not f.closed:
533+
f.close()
534+
os_helper.unlink(temp_path)
523535

524536
def test_tofromlist(self):
525537
a = array.array(self.typecode, 2*self.example)
@@ -1201,6 +1213,7 @@ def test_obsolete_write_lock(self):
12011213
a = array.array('B', b"")
12021214
self.assertRaises(BufferError, _testcapi.getbuffer_with_null_view, a)
12031215

1216+
@unittest.skipIf(support.Py_GIL_DISABLED, 'not freed if GIL disabled')
12041217
def test_free_after_iterating(self):
12051218
support.check_free_after_iterating(self, iter, array.array,
12061219
(self.typecode,))
@@ -1255,6 +1268,7 @@ def test_issue17223(self):
12551268
self.assertRaises(ValueError, a.tounicode)
12561269
self.assertRaises(ValueError, str, a)
12571270

1271+
@unittest.skipIf(support.Py_GIL_DISABLED, 'warning stuff is not free-thread safe yet')
12581272
def test_typecode_u_deprecation(self):
12591273
with self.assertWarns(DeprecationWarning):
12601274
array.array("u")

Modules/arraymodule.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
254254
#else
255255
arraydata_free(self->data, false);
256256
#endif
257-
self->data = NULL;
258257
Py_SET_SIZE(self, 0);
258+
FT_ATOMIC_STORE_PTR_RELAXED(self->data, NULL);
259259
return 0;
260260
}
261261

@@ -2629,10 +2629,11 @@ array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls,
26292629
array_state *state = get_array_state_by_class(cls);
26302630
assert(state != NULL);
26312631

2632-
if (state->array_reconstructor == NULL) {
2633-
state->array_reconstructor = PyImport_ImportModuleAttrString(
2634-
"array", "_array_reconstructor");
2635-
if (state->array_reconstructor == NULL) {
2632+
if (FT_ATOMIC_LOAD_PTR_RELAXED(state->array_reconstructor) == NULL) {
2633+
PyObject *array_reconstructor = PyImport_ImportModuleAttrString(
2634+
"array", "_array_reconstructor");
2635+
FT_ATOMIC_STORE_PTR_RELAXED(state->array_reconstructor, array_reconstructor);
2636+
if (array_reconstructor == NULL) {
26362637
return NULL;
26372638
}
26382639
}

0 commit comments

Comments
 (0)