Skip to content

Commit f64a812

Browse files
committed
Enhance tests: test NULL and release the GIL
1 parent 423d25a commit f64a812

File tree

2 files changed

+50
-18
lines changed

2 files changed

+50
-18
lines changed

Lib/test/test_capi/test_object.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
_testcapi = import_helper.import_module('_testcapi')
1515
_testinternalcapi = import_helper.import_module('_testinternalcapi')
1616

17+
NULL = None
1718
STDERR_FD = 2
1819

1920

@@ -250,39 +251,54 @@ def func(x):
250251

251252
func(object())
252253

253-
def test_pyobject_dump(self):
254+
def pyobject_dump(self, obj, release_gil=False):
254255
pyobject_dump = _testcapi.pyobject_dump
255-
obj = 'test string'
256-
257-
filename = os_helper.TESTFN
258-
self.addCleanup(os_helper.unlink, filename)
259256

260257
try:
261258
old_stderr = os.dup(STDERR_FD)
262259
except OSError as exc:
263260
# os.dup(STDERR_FD) is not supported on WASI
264261
self.skipTest(f"os.dup() failed with {exc!r}")
265262

263+
filename = os_helper.TESTFN
266264
try:
267-
with open(filename, "wb") as fp:
268-
fd = fp.fileno()
269-
os.dup2(fd, STDERR_FD)
270-
pyobject_dump(obj)
265+
try:
266+
with open(filename, "wb") as fp:
267+
fd = fp.fileno()
268+
os.dup2(fd, STDERR_FD)
269+
pyobject_dump(obj, release_gil)
270+
finally:
271+
os.dup2(old_stderr, STDERR_FD)
272+
os.close(old_stderr)
273+
274+
with open(filename) as fp:
275+
return fp.read().rstrip()
271276
finally:
272-
os.dup2(old_stderr, STDERR_FD)
273-
os.close(old_stderr)
274-
275-
with open(filename) as fp:
276-
output = fp.read()
277+
os_helper.unlink(filename)
277278

279+
def test_pyobject_dump(self):
280+
# test string object
281+
str_obj = 'test string'
282+
output = self.pyobject_dump(str_obj)
278283
hex_regex = r'(0x)?[0-9a-fA-F]+'
279-
self.assertRegex(output.rstrip(),
284+
regex = (
280285
fr"object address : {hex_regex}\n"
281286
r"object refcount : [0-9]+\n"
282287
fr"object type : {hex_regex}\n"
283288
r"object type name: str\n"
284289
r"object repr : 'test string'"
285290
)
291+
self.assertRegex(output, regex)
292+
293+
# release the GIL
294+
output = self.pyobject_dump(str_obj, release_gil=True)
295+
self.assertRegex(output, regex)
296+
297+
# test NULL object
298+
output = self.pyobject_dump(NULL)
299+
hex_regex = r'(0x)?[0-9a-fA-F]+'
300+
self.assertEqual(output,
301+
'<object at (nil) is freed>')
286302

287303

288304
if __name__ == "__main__":

Modules/_testcapi/object.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,25 @@ is_uniquely_referenced(PyObject *self, PyObject *op)
486486

487487

488488
static PyObject *
489-
pyobject_dump(PyObject *self, PyObject *op)
489+
pyobject_dump(PyObject *self, PyObject *args)
490490
{
491-
PyObject_Dump(op);
491+
PyObject *op;
492+
int release_gil = 0;
493+
494+
if (!PyArg_ParseTuple(args, "O|i", &op, &release_gil)) {
495+
return NULL;
496+
}
497+
NULLABLE(op);
498+
499+
if (release_gil) {
500+
Py_BEGIN_ALLOW_THREADS
501+
PyObject_Dump(op);
502+
Py_END_ALLOW_THREADS
503+
504+
}
505+
else {
506+
PyObject_Dump(op);
507+
}
492508
Py_RETURN_NONE;
493509
}
494510

@@ -519,7 +535,7 @@ static PyMethodDef test_methods[] = {
519535
{"test_py_is_funcs", test_py_is_funcs, METH_NOARGS},
520536
{"clear_managed_dict", clear_managed_dict, METH_O, NULL},
521537
{"is_uniquely_referenced", is_uniquely_referenced, METH_O},
522-
{"pyobject_dump", pyobject_dump, METH_O},
538+
{"pyobject_dump", pyobject_dump, METH_VARARGS},
523539
{NULL},
524540
};
525541

0 commit comments

Comments
 (0)