mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-93649: Split exception tests from _testcapimodule.c (GH-102173)
Automerge-Triggered-By: GH:erlend-aasland
This commit is contained in:
parent
e07b304bb0
commit
efc985a714
8 changed files with 434 additions and 416 deletions
145
Lib/test/test_capi/test_exceptions.py
Normal file
145
Lib/test/test_capi/test_exceptions.py
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from test import support
|
||||||
|
from test.support import import_helper
|
||||||
|
from test.support.script_helper import assert_python_failure
|
||||||
|
|
||||||
|
from .test_misc import decode_stderr
|
||||||
|
|
||||||
|
# Skip this test if the _testcapi module isn't available.
|
||||||
|
_testcapi = import_helper.import_module('_testcapi')
|
||||||
|
|
||||||
|
class Test_Exceptions(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_exception(self):
|
||||||
|
raised_exception = ValueError("5")
|
||||||
|
new_exc = TypeError("TEST")
|
||||||
|
try:
|
||||||
|
raise raised_exception
|
||||||
|
except ValueError as e:
|
||||||
|
orig_sys_exception = sys.exception()
|
||||||
|
orig_exception = _testcapi.set_exception(new_exc)
|
||||||
|
new_sys_exception = sys.exception()
|
||||||
|
new_exception = _testcapi.set_exception(orig_exception)
|
||||||
|
reset_sys_exception = sys.exception()
|
||||||
|
|
||||||
|
self.assertEqual(orig_exception, e)
|
||||||
|
|
||||||
|
self.assertEqual(orig_exception, raised_exception)
|
||||||
|
self.assertEqual(orig_sys_exception, orig_exception)
|
||||||
|
self.assertEqual(reset_sys_exception, orig_exception)
|
||||||
|
self.assertEqual(new_exception, new_exc)
|
||||||
|
self.assertEqual(new_sys_exception, new_exception)
|
||||||
|
else:
|
||||||
|
self.fail("Exception not raised")
|
||||||
|
|
||||||
|
def test_exc_info(self):
|
||||||
|
raised_exception = ValueError("5")
|
||||||
|
new_exc = TypeError("TEST")
|
||||||
|
try:
|
||||||
|
raise raised_exception
|
||||||
|
except ValueError as e:
|
||||||
|
tb = e.__traceback__
|
||||||
|
orig_sys_exc_info = sys.exc_info()
|
||||||
|
orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
|
||||||
|
new_sys_exc_info = sys.exc_info()
|
||||||
|
new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
|
||||||
|
reset_sys_exc_info = sys.exc_info()
|
||||||
|
|
||||||
|
self.assertEqual(orig_exc_info[1], e)
|
||||||
|
|
||||||
|
self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
|
||||||
|
self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
|
||||||
|
self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
|
||||||
|
self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
|
||||||
|
self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
|
||||||
|
else:
|
||||||
|
self.assertTrue(False)
|
||||||
|
|
||||||
|
|
||||||
|
class Test_FatalError(unittest.TestCase):
|
||||||
|
|
||||||
|
def check_fatal_error(self, code, expected, not_expected=()):
|
||||||
|
with support.SuppressCrashReport():
|
||||||
|
rc, out, err = assert_python_failure('-sSI', '-c', code)
|
||||||
|
|
||||||
|
err = decode_stderr(err)
|
||||||
|
self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n',
|
||||||
|
err)
|
||||||
|
|
||||||
|
match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$',
|
||||||
|
err, re.MULTILINE)
|
||||||
|
if not match:
|
||||||
|
self.fail(f"Cannot find 'Extension modules:' in {err!r}")
|
||||||
|
modules = set(match.group(1).strip().split(', '))
|
||||||
|
total = int(match.group(2))
|
||||||
|
|
||||||
|
for name in expected:
|
||||||
|
self.assertIn(name, modules)
|
||||||
|
for name in not_expected:
|
||||||
|
self.assertNotIn(name, modules)
|
||||||
|
self.assertEqual(len(modules), total)
|
||||||
|
|
||||||
|
@support.requires_subprocess()
|
||||||
|
def test_fatal_error(self):
|
||||||
|
# By default, stdlib extension modules are ignored,
|
||||||
|
# but not test modules.
|
||||||
|
expected = ('_testcapi',)
|
||||||
|
not_expected = ('sys',)
|
||||||
|
code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")'
|
||||||
|
self.check_fatal_error(code, expected, not_expected)
|
||||||
|
|
||||||
|
# Mark _testcapi as stdlib module, but not sys
|
||||||
|
expected = ('sys',)
|
||||||
|
not_expected = ('_testcapi',)
|
||||||
|
code = """if True:
|
||||||
|
import _testcapi, sys
|
||||||
|
sys.stdlib_module_names = frozenset({"_testcapi"})
|
||||||
|
_testcapi.fatal_error(b"MESSAGE")
|
||||||
|
"""
|
||||||
|
self.check_fatal_error(code, expected)
|
||||||
|
|
||||||
|
|
||||||
|
class Test_ErrSetAndRestore(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_err_set_raised(self):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_testcapi.err_set_raised(ValueError())
|
||||||
|
v = ValueError()
|
||||||
|
try:
|
||||||
|
_testcapi.err_set_raised(v)
|
||||||
|
except ValueError as ex:
|
||||||
|
self.assertIs(v, ex)
|
||||||
|
|
||||||
|
def test_err_restore(self):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_testcapi.err_restore(ValueError)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_testcapi.err_restore(ValueError, 1)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_testcapi.err_restore(ValueError, 1, None)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_testcapi.err_restore(ValueError, ValueError())
|
||||||
|
try:
|
||||||
|
_testcapi.err_restore(KeyError, "hi")
|
||||||
|
except KeyError as k:
|
||||||
|
self.assertEqual("hi", k.args[0])
|
||||||
|
try:
|
||||||
|
1/0
|
||||||
|
except Exception as e:
|
||||||
|
tb = e.__traceback__
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
_testcapi.err_restore(ValueError, 1, tb)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
_testcapi.err_restore(ValueError, 1, 0)
|
||||||
|
try:
|
||||||
|
_testcapi.err_restore(ValueError, 1, tb)
|
||||||
|
except ValueError as v:
|
||||||
|
self.assertEqual(1, v.args[0])
|
||||||
|
self.assertIs(tb, v.__traceback__.tb_next)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
|
@ -8,7 +8,6 @@ import importlib.util
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import random
|
import random
|
||||||
import re
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
@ -91,51 +90,6 @@ class CAPITest(unittest.TestCase):
|
||||||
def test_memoryview_from_NULL_pointer(self):
|
def test_memoryview_from_NULL_pointer(self):
|
||||||
self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
|
self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer)
|
||||||
|
|
||||||
def test_exception(self):
|
|
||||||
raised_exception = ValueError("5")
|
|
||||||
new_exc = TypeError("TEST")
|
|
||||||
try:
|
|
||||||
raise raised_exception
|
|
||||||
except ValueError as e:
|
|
||||||
orig_sys_exception = sys.exception()
|
|
||||||
orig_exception = _testcapi.set_exception(new_exc)
|
|
||||||
new_sys_exception = sys.exception()
|
|
||||||
new_exception = _testcapi.set_exception(orig_exception)
|
|
||||||
reset_sys_exception = sys.exception()
|
|
||||||
|
|
||||||
self.assertEqual(orig_exception, e)
|
|
||||||
|
|
||||||
self.assertEqual(orig_exception, raised_exception)
|
|
||||||
self.assertEqual(orig_sys_exception, orig_exception)
|
|
||||||
self.assertEqual(reset_sys_exception, orig_exception)
|
|
||||||
self.assertEqual(new_exception, new_exc)
|
|
||||||
self.assertEqual(new_sys_exception, new_exception)
|
|
||||||
else:
|
|
||||||
self.fail("Exception not raised")
|
|
||||||
|
|
||||||
def test_exc_info(self):
|
|
||||||
raised_exception = ValueError("5")
|
|
||||||
new_exc = TypeError("TEST")
|
|
||||||
try:
|
|
||||||
raise raised_exception
|
|
||||||
except ValueError as e:
|
|
||||||
tb = e.__traceback__
|
|
||||||
orig_sys_exc_info = sys.exc_info()
|
|
||||||
orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
|
|
||||||
new_sys_exc_info = sys.exc_info()
|
|
||||||
new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
|
|
||||||
reset_sys_exc_info = sys.exc_info()
|
|
||||||
|
|
||||||
self.assertEqual(orig_exc_info[1], e)
|
|
||||||
|
|
||||||
self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
|
|
||||||
self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
|
|
||||||
self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
|
|
||||||
self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
|
|
||||||
self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
|
|
||||||
else:
|
|
||||||
self.assertTrue(False)
|
|
||||||
|
|
||||||
@unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
|
@unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.')
|
||||||
def test_seq_bytes_to_charp_array(self):
|
def test_seq_bytes_to_charp_array(self):
|
||||||
# Issue #15732: crash in _PySequence_BytesToCharpArray()
|
# Issue #15732: crash in _PySequence_BytesToCharpArray()
|
||||||
|
@ -837,46 +791,6 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, pynumber_tobase, '123', 10)
|
self.assertRaises(TypeError, pynumber_tobase, '123', 10)
|
||||||
self.assertRaises(SystemError, pynumber_tobase, 123, 0)
|
self.assertRaises(SystemError, pynumber_tobase, 123, 0)
|
||||||
|
|
||||||
def check_fatal_error(self, code, expected, not_expected=()):
|
|
||||||
with support.SuppressCrashReport():
|
|
||||||
rc, out, err = assert_python_failure('-sSI', '-c', code)
|
|
||||||
|
|
||||||
err = decode_stderr(err)
|
|
||||||
self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n',
|
|
||||||
err)
|
|
||||||
|
|
||||||
match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$',
|
|
||||||
err, re.MULTILINE)
|
|
||||||
if not match:
|
|
||||||
self.fail(f"Cannot find 'Extension modules:' in {err!r}")
|
|
||||||
modules = set(match.group(1).strip().split(', '))
|
|
||||||
total = int(match.group(2))
|
|
||||||
|
|
||||||
for name in expected:
|
|
||||||
self.assertIn(name, modules)
|
|
||||||
for name in not_expected:
|
|
||||||
self.assertNotIn(name, modules)
|
|
||||||
self.assertEqual(len(modules), total)
|
|
||||||
|
|
||||||
@support.requires_subprocess()
|
|
||||||
def test_fatal_error(self):
|
|
||||||
# By default, stdlib extension modules are ignored,
|
|
||||||
# but not test modules.
|
|
||||||
expected = ('_testcapi',)
|
|
||||||
not_expected = ('sys',)
|
|
||||||
code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")'
|
|
||||||
self.check_fatal_error(code, expected, not_expected)
|
|
||||||
|
|
||||||
# Mark _testcapi as stdlib module, but not sys
|
|
||||||
expected = ('sys',)
|
|
||||||
not_expected = ('_testcapi',)
|
|
||||||
code = textwrap.dedent('''
|
|
||||||
import _testcapi, sys
|
|
||||||
sys.stdlib_module_names = frozenset({"_testcapi"})
|
|
||||||
_testcapi.fatal_error(b"MESSAGE")
|
|
||||||
''')
|
|
||||||
self.check_fatal_error(code, expected)
|
|
||||||
|
|
||||||
def test_pyobject_repr_from_null(self):
|
def test_pyobject_repr_from_null(self):
|
||||||
s = _testcapi.pyobject_repr_from_null()
|
s = _testcapi.pyobject_repr_from_null()
|
||||||
self.assertEqual(s, '<NULL>')
|
self.assertEqual(s, '<NULL>')
|
||||||
|
@ -1214,9 +1128,9 @@ class TestPendingCalls(unittest.TestCase):
|
||||||
self.pendingcalls_wait(l, n)
|
self.pendingcalls_wait(l, n)
|
||||||
|
|
||||||
def test_gen_get_code(self):
|
def test_gen_get_code(self):
|
||||||
def genf(): yield
|
def genf(): yield
|
||||||
gen = genf()
|
gen = genf()
|
||||||
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
|
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
|
||||||
|
|
||||||
|
|
||||||
class SubinterpreterTest(unittest.TestCase):
|
class SubinterpreterTest(unittest.TestCase):
|
||||||
|
@ -1641,44 +1555,5 @@ class Test_Pep523API(unittest.TestCase):
|
||||||
self.do_test(func2)
|
self.do_test(func2)
|
||||||
|
|
||||||
|
|
||||||
class Test_ErrSetAndRestore(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_err_set_raised(self):
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
_testcapi.err_set_raised(ValueError())
|
|
||||||
v = ValueError()
|
|
||||||
try:
|
|
||||||
_testcapi.err_set_raised(v)
|
|
||||||
except ValueError as ex:
|
|
||||||
self.assertIs(v, ex)
|
|
||||||
|
|
||||||
def test_err_restore(self):
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
_testcapi.err_restore(ValueError)
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
_testcapi.err_restore(ValueError, 1)
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
_testcapi.err_restore(ValueError, 1, None)
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
_testcapi.err_restore(ValueError, ValueError())
|
|
||||||
try:
|
|
||||||
_testcapi.err_restore(KeyError, "hi")
|
|
||||||
except KeyError as k:
|
|
||||||
self.assertEqual("hi", k.args[0])
|
|
||||||
try:
|
|
||||||
1/0
|
|
||||||
except Exception as e:
|
|
||||||
tb = e.__traceback__
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
_testcapi.err_restore(ValueError, 1, tb)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
_testcapi.err_restore(ValueError, 1, 0)
|
|
||||||
try:
|
|
||||||
_testcapi.err_restore(ValueError, 1, tb)
|
|
||||||
except ValueError as v:
|
|
||||||
self.assertEqual(1, v.args[0])
|
|
||||||
self.assertIs(tb, v.__traceback__.tb_next)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -169,7 +169,7 @@
|
||||||
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
|
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
|
||||||
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
|
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
|
||||||
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
|
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
|
||||||
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c
|
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c
|
||||||
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
|
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
|
||||||
|
|
||||||
# Some testing modules MUST be built as shared libraries.
|
# Some testing modules MUST be built as shared libraries.
|
||||||
|
|
277
Modules/_testcapi/exceptions.c
Normal file
277
Modules/_testcapi/exceptions.c
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
#include "parts.h"
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
err_set_raised(PyObject *self, PyObject *exc)
|
||||||
|
{
|
||||||
|
Py_INCREF(exc);
|
||||||
|
PyErr_SetRaisedException(exc);
|
||||||
|
assert(PyErr_Occurred());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
err_restore(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *type = NULL, *value = NULL, *traceback = NULL;
|
||||||
|
switch(PyTuple_Size(args)) {
|
||||||
|
case 3:
|
||||||
|
traceback = PyTuple_GetItem(args, 2);
|
||||||
|
Py_INCREF(traceback);
|
||||||
|
/* fall through */
|
||||||
|
case 2:
|
||||||
|
value = PyTuple_GetItem(args, 1);
|
||||||
|
Py_INCREF(value);
|
||||||
|
/* fall through */
|
||||||
|
case 1:
|
||||||
|
type = PyTuple_GetItem(args, 0);
|
||||||
|
Py_INCREF(type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"wrong number of arguments");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyErr_Restore(type, value, traceback);
|
||||||
|
assert(PyErr_Occurred());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To test the format of exceptions as printed out. */
|
||||||
|
static PyObject *
|
||||||
|
exception_print(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *value;
|
||||||
|
PyObject *tb = NULL;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O:exception_print", &value)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyExceptionInstance_Check(value)) {
|
||||||
|
tb = PyException_GetTraceback(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_Display((PyObject *) Py_TYPE(value), value, tb);
|
||||||
|
Py_XDECREF(tb);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
|
||||||
|
Run via Lib/test/test_exceptions.py */
|
||||||
|
static PyObject *
|
||||||
|
make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *doc = NULL;
|
||||||
|
PyObject *base = NULL;
|
||||||
|
PyObject *dict = NULL;
|
||||||
|
|
||||||
|
static char *kwlist[] = {"name", "doc", "base", "dict", NULL};
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||||
|
"s|sOO:make_exception_with_doc", kwlist,
|
||||||
|
&name, &doc, &base, &dict))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyErr_NewExceptionWithDoc(name, doc, base, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
raise_exception(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *exc;
|
||||||
|
int num_args;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "Oi:raise_exception", &exc, &num_args)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *exc_args = PyTuple_New(num_args);
|
||||||
|
if (exc_args == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num_args; ++i) {
|
||||||
|
PyObject *v = PyLong_FromLong(i);
|
||||||
|
if (v == NULL) {
|
||||||
|
Py_DECREF(exc_args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyTuple_SET_ITEM(exc_args, i, v);
|
||||||
|
}
|
||||||
|
PyErr_SetObject(exc, exc_args);
|
||||||
|
Py_DECREF(exc_args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reliably raise a MemoryError */
|
||||||
|
static PyObject *
|
||||||
|
raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
test_fatal_error(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
char *message;
|
||||||
|
int release_gil = 0;
|
||||||
|
if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (release_gil) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
Py_FatalError(message);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Py_FatalError(message);
|
||||||
|
}
|
||||||
|
// Py_FatalError() does not return, but exits the process.
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
test_set_exc_info(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *new_type, *new_value, *new_tb;
|
||||||
|
PyObject *type, *value, *tb;
|
||||||
|
if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
|
||||||
|
&new_type, &new_value, &new_tb))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_GetExcInfo(&type, &value, &tb);
|
||||||
|
|
||||||
|
Py_INCREF(new_type);
|
||||||
|
Py_INCREF(new_value);
|
||||||
|
Py_INCREF(new_tb);
|
||||||
|
PyErr_SetExcInfo(new_type, new_value, new_tb);
|
||||||
|
|
||||||
|
PyObject *orig_exc = PyTuple_Pack(3,
|
||||||
|
type ? type : Py_None,
|
||||||
|
value ? value : Py_None,
|
||||||
|
tb ? tb : Py_None);
|
||||||
|
Py_XDECREF(type);
|
||||||
|
Py_XDECREF(value);
|
||||||
|
Py_XDECREF(tb);
|
||||||
|
return orig_exc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
test_set_exception(PyObject *self, PyObject *new_exc)
|
||||||
|
{
|
||||||
|
PyObject *exc = PyErr_GetHandledException();
|
||||||
|
assert(PyExceptionInstance_Check(exc) || exc == NULL);
|
||||||
|
|
||||||
|
PyErr_SetHandledException(new_exc);
|
||||||
|
return exc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
test_write_unraisable_exc(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *exc, *err_msg, *obj;
|
||||||
|
if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *err_msg_utf8;
|
||||||
|
if (err_msg != Py_None) {
|
||||||
|
err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
|
||||||
|
if (err_msg_utf8 == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err_msg_utf8 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
|
||||||
|
_PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To test the format of tracebacks as printed out. */
|
||||||
|
static PyObject *
|
||||||
|
traceback_print(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *file;
|
||||||
|
PyObject *traceback;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "OO:traceback_print",
|
||||||
|
&traceback, &file))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyTraceBack_Print(traceback, file) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the PyRecurdingInfinitelyError_Type
|
||||||
|
*/
|
||||||
|
|
||||||
|
static PyTypeObject PyRecursingInfinitelyError_Type;
|
||||||
|
|
||||||
|
static int
|
||||||
|
recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
|
||||||
|
|
||||||
|
/* Instantiating this exception starts infinite recursion. */
|
||||||
|
Py_INCREF(type);
|
||||||
|
PyErr_SetObject(type, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyTypeObject PyRecursingInfinitelyError_Type = {
|
||||||
|
.tp_name = "RecursingInfinitelyError",
|
||||||
|
.tp_basicsize = sizeof(PyBaseExceptionObject),
|
||||||
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||||
|
.tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
|
||||||
|
.tp_init = (initproc)recurse_infinitely_error_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyMethodDef test_methods[] = {
|
||||||
|
{"err_restore", err_restore, METH_VARARGS},
|
||||||
|
{"err_set_raised", err_set_raised, METH_O},
|
||||||
|
{"exception_print", exception_print, METH_VARARGS},
|
||||||
|
{"fatal_error", test_fatal_error, METH_VARARGS,
|
||||||
|
PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
|
||||||
|
{"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
|
||||||
|
METH_VARARGS | METH_KEYWORDS},
|
||||||
|
{"raise_exception", raise_exception, METH_VARARGS},
|
||||||
|
{"raise_memoryerror", raise_memoryerror, METH_NOARGS},
|
||||||
|
{"set_exc_info", test_set_exc_info, METH_VARARGS},
|
||||||
|
{"set_exception", test_set_exception, METH_O},
|
||||||
|
{"traceback_print", traceback_print, METH_VARARGS},
|
||||||
|
{"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyTestCapi_Init_Exceptions(PyObject *mod)
|
||||||
|
{
|
||||||
|
PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
|
||||||
|
if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
|
||||||
|
(PyObject *)&PyRecursingInfinitelyError_Type) < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyModule_AddFunctions(mod, test_methods) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ int _PyTestCapi_Init_Watchers(PyObject *module);
|
||||||
int _PyTestCapi_Init_Long(PyObject *module);
|
int _PyTestCapi_Init_Long(PyObject *module);
|
||||||
int _PyTestCapi_Init_Float(PyObject *module);
|
int _PyTestCapi_Init_Float(PyObject *module);
|
||||||
int _PyTestCapi_Init_Structmember(PyObject *module);
|
int _PyTestCapi_Init_Structmember(PyObject *module);
|
||||||
|
int _PyTestCapi_Init_Exceptions(PyObject *module);
|
||||||
|
|
||||||
#ifdef LIMITED_API_AVAILABLE
|
#ifdef LIMITED_API_AVAILABLE
|
||||||
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
|
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
|
||||||
|
|
|
@ -720,33 +720,6 @@ pyobject_bytes_from_null(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
return PyObject_Bytes(NULL);
|
return PyObject_Bytes(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
raise_exception(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *exc;
|
|
||||||
PyObject *exc_args, *v;
|
|
||||||
int num_args, i;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "Oi:raise_exception",
|
|
||||||
&exc, &num_args))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
exc_args = PyTuple_New(num_args);
|
|
||||||
if (exc_args == NULL)
|
|
||||||
return NULL;
|
|
||||||
for (i = 0; i < num_args; ++i) {
|
|
||||||
v = PyLong_FromLong(i);
|
|
||||||
if (v == NULL) {
|
|
||||||
Py_DECREF(exc_args);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
PyTuple_SET_ITEM(exc_args, i, v);
|
|
||||||
}
|
|
||||||
PyErr_SetObject(exc, exc_args);
|
|
||||||
Py_DECREF(exc_args);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_errno(PyObject *self, PyObject *args)
|
set_errno(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -759,40 +732,6 @@ set_errno(PyObject *self, PyObject *args)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
test_set_exception(PyObject *self, PyObject *new_exc)
|
|
||||||
{
|
|
||||||
PyObject *exc = PyErr_GetHandledException();
|
|
||||||
assert(PyExceptionInstance_Check(exc) || exc == NULL);
|
|
||||||
|
|
||||||
PyErr_SetHandledException(new_exc);
|
|
||||||
return exc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
test_set_exc_info(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *orig_exc;
|
|
||||||
PyObject *new_type, *new_value, *new_tb;
|
|
||||||
PyObject *type, *value, *tb;
|
|
||||||
if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
|
|
||||||
&new_type, &new_value, &new_tb))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
PyErr_GetExcInfo(&type, &value, &tb);
|
|
||||||
|
|
||||||
Py_INCREF(new_type);
|
|
||||||
Py_INCREF(new_value);
|
|
||||||
Py_INCREF(new_tb);
|
|
||||||
PyErr_SetExcInfo(new_type, new_value, new_tb);
|
|
||||||
|
|
||||||
orig_exc = PyTuple_Pack(3, type ? type : Py_None, value ? value : Py_None, tb ? tb : Py_None);
|
|
||||||
Py_XDECREF(type);
|
|
||||||
Py_XDECREF(value);
|
|
||||||
Py_XDECREF(tb);
|
|
||||||
return orig_exc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test_thread_state spawns a thread of its own, and that thread releases
|
/* test_thread_state spawns a thread of its own, and that thread releases
|
||||||
* `thread_done` when it's finished. The driver code has to know when the
|
* `thread_done` when it's finished. The driver code has to know when the
|
||||||
* thread finishes, because the thread uses a PyObject (the callable) that
|
* thread finishes, because the thread uses a PyObject (the callable) that
|
||||||
|
@ -1272,57 +1211,6 @@ profile_int(PyObject *self, PyObject* args)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* To test the format of tracebacks as printed out. */
|
|
||||||
static PyObject *
|
|
||||||
traceback_print(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *file;
|
|
||||||
PyObject *traceback;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OO:traceback_print",
|
|
||||||
&traceback, &file))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
result = PyTraceBack_Print(traceback, file);
|
|
||||||
if (result < 0)
|
|
||||||
return NULL;
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To test the format of exceptions as printed out. */
|
|
||||||
static PyObject *
|
|
||||||
exception_print(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *value;
|
|
||||||
PyObject *tb = NULL;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O:exception_print",
|
|
||||||
&value)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyExceptionInstance_Check(value)) {
|
|
||||||
tb = PyException_GetTraceback(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyErr_Display((PyObject *) Py_TYPE(value), value, tb);
|
|
||||||
Py_XDECREF(tb);
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* reliably raise a MemoryError */
|
|
||||||
static PyObject *
|
|
||||||
raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
|
|
||||||
{
|
|
||||||
PyErr_NoMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Issue 6012 */
|
/* Issue 6012 */
|
||||||
static PyObject *str1, *str2;
|
static PyObject *str1, *str2;
|
||||||
static int
|
static int
|
||||||
|
@ -1368,26 +1256,6 @@ code_newempty(PyObject *self, PyObject *args)
|
||||||
return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno);
|
return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
|
|
||||||
Run via Lib/test/test_exceptions.py */
|
|
||||||
static PyObject *
|
|
||||||
make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
const char *doc = NULL;
|
|
||||||
PyObject *base = NULL;
|
|
||||||
PyObject *dict = NULL;
|
|
||||||
|
|
||||||
static char *kwlist[] = {"name", "doc", "base", "dict", NULL};
|
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
|
||||||
"s|sOO:make_exception_with_doc", kwlist,
|
|
||||||
&name, &doc, &base, &dict))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyErr_NewExceptionWithDoc(name, doc, base, dict);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored))
|
make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
@ -2491,31 +2359,6 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
|
||||||
test_write_unraisable_exc(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *exc, *err_msg, *obj;
|
|
||||||
if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *err_msg_utf8;
|
|
||||||
if (err_msg != Py_None) {
|
|
||||||
err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
|
|
||||||
if (err_msg_utf8 == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
err_msg_utf8 = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
|
|
||||||
_PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
sequence_getitem(PyObject *self, PyObject *args)
|
sequence_getitem(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -2874,25 +2717,6 @@ test_py_is_funcs(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
test_fatal_error(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
char *message;
|
|
||||||
int release_gil = 0;
|
|
||||||
if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
|
|
||||||
return NULL;
|
|
||||||
if (release_gil) {
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
Py_FatalError(message);
|
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Py_FatalError(message);
|
|
||||||
}
|
|
||||||
// Py_FatalError() does not return, but exits the process.
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// type->tp_version_tag
|
// type->tp_version_tag
|
||||||
static PyObject *
|
static PyObject *
|
||||||
type_get_version(PyObject *self, PyObject *type)
|
type_get_version(PyObject *self, PyObject *type)
|
||||||
|
@ -3492,46 +3316,9 @@ function_set_kw_defaults(PyObject *self, PyObject *args)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
err_set_raised(PyObject *self, PyObject *exc)
|
|
||||||
{
|
|
||||||
Py_INCREF(exc);
|
|
||||||
PyErr_SetRaisedException(exc);
|
|
||||||
assert(PyErr_Occurred());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
err_restore(PyObject *self, PyObject *args) {
|
|
||||||
PyObject *type = NULL, *value = NULL, *traceback = NULL;
|
|
||||||
switch(PyTuple_Size(args)) {
|
|
||||||
case 3:
|
|
||||||
traceback = PyTuple_GetItem(args, 2);
|
|
||||||
Py_INCREF(traceback);
|
|
||||||
/* fall through */
|
|
||||||
case 2:
|
|
||||||
value = PyTuple_GetItem(args, 1);
|
|
||||||
Py_INCREF(value);
|
|
||||||
/* fall through */
|
|
||||||
case 1:
|
|
||||||
type = PyTuple_GetItem(args, 0);
|
|
||||||
Py_INCREF(type);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PyErr_SetString(PyExc_TypeError,
|
|
||||||
"wrong number of arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
PyErr_Restore(type, value, traceback);
|
|
||||||
assert(PyErr_Occurred());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
|
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
|
||||||
|
|
||||||
static PyMethodDef TestMethods[] = {
|
static PyMethodDef TestMethods[] = {
|
||||||
{"raise_exception", raise_exception, METH_VARARGS},
|
|
||||||
{"raise_memoryerror", raise_memoryerror, METH_NOARGS},
|
|
||||||
{"set_errno", set_errno, METH_VARARGS},
|
{"set_errno", set_errno, METH_VARARGS},
|
||||||
{"test_config", test_config, METH_NOARGS},
|
{"test_config", test_config, METH_NOARGS},
|
||||||
{"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS},
|
{"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS},
|
||||||
|
@ -3574,15 +3361,9 @@ static PyMethodDef TestMethods[] = {
|
||||||
#ifdef HAVE_GETTIMEOFDAY
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
{"profile_int", profile_int, METH_NOARGS},
|
{"profile_int", profile_int, METH_NOARGS},
|
||||||
#endif
|
#endif
|
||||||
{"traceback_print", traceback_print, METH_VARARGS},
|
|
||||||
{"exception_print", exception_print, METH_VARARGS},
|
|
||||||
{"set_exception", test_set_exception, METH_O},
|
|
||||||
{"set_exc_info", test_set_exc_info, METH_VARARGS},
|
|
||||||
{"argparsing", argparsing, METH_VARARGS},
|
{"argparsing", argparsing, METH_VARARGS},
|
||||||
{"code_newempty", code_newempty, METH_VARARGS},
|
{"code_newempty", code_newempty, METH_VARARGS},
|
||||||
{"eval_code_ex", eval_eval_code_ex, METH_VARARGS},
|
{"eval_code_ex", eval_eval_code_ex, METH_VARARGS},
|
||||||
{"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
|
|
||||||
METH_VARARGS | METH_KEYWORDS},
|
|
||||||
{"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer,
|
{"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer,
|
||||||
METH_NOARGS},
|
METH_NOARGS},
|
||||||
{"crash_no_current_thread", crash_no_current_thread, METH_NOARGS},
|
{"crash_no_current_thread", crash_no_current_thread, METH_NOARGS},
|
||||||
|
@ -3633,7 +3414,6 @@ static PyMethodDef TestMethods[] = {
|
||||||
#ifdef Py_REF_DEBUG
|
#ifdef Py_REF_DEBUG
|
||||||
{"negative_refcount", negative_refcount, METH_NOARGS},
|
{"negative_refcount", negative_refcount, METH_NOARGS},
|
||||||
#endif
|
#endif
|
||||||
{"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
|
|
||||||
{"sequence_getitem", sequence_getitem, METH_VARARGS},
|
{"sequence_getitem", sequence_getitem, METH_VARARGS},
|
||||||
{"sequence_setitem", sequence_setitem, METH_VARARGS},
|
{"sequence_setitem", sequence_setitem, METH_VARARGS},
|
||||||
{"sequence_delitem", sequence_delitem, METH_VARARGS},
|
{"sequence_delitem", sequence_delitem, METH_VARARGS},
|
||||||
|
@ -3653,8 +3433,6 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"test_refcount_funcs", test_refcount_funcs, METH_NOARGS},
|
{"test_refcount_funcs", test_refcount_funcs, METH_NOARGS},
|
||||||
{"test_py_is_macros", test_py_is_macros, METH_NOARGS},
|
{"test_py_is_macros", test_py_is_macros, METH_NOARGS},
|
||||||
{"test_py_is_funcs", test_py_is_funcs, METH_NOARGS},
|
{"test_py_is_funcs", test_py_is_funcs, METH_NOARGS},
|
||||||
{"fatal_error", test_fatal_error, METH_VARARGS,
|
|
||||||
PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
|
|
||||||
{"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")},
|
{"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")},
|
||||||
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
|
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
|
||||||
{"frame_getlocals", frame_getlocals, METH_O, NULL},
|
{"frame_getlocals", frame_getlocals, METH_O, NULL},
|
||||||
|
@ -3680,8 +3458,6 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"function_set_defaults", function_set_defaults, METH_VARARGS, NULL},
|
{"function_set_defaults", function_set_defaults, METH_VARARGS, NULL},
|
||||||
{"function_get_kw_defaults", function_get_kw_defaults, METH_O, NULL},
|
{"function_get_kw_defaults", function_get_kw_defaults, METH_O, NULL},
|
||||||
{"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL},
|
{"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL},
|
||||||
{"err_set_raised", err_set_raised, METH_O, NULL},
|
|
||||||
{"err_restore", err_restore, METH_VARARGS, NULL},
|
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3902,61 +3678,6 @@ static PyTypeObject awaitType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int recurse_infinitely_error_init(PyObject *, PyObject *, PyObject *);
|
|
||||||
|
|
||||||
static PyTypeObject PyRecursingInfinitelyError_Type = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
"RecursingInfinitelyError", /* tp_name */
|
|
||||||
sizeof(PyBaseExceptionObject), /* tp_basicsize */
|
|
||||||
0, /* tp_itemsize */
|
|
||||||
0, /* tp_dealloc */
|
|
||||||
0, /* tp_vectorcall_offset */
|
|
||||||
0, /* tp_getattr */
|
|
||||||
0, /* tp_setattr */
|
|
||||||
0, /* tp_as_async */
|
|
||||||
0, /* tp_repr */
|
|
||||||
0, /* tp_as_number */
|
|
||||||
0, /* tp_as_sequence */
|
|
||||||
0, /* tp_as_mapping */
|
|
||||||
0, /* tp_hash */
|
|
||||||
0, /* tp_call */
|
|
||||||
0, /* tp_str */
|
|
||||||
0, /* tp_getattro */
|
|
||||||
0, /* tp_setattro */
|
|
||||||
0, /* tp_as_buffer */
|
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
|
||||||
PyDoc_STR("Instantiating this exception starts infinite recursion."), /* tp_doc */
|
|
||||||
0, /* tp_traverse */
|
|
||||||
0, /* tp_clear */
|
|
||||||
0, /* tp_richcompare */
|
|
||||||
0, /* tp_weaklistoffset */
|
|
||||||
0, /* tp_iter */
|
|
||||||
0, /* tp_iternext */
|
|
||||||
0, /* tp_methods */
|
|
||||||
0, /* tp_members */
|
|
||||||
0, /* tp_getset */
|
|
||||||
0, /* tp_base */
|
|
||||||
0, /* tp_dict */
|
|
||||||
0, /* tp_descr_get */
|
|
||||||
0, /* tp_descr_set */
|
|
||||||
0, /* tp_dictoffset */
|
|
||||||
(initproc)recurse_infinitely_error_init, /* tp_init */
|
|
||||||
0, /* tp_alloc */
|
|
||||||
0, /* tp_new */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
|
|
||||||
{
|
|
||||||
PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
|
|
||||||
|
|
||||||
/* Instantiating this exception starts infinite recursion. */
|
|
||||||
Py_INCREF(type);
|
|
||||||
PyErr_SetObject(type, NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Test bpo-35983: create a subclass of "list" which checks that instances
|
/* Test bpo-35983: create a subclass of "list" which checks that instances
|
||||||
* are not deallocated twice */
|
* are not deallocated twice */
|
||||||
|
|
||||||
|
@ -4283,14 +4004,6 @@ PyInit__testcapi(void)
|
||||||
Py_INCREF(&MethStatic_Type);
|
Py_INCREF(&MethStatic_Type);
|
||||||
PyModule_AddObject(m, "MethStatic", (PyObject *)&MethStatic_Type);
|
PyModule_AddObject(m, "MethStatic", (PyObject *)&MethStatic_Type);
|
||||||
|
|
||||||
PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
|
|
||||||
if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_INCREF(&PyRecursingInfinitelyError_Type);
|
|
||||||
PyModule_AddObject(m, "RecursingInfinitelyError",
|
|
||||||
(PyObject *)&PyRecursingInfinitelyError_Type);
|
|
||||||
|
|
||||||
PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX));
|
PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX));
|
||||||
PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN));
|
PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN));
|
||||||
PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX));
|
PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX));
|
||||||
|
@ -4368,6 +4081,9 @@ PyInit__testcapi(void)
|
||||||
if (_PyTestCapi_Init_Structmember(m) < 0) {
|
if (_PyTestCapi_Init_Structmember(m) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (_PyTestCapi_Init_Exceptions(m) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef LIMITED_API_AVAILABLE
|
#ifndef LIMITED_API_AVAILABLE
|
||||||
PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);
|
PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);
|
||||||
|
|
|
@ -107,6 +107,7 @@
|
||||||
<ClCompile Include="..\Modules\_testcapi\float.c" />
|
<ClCompile Include="..\Modules\_testcapi\float.c" />
|
||||||
<ClCompile Include="..\Modules\_testcapi\long.c" />
|
<ClCompile Include="..\Modules\_testcapi\long.c" />
|
||||||
<ClCompile Include="..\Modules\_testcapi\structmember.c" />
|
<ClCompile Include="..\Modules\_testcapi\structmember.c" />
|
||||||
|
<ClCompile Include="..\Modules\_testcapi\exceptions.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\PC\python_nt.rc" />
|
<ResourceCompile Include="..\PC\python_nt.rc" />
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
<ClCompile Include="..\Modules\_testcapi\structmember.c">
|
<ClCompile Include="..\Modules\_testcapi\structmember.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Modules\_testcapi\exceptions.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\PC\python_nt.rc">
|
<ResourceCompile Include="..\PC\python_nt.rc">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue