mirror of
https://github.com/python/cpython.git
synced 2024-11-24 18:34:43 +08:00
gh-107735: Add C API tests for PySys_GetObject() and PySys_SetObject() (GH-107736)
This commit is contained in:
parent
430632d6f7
commit
bea5f93196
@ -51,6 +51,8 @@ _testcapi = import_helper.import_module('_testcapi')
|
|||||||
import _testinternalcapi
|
import _testinternalcapi
|
||||||
|
|
||||||
|
|
||||||
|
NULL = None
|
||||||
|
|
||||||
def decode_stderr(err):
|
def decode_stderr(err):
|
||||||
return err.decode('utf-8', 'replace').replace('\r', '')
|
return err.decode('utf-8', 'replace').replace('\r', '')
|
||||||
|
|
||||||
@ -2576,5 +2578,46 @@ class TestUops(unittest.TestCase):
|
|||||||
with self.assertRaises(StopIteration):
|
with self.assertRaises(StopIteration):
|
||||||
next(it)
|
next(it)
|
||||||
|
|
||||||
|
def test_sys_getobject(self):
|
||||||
|
getobject = _testcapi.sys_getobject
|
||||||
|
|
||||||
|
self.assertIs(getobject(b'stdout'), sys.stdout)
|
||||||
|
with support.swap_attr(sys, '\U0001f40d', 42):
|
||||||
|
self.assertEqual(getobject('\U0001f40d'.encode()), 42)
|
||||||
|
|
||||||
|
self.assertIs(getobject(b'nonexisting'), AttributeError)
|
||||||
|
self.assertIs(getobject(b'\xff'), AttributeError)
|
||||||
|
# CRASHES getobject(NULL)
|
||||||
|
|
||||||
|
def test_sys_setobject(self):
|
||||||
|
setobject = _testcapi.sys_setobject
|
||||||
|
|
||||||
|
value = ['value']
|
||||||
|
value2 = ['value2']
|
||||||
|
try:
|
||||||
|
self.assertEqual(setobject(b'newattr', value), 0)
|
||||||
|
self.assertIs(sys.newattr, value)
|
||||||
|
self.assertEqual(setobject(b'newattr', value2), 0)
|
||||||
|
self.assertIs(sys.newattr, value2)
|
||||||
|
self.assertEqual(setobject(b'newattr', NULL), 0)
|
||||||
|
self.assertFalse(hasattr(sys, 'newattr'))
|
||||||
|
self.assertEqual(setobject(b'newattr', NULL), 0)
|
||||||
|
finally:
|
||||||
|
with contextlib.suppress(AttributeError):
|
||||||
|
del sys.newattr
|
||||||
|
try:
|
||||||
|
self.assertEqual(setobject('\U0001f40d'.encode(), value), 0)
|
||||||
|
self.assertIs(getattr(sys, '\U0001f40d'), value)
|
||||||
|
self.assertEqual(setobject('\U0001f40d'.encode(), NULL), 0)
|
||||||
|
self.assertFalse(hasattr(sys, '\U0001f40d'))
|
||||||
|
finally:
|
||||||
|
with contextlib.suppress(AttributeError):
|
||||||
|
delattr(sys, '\U0001f40d')
|
||||||
|
|
||||||
|
with self.assertRaises(UnicodeDecodeError):
|
||||||
|
setobject(b'\xff', value)
|
||||||
|
# CRASHES setobject(NULL, value)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -44,6 +44,16 @@
|
|||||||
// Include definitions from there.
|
// Include definitions from there.
|
||||||
#include "_testcapi/parts.h"
|
#include "_testcapi/parts.h"
|
||||||
|
|
||||||
|
#define NULLABLE(x) do { if (x == Py_None) x = NULL; } while (0);
|
||||||
|
|
||||||
|
#define RETURN_INT(value) do { \
|
||||||
|
int _ret = (value); \
|
||||||
|
if (_ret == -1) { \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
return PyLong_FromLong(_ret); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
static struct PyModuleDef _testcapimodule;
|
static struct PyModuleDef _testcapimodule;
|
||||||
static PyObject *TestError; /* set to exception object in init */
|
static PyObject *TestError; /* set to exception object in init */
|
||||||
@ -3505,6 +3515,35 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sys_getobject(PyObject *Py_UNUSED(module), PyObject *arg)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
Py_ssize_t size;
|
||||||
|
if (!PyArg_Parse(arg, "z#", &name, &size)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *result = PySys_GetObject(name);
|
||||||
|
if (result == NULL) {
|
||||||
|
result = PyExc_AttributeError;
|
||||||
|
}
|
||||||
|
return Py_NewRef(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sys_setobject(PyObject *Py_UNUSED(module), PyObject *args)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
Py_ssize_t size;
|
||||||
|
PyObject *value;
|
||||||
|
if (!PyArg_ParseTuple(args, "z#O", &name, &size, &value)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
NULLABLE(value);
|
||||||
|
RETURN_INT(PySys_SetObject(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef TestMethods[] = {
|
static PyMethodDef TestMethods[] = {
|
||||||
{"set_errno", set_errno, METH_VARARGS},
|
{"set_errno", set_errno, METH_VARARGS},
|
||||||
{"test_config", test_config, METH_NOARGS},
|
{"test_config", test_config, METH_NOARGS},
|
||||||
@ -3640,6 +3679,8 @@ static PyMethodDef TestMethods[] = {
|
|||||||
{"check_pyimport_addmodule", check_pyimport_addmodule, METH_VARARGS},
|
{"check_pyimport_addmodule", check_pyimport_addmodule, METH_VARARGS},
|
||||||
{"test_weakref_capi", test_weakref_capi, METH_NOARGS},
|
{"test_weakref_capi", test_weakref_capi, METH_NOARGS},
|
||||||
{"test_dict_capi", test_dict_capi, METH_NOARGS},
|
{"test_dict_capi", test_dict_capi, METH_NOARGS},
|
||||||
|
{"sys_getobject", sys_getobject, METH_O},
|
||||||
|
{"sys_setobject", sys_setobject, METH_VARARGS},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user