pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/b2566d89ce50e9924bb2fccb87dcfa3ceb6cc0d6

55097560d244c08.css" /> GH-113633: Use module state structure for _testcapi. (GH-113634) · python/cpython@b2566d8 · GitHub
Skip to content

Commit b2566d8

Browse files
authored
GH-113633: Use module state structure for _testcapi. (GH-113634)
Use module state structure for _testcapi.
1 parent 8e4ff5c commit b2566d8

File tree

2 files changed

+65
-51
lines changed

2 files changed

+65
-51
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use module state for the _testcapi extension module.

Modules/_testcapimodule.c

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,32 @@
3333

3434
// Forward declarations
3535
static struct PyModuleDef _testcapimodule;
36-
static PyObject *TestError; /* set to exception object in init */
3736

37+
// Module state
38+
typedef struct {
39+
PyObject *error; // _testcapi.error object
40+
} testcapistate_t;
41+
42+
static testcapistate_t*
43+
get_testcapi_state(PyObject *module)
44+
{
45+
void *state = PyModule_GetState(module);
46+
assert(state != NULL);
47+
return (testcapistate_t *)state;
48+
}
3849

39-
/* Raise TestError with test_name + ": " + msg, and return NULL. */
50+
static PyObject *
51+
get_testerror(PyObject *self) {
52+
testcapistate_t *state = get_testcapi_state((PyObject *)Py_TYPE(self));
53+
return state->error;
54+
}
55+
56+
/* Raise _testcapi.error with test_name + ": " + msg, and return NULL. */
4057

4158
static PyObject *
42-
raiseTestError(const char* test_name, const char* msg)
59+
raiseTestError(PyObject *self, const char* test_name, const char* msg)
4360
{
44-
PyErr_Format(TestError, "%s: %s", test_name, msg);
61+
PyErr_Format(get_testerror(self), "%s: %s", test_name, msg);
4562
return NULL;
4663
}
4764

@@ -52,10 +69,10 @@ raiseTestError(const char* test_name, const char* msg)
5269
platforms have these hardcoded. Better safe than sorry.
5370
*/
5471
static PyObject*
55-
sizeof_error(const char* fatname, const char* typname,
72+
sizeof_error(PyObject *self, const char* fatname, const char* typname,
5673
int expected, int got)
5774
{
58-
PyErr_Format(TestError,
75+
PyErr_Format(get_testerror(self),
5976
"%s #define == %d but sizeof(%s) == %d",
6077
fatname, expected, typname, got);
6178
return (PyObject*)NULL;
@@ -66,7 +83,7 @@ test_config(PyObject *self, PyObject *Py_UNUSED(ignored))
6683
{
6784
#define CHECK_SIZEOF(FATNAME, TYPE) \
6885
if (FATNAME != sizeof(TYPE)) \
69-
return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE))
86+
return sizeof_error(self, #FATNAME, #TYPE, FATNAME, sizeof(TYPE))
7087

7188
CHECK_SIZEOF(SIZEOF_SHORT, short);
7289
CHECK_SIZEOF(SIZEOF_INT, int);
@@ -89,15 +106,15 @@ test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored))
89106
#endif
90107
#define CHECK_SIZEOF(TYPE, EXPECTED) \
91108
if (EXPECTED != sizeof(TYPE)) { \
92-
PyErr_Format(TestError, \
109+
PyErr_Format(get_testerror(self), \
93110
"sizeof(%s) = %u instead of %u", \
94111
#TYPE, sizeof(TYPE), EXPECTED); \
95112
return (PyObject*)NULL; \
96113
}
97114
#define IS_SIGNED(TYPE) (((TYPE)-1) < (TYPE)0)
98115
#define CHECK_SIGNNESS(TYPE, SIGNED) \
99116
if (IS_SIGNED(TYPE) != SIGNED) { \
100-
PyErr_Format(TestError, \
117+
PyErr_Format(get_testerror(self), \
101118
"%s signness is, instead of %i", \
102119
#TYPE, IS_SIGNED(TYPE), SIGNED); \
103120
return (PyObject*)NULL; \
@@ -170,7 +187,7 @@ test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored))
170187
for (i = 0; i < NLIST; ++i) {
171188
PyObject* anint = PyList_GET_ITEM(list, i);
172189
if (PyLong_AS_LONG(anint) != NLIST-1-i) {
173-
PyErr_SetString(TestError,
190+
PyErr_SetString(get_testerror(self),
174191
"test_list_api: reverse screwed up");
175192
Py_DECREF(list);
176193
return (PyObject*)NULL;
@@ -183,7 +200,7 @@ test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored))
183200
}
184201

185202
static int
186-
test_dict_inner(int count)
203+
test_dict_inner(PyObject *self, int count)
187204
{
188205
Py_ssize_t pos = 0, iterations = 0;
189206
int i;
@@ -231,7 +248,7 @@ test_dict_inner(int count)
231248

232249
if (iterations != count) {
233250
PyErr_SetString(
234-
TestError,
251+
get_testerror(self),
235252
"test_dict_iteration: dict iteration went wrong ");
236253
return -1;
237254
} else {
@@ -250,7 +267,7 @@ test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored))
250267
int i;
251268

252269
for (i = 0; i < 200; i++) {
253-
if (test_dict_inner(i) < 0) {
270+
if (test_dict_inner(self, i) < 0) {
254271
return NULL;
255272
}
256273
}
@@ -334,14 +351,14 @@ test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored))
334351
if (obj == NULL) {
335352
PyErr_Clear();
336353
PyErr_SetString(
337-
TestError,
354+
get_testerror(self),
338355
"test_lazy_hash_inheritance: failed to create object");
339356
return NULL;
340357
}
341358

342359
if (type->tp_dict != NULL) {
343360
PyErr_SetString(
344-
TestError,
361+
get_testerror(self),
345362
"test_lazy_hash_inheritance: type initialised too soon");
346363
Py_DECREF(obj);
347364
return NULL;
@@ -351,23 +368,23 @@ test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored))
351368
if ((hash == -1) && PyErr_Occurred()) {
352369
PyErr_Clear();
353370
PyErr_SetString(
354-
TestError,
371+
get_testerror(self),
355372
"test_lazy_hash_inheritance: could not hash object");
356373
Py_DECREF(obj);
357374
return NULL;
358375
}
359376

360377
if (type->tp_dict == NULL) {
361378
PyErr_SetString(
362-
TestError,
379+
get_testerror(self),
363380
"test_lazy_hash_inheritance: type not initialised by hash()");
364381
Py_DECREF(obj);
365382
return NULL;
366383
}
367384

368385
if (type->tp_hash != PyType_Type.tp_hash) {
369386
PyErr_SetString(
370-
TestError,
387+
get_testerror(self),
371388
"test_lazy_hash_inheritance: unexpected hash function");
372389
Py_DECREF(obj);
373390
return NULL;
@@ -427,7 +444,7 @@ py_buildvalue_ints(PyObject *self, PyObject *args)
427444
}
428445

429446
static int
430-
test_buildvalue_N_error(const char *fmt)
447+
test_buildvalue_N_error(PyObject *self, const char *fmt)
431448
{
432449
PyObject *arg, *res;
433450

@@ -443,7 +460,7 @@ test_buildvalue_N_error(const char *fmt)
443460
}
444461
Py_DECREF(res);
445462
if (Py_REFCNT(arg) != 1) {
446-
PyErr_Format(TestError, "test_buildvalue_N: "
463+
PyErr_Format(get_testerror(self), "test_buildvalue_N: "
447464
"arg was not decrefed in successful "
448465
"Py_BuildValue(\"%s\")", fmt);
449466
return -1;
@@ -452,13 +469,13 @@ test_buildvalue_N_error(const char *fmt)
452469
Py_INCREF(arg);
453470
res = Py_BuildValue(fmt, raise_error, NULL, arg);
454471
if (res != NULL || !PyErr_Occurred()) {
455-
PyErr_Format(TestError, "test_buildvalue_N: "
472+
PyErr_Format(get_testerror(self), "test_buildvalue_N: "
456473
"Py_BuildValue(\"%s\") didn't complain", fmt);
457474
return -1;
458475
}
459476
PyErr_Clear();
460477
if (Py_REFCNT(arg) != 1) {
461-
PyErr_Format(TestError, "test_buildvalue_N: "
478+
PyErr_Format(get_testerror(self), "test_buildvalue_N: "
462479
"arg was not decrefed in failed "
463480
"Py_BuildValue(\"%s\")", fmt);
464481
return -1;
@@ -482,25 +499,25 @@ test_buildvalue_N(PyObject *self, PyObject *Py_UNUSED(ignored))
482499
return NULL;
483500
}
484501
if (res != arg) {
485-
return raiseTestError("test_buildvalue_N",
502+
return raiseTestError(self, "test_buildvalue_N",
486503
"Py_BuildValue(\"N\") returned wrong result");
487504
}
488505
if (Py_REFCNT(arg) != 2) {
489-
return raiseTestError("test_buildvalue_N",
506+
return raiseTestError(self, "test_buildvalue_N",
490507
"arg was not decrefed in Py_BuildValue(\"N\")");
491508
}
492509
Py_DECREF(res);
493510
Py_DECREF(arg);
494511

495-
if (test_buildvalue_N_error("O&N") < 0)
512+
if (test_buildvalue_N_error(self, "O&N") < 0)
496513
return NULL;
497-
if (test_buildvalue_N_error("(O&N)") < 0)
514+
if (test_buildvalue_N_error(self, "(O&N)") < 0)
498515
return NULL;
499-
if (test_buildvalue_N_error("[O&N]") < 0)
516+
if (test_buildvalue_N_error(self, "[O&N]") < 0)
500517
return NULL;
501-
if (test_buildvalue_N_error("{O&N}") < 0)
518+
if (test_buildvalue_N_error(self, "{O&N}") < 0)
502519
return NULL;
503-
if (test_buildvalue_N_error("{()O&(())N}") < 0)
520+
if (test_buildvalue_N_error(self, "{()O&(())N}") < 0)
504521
return NULL;
505522

506523
Py_RETURN_NONE;
@@ -910,7 +927,7 @@ test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) {
910927

911928
Py_RETURN_NONE;
912929
fail:
913-
return raiseTestError("test_string_to_double", msg);
930+
return raiseTestError(self, "test_string_to_double", msg);
914931
#undef CHECK_STRING
915932
#undef CHECK_INVALID
916933
}
@@ -1061,7 +1078,7 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored))
10611078

10621079
exit:
10631080
if (error) {
1064-
return raiseTestError("test_capsule", error);
1081+
return raiseTestError(self, "test_capsule", error);
10651082
}
10661083
Py_RETURN_NONE;
10671084
#undef FAIL
@@ -1272,7 +1289,7 @@ test_from_contiguous(PyObject* self, PyObject *Py_UNUSED(ignored))
12721289
ptr = view.buf;
12731290
for (i = 0; i < 5; i++) {
12741291
if (ptr[2*i] != i) {
1275-
PyErr_SetString(TestError,
1292+
PyErr_SetString(get_testerror(self),
12761293
"test_from_contiguous: incorrect result");
12771294
return NULL;
12781295
}
@@ -1285,7 +1302,7 @@ test_from_contiguous(PyObject* self, PyObject *Py_UNUSED(ignored))
12851302
ptr = view.buf;
12861303
for (i = 0; i < 5; i++) {
12871304
if (*(ptr-2*i) != i) {
1288-
PyErr_SetString(TestError,
1305+
PyErr_SetString(get_testerror(self),
12891306
"test_from_contiguous: incorrect result");
12901307
return NULL;
12911308
}
@@ -1338,7 +1355,7 @@ test_pep3118_obsolete_write_locks(PyObject* self, PyObject *Py_UNUSED(ignored))
13381355
Py_RETURN_NONE;
13391356

13401357
error:
1341-
PyErr_SetString(TestError,
1358+
PyErr_SetString(get_testerror(self),
13421359
"test_pep3118_obsolete_write_locks: failure");
13431360
return NULL;
13441361
}
@@ -1959,7 +1976,7 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args)
19591976
{
19601977
Py_tss_t tss_key = Py_tss_NEEDS_INIT;
19611978
if (PyThread_tss_is_created(&tss_key)) {
1962-
return raiseTestError("test_pythread_tss_key_state",
1979+
return raiseTestError(self, "test_pythread_tss_key_state",
19631980
"TSS key not in an uninitialized state at "
19641981
"creation time");
19651982
}
@@ -1968,27 +1985,27 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args)
19681985
return NULL;
19691986
}
19701987
if (!PyThread_tss_is_created(&tss_key)) {
1971-
return raiseTestError("test_pythread_tss_key_state",
1988+
return raiseTestError(self, "test_pythread_tss_key_state",
19721989
"PyThread_tss_create succeeded, "
19731990
"but with TSS key in an uninitialized state");
19741991
}
19751992
if (PyThread_tss_create(&tss_key) != 0) {
1976-
return raiseTestError("test_pythread_tss_key_state",
1993+
return raiseTestError(self, "test_pythread_tss_key_state",
19771994
"PyThread_tss_create unsuccessful with "
19781995
"an already initialized key");
19791996
}
19801997
#define CHECK_TSS_API(expr) \
19811998
(void)(expr); \
19821999
if (!PyThread_tss_is_created(&tss_key)) { \
1983-
return raiseTestError("test_pythread_tss_key_state", \
2000+
return raiseTestError(self, "test_pythread_tss_key_state", \
19842001
"TSS key initialization state was not " \
19852002
"preserved after calling " #expr); }
19862003
CHECK_TSS_API(PyThread_tss_set(&tss_key, NULL));
19872004
CHECK_TSS_API(PyThread_tss_get(&tss_key));
19882005
#undef CHECK_TSS_API
19892006
PyThread_tss_delete(&tss_key);
19902007
if (PyThread_tss_is_created(&tss_key)) {
1991-
return raiseTestError("test_pythread_tss_key_state",
2008+
return raiseTestError(self, "test_pythread_tss_key_state",
19922009
"PyThread_tss_delete called, but did not "
19932010
"set the key state to uninitialized");
19942011
}
@@ -1999,7 +2016,7 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args)
19992016
return NULL;
20002017
}
20012018
if (PyThread_tss_is_created(ptr_key)) {
2002-
return raiseTestError("test_pythread_tss_key_state",
2019+
return raiseTestError(self, "test_pythread_tss_key_state",
20032020
"TSS key not in an uninitialized state at "
20042021
"allocation time");
20052022
}
@@ -3831,14 +3848,9 @@ static PyTypeObject ContainerNoGC_type = {
38313848

38323849
static struct PyModuleDef _testcapimodule = {
38333850
PyModuleDef_HEAD_INIT,
3834-
"_testcapi",
3835-
NULL,
3836-
-1,
3837-
TestMethods,
3838-
NULL,
3839-
NULL,
3840-
NULL,
3841-
NULL
3851+
.m_name = "_testcapi",
3852+
.m_size = sizeof(testcapistate_t),
3853+
.m_methods = TestMethods,
38423854
};
38433855

38443856
/* Per PEP 489, this module will not be converted to multi-phase initialization
@@ -3933,9 +3945,10 @@ PyInit__testcapi(void)
39333945
PyModule_AddIntConstant(m, "the_number_three", 3);
39343946
PyModule_AddIntMacro(m, Py_C_RECURSION_LIMIT);
39353947

3936-
TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
3937-
Py_INCREF(TestError);
3938-
PyModule_AddObject(m, "error", TestError);
3948+
testcapistate_t *state = get_testcapi_state(m);
3949+
state->error = PyErr_NewException("_testcapi.error", NULL, NULL);
3950+
Py_INCREF(state->error);
3951+
PyModule_AddObject(m, "error", state->error);
39393952

39403953
if (PyType_Ready(&ContainerNoGC_type) < 0) {
39413954
return NULL;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy