Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-110572: Remove test_* from _testcapi/getargs.c #111214

Merged
merged 3 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions Lib/test/test_capi/test_getargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,15 @@ def test_w_star(self):
self.assertRaises(TypeError, getargs_w_star, NONCONTIG_WRITABLE)
self.assertRaises(TypeError, getargs_w_star, NONCONTIG_READONLY)

def test_getargs_empty(self):
from _testcapi import getargs_empty
self.assertTrue(getargs_empty())
self.assertRaises(TypeError, getargs_empty, 1)
self.assertRaises(TypeError, getargs_empty, 1, 2, 3)
self.assertRaises(TypeError, getargs_empty, a=1)
self.assertRaises(TypeError, getargs_empty, a=1, b=2)
self.assertRaises(TypeError, getargs_empty, 'x', 'y', 'z', a=1, b=2)


class String_TestCase(unittest.TestCase):
def test_C(self):
Expand Down Expand Up @@ -1306,11 +1315,5 @@ def test_nonascii_keywords(self):
parse((), {name2: 1, name3: 2}, '|OO', [name, name3])


class Test_testcapi(unittest.TestCase):
locals().update((name, getattr(_testcapi, name))
for name in dir(_testcapi)
if name.startswith('test_') and name.endswith('_code'))


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2159,7 +2159,7 @@ def test_gilstate_matches_current(self):
class Test_testcapi(unittest.TestCase):
locals().update((name, getattr(_testcapi, name))
for name in dir(_testcapi)
if name.startswith('test_') and not name.endswith('_code'))
serhiy-storchaka marked this conversation as resolved.
Show resolved Hide resolved
if name.startswith('test_'))

# Suppress warning from PyUnicode_FromUnicode().
@warnings_helper.ignore_warnings(category=DeprecationWarning)
Expand Down
220 changes: 14 additions & 206 deletions Modules/_testcapi/getargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,32 +138,25 @@ getargs_w_star(PyObject *self, PyObject *args)
}

static PyObject *
test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored))
getargs_empty(PyObject *self, PyObject *args, PyObject *kwargs)
{
/* Test that formats can begin with '|'. See issue #4720. */
PyObject *dict = NULL;
static char *kwlist[] = {NULL};
PyObject *tuple = PyTuple_New(0);
if (!tuple) {
return NULL;
}
assert(PyTuple_CheckExact(args));
assert(kwargs == NULL || PyDict_CheckExact(kwargs));

int result;
if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) {
goto done;
}
dict = PyDict_New();
if (!dict) {
goto done;
}
result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse",
kwlist);
done:
Py_DECREF(tuple);
Py_XDECREF(dict);
if (kwargs != NULL && PyDict_GET_SIZE(kwargs) > 0) {
static char *kwlist[] = {NULL};
result = PyArg_ParseTupleAndKeywords(args, kwargs, "|:getargs_empty",
kwlist);
}
else {
result = PyArg_ParseTuple(args, "|:getargs_empty");
}
if (!result) {
return NULL;
}
Py_RETURN_NONE;
return PyLong_FromLong(result);
}

/* Test tuple argument processing */
Expand Down Expand Up @@ -354,90 +347,6 @@ getargs_K(PyObject *self, PyObject *args)
return PyLong_FromUnsignedLongLong(value);
}

/* This function not only tests the 'k' getargs code, but also the
PyLong_AsUnsignedLongMask() function. */
static PyObject *
test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyObject *tuple = PyTuple_New(1);
if (tuple == NULL) {
return NULL;
}

/* a number larger than ULONG_MAX even on 64-bit platforms */
PyObject *num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
if (num == NULL) {
goto error;
}

unsigned long value = PyLong_AsUnsignedLongMask(num);
if (value == (unsigned long)-1 && PyErr_Occurred()) {
Py_DECREF(num);
goto error;
}
else if (value != ULONG_MAX) {
Py_DECREF(num);
PyErr_SetString(PyExc_AssertionError,
"test_k_code: "
"PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
goto error;
}

PyTuple_SET_ITEM(tuple, 0, num);

value = 0;
if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) {
goto error;
}
if (value != ULONG_MAX) {
PyErr_SetString(PyExc_AssertionError,
"test_k_code: k code returned wrong value for long 0xFFF...FFF");
goto error;
}

Py_DECREF(tuple); // also clears `num`
tuple = PyTuple_New(1);
if (tuple == NULL) {
return NULL;
}
num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16);
if (num == NULL) {
goto error;
}

value = PyLong_AsUnsignedLongMask(num);
if (value == (unsigned long)-1 && PyErr_Occurred()) {
Py_DECREF(num);
goto error;
}
else if (value != (unsigned long)-0x42) {
Py_DECREF(num);
PyErr_SetString(PyExc_AssertionError,
"test_k_code: "
"PyLong_AsUnsignedLongMask() returned wrong value for long -0xFFF..000042");
goto error;
}

PyTuple_SET_ITEM(tuple, 0, num);

value = 0;
if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) {
goto error;
}
if (value != (unsigned long)-0x42) {
PyErr_SetString(PyExc_AssertionError,
"test_k_code: k code returned wrong value for long -0xFFF..000042");
goto error;
}

Py_DECREF(tuple);
Py_RETURN_NONE;

error:
Py_DECREF(tuple);
return NULL;
}

static PyObject *
getargs_f(PyObject *self, PyObject *args)
{
Expand Down Expand Up @@ -718,104 +627,6 @@ getargs_et_hash(PyObject *self, PyObject *args)
return result;
}

/* Test the L code for PyArg_ParseTuple. This should deliver a long long
for both long and int arguments. The test may leak a little memory if
it fails.
*/
static PyObject *
test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyObject *tuple = PyTuple_New(1);
if (tuple == NULL) {
return NULL;
}

PyObject *num = PyLong_FromLong(42);
if (num == NULL) {
goto error;
}

PyTuple_SET_ITEM(tuple, 0, num);

long long value = -1;
if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) {
goto error;
}
if (value != 42) {
PyErr_SetString(PyExc_AssertionError,
"test_L_code: L code returned wrong value for long 42");
goto error;
}

Py_DECREF(tuple); // also clears `num`
tuple = PyTuple_New(1);
if (tuple == NULL) {
return NULL;
}
num = PyLong_FromLong(42);
if (num == NULL) {
goto error;
}

PyTuple_SET_ITEM(tuple, 0, num);

value = -1;
if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) {
goto error;
}
if (value != 42) {
PyErr_SetString(PyExc_AssertionError,
"test_L_code: L code returned wrong value for int 42");
goto error;
}

Py_DECREF(tuple);
Py_RETURN_NONE;

error:
Py_DECREF(tuple);
return NULL;
}

/* Test the s and z codes for PyArg_ParseTuple.
*/
static PyObject *
test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored))
{
/* Unicode strings should be accepted */
PyObject *tuple = PyTuple_New(1);
if (tuple == NULL) {
return NULL;
}

PyObject *obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"),
"latin-1", NULL);
if (obj == NULL) {
goto error;
}

PyTuple_SET_ITEM(tuple, 0, obj);

/* These two blocks used to raise a TypeError:
* "argument must be string without null bytes, not str"
*/
char *value;
if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) {
goto error;
}

if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) {
goto error;
}

Py_DECREF(tuple);
Py_RETURN_NONE;

error:
Py_DECREF(tuple);
return NULL;
}

static PyObject *
gh_99240_clear_args(PyObject *self, PyObject *args)
{
Expand Down Expand Up @@ -869,17 +680,14 @@ static PyMethodDef test_methods[] = {
{"getargs_s_star", getargs_s_star, METH_VARARGS},
{"getargs_tuple", getargs_tuple, METH_VARARGS},
{"getargs_w_star", getargs_w_star, METH_VARARGS},
{"getargs_empty", _PyCFunction_CAST(getargs_empty), METH_VARARGS|METH_KEYWORDS},
{"getargs_y", getargs_y, METH_VARARGS},
{"getargs_y_hash", getargs_y_hash, METH_VARARGS},
{"getargs_y_star", getargs_y_star, METH_VARARGS},
{"getargs_z", getargs_z, METH_VARARGS},
{"getargs_z_hash", getargs_z_hash, METH_VARARGS},
{"getargs_z_star", getargs_z_star, METH_VARARGS},
{"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS},
{"test_L_code", test_L_code, METH_NOARGS},
{"test_empty_argparse", test_empty_argparse, METH_NOARGS},
{"test_k_code", test_k_code, METH_NOARGS},
{"test_s_code", test_s_code, METH_NOARGS},
{"gh_99240_clear_args", gh_99240_clear_args, METH_VARARGS},
{NULL},
};
Expand Down
2 changes: 1 addition & 1 deletion Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ Modules/_testcapimodule.c make_exception_with_doc kwlist -
Modules/_testcapimodule.c raise_SIGINT_then_send_None PyId_send -
Modules/_testcapimodule.c slot_tp_del PyId___tp_del__ -
Modules/_testcapimodule.c test_capsule buffer -
Modules/_testcapimodule.c test_empty_argparse kwlist -
Modules/_testcapimodule.c getargs_empty kwlist -
Modules/_testcapimodule.c test_structmembers_new keywords -
Modules/_testcapimodule.c getargs_s_hash_int keywords -
Modules/_testcapimodule.c - g_dict_watch_events -
Expand Down
Loading