Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0ec761a

Browse files
[3.12]gh-117482: Fix Builtin Types Slot Wrappers (gh-121632)
When builtin static types are initialized for a subinterpreter, various "tp" slots have already been inherited (for the main interpreter). This was interfering with the logic in add_operators() (in Objects/typeobject.c), causing a wrapper to get created when it shouldn't. This change fixes that by preserving the original data from the static type struct and checking that.(cherry picked from commit5250a03, AKAgh-121602)Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
1 parent5492f84 commit0ec761a

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed

‎Lib/test/test_types.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
importpickle
1010
importlocale
1111
importsys
12+
importtextwrap
1213
importtypes
1314
importunittest.mock
1415
importweakref
@@ -2252,5 +2253,39 @@ def coro():
22522253
'close','throw'}))
22532254

22542255

2256+
classSubinterpreterTests(unittest.TestCase):
2257+
2258+
@classmethod
2259+
defsetUpClass(cls):
2260+
globalinterpreters
2261+
try:
2262+
fromtest.supportimportinterpreters
2263+
exceptModuleNotFoundError:
2264+
raiseunittest.SkipTest('subinterpreters required')
2265+
2266+
@cpython_only
2267+
deftest_slot_wrappers(self):
2268+
rch,sch=interpreters.create_channel()
2269+
2270+
# For now it's sufficient to check int.__str__.
2271+
# See https://github.com/python/cpython/issues/117482
2272+
# and https://github.com/python/cpython/pull/117660.
2273+
script=textwrap.dedent(f'''
2274+
text = repr(int.__str__)
2275+
sch = interpreters.SendChannel({sch.id})
2276+
sch.send_nowait(text)
2277+
''')
2278+
2279+
exec(script)
2280+
expected=rch.recv()
2281+
2282+
interp=interpreters.create()
2283+
interp.run('from test.support import interpreters')
2284+
interp.run(script)
2285+
results=rch.recv()
2286+
2287+
self.assertEqual(results,expected)
2288+
2289+
22552290
if__name__=='__main__':
22562291
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Unexpected slot wrappers are no longer created for builtin static types in
2+
subinterpreters.

‎Objects/typeobject.c‎

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ static_builtin_index_clear(PyTypeObject *self)
116116
self->tp_subclasses=NULL;
117117
}
118118

119+
120+
/* In 3.13+ this is stored in _PyRuntimeState. */
121+
staticPyTypeObjectstatic_type_defs[_Py_MAX_STATIC_BUILTIN_TYPES];
122+
123+
staticinlinePyTypeObject*
124+
static_builtin_get_def(PyTypeObject*type)
125+
{
126+
size_tindex=static_builtin_index_get(type);
127+
return&static_type_defs[index];
128+
}
129+
130+
119131
staticinlinestatic_builtin_state*
120132
static_builtin_state_get(PyInterpreterState*interp,PyTypeObject*self)
121133
{
@@ -6982,7 +6994,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
69826994
return0;
69836995
}
69846996

6985-
staticintadd_operators(PyTypeObject*);
6997+
staticintadd_operators(PyTypeObject*,PyTypeObject*);
69866998
staticintadd_tp_new_wrapper(PyTypeObject*type);
69876999

69887000
#defineCOLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
@@ -7147,10 +7159,10 @@ type_dict_set_doc(PyTypeObject *type)
71477159

71487160

71497161
staticint
7150-
type_ready_fill_dict(PyTypeObject*type)
7162+
type_ready_fill_dict(PyTypeObject*type,PyTypeObject*def)
71517163
{
71527164
/* Add type-specific descriptors to tp_dict */
7153-
if (add_operators(type)<0) {
7165+
if (add_operators(type,def)<0) {
71547166
return-1;
71557167
}
71567168
if (type_add_methods(type)<0) {
@@ -7462,7 +7474,7 @@ type_ready_post_checks(PyTypeObject *type)
74627474

74637475

74647476
staticint
7465-
type_ready(PyTypeObject*type,intrerunbuiltin)
7477+
type_ready(PyTypeObject*type,PyTypeObject*def,intrerunbuiltin)
74667478
{
74677479
_PyObject_ASSERT((PyObject*)type, !is_readying(type));
74687480
start_readying(type);
@@ -7499,7 +7511,7 @@ type_ready(PyTypeObject *type, int rerunbuiltin)
74997511
if (type_ready_set_new(type,rerunbuiltin)<0) {
75007512
gotoerror;
75017513
}
7502-
if (type_ready_fill_dict(type)<0) {
7514+
if (type_ready_fill_dict(type,def)<0) {
75037515
gotoerror;
75047516
}
75057517
if (!rerunbuiltin) {
@@ -7551,7 +7563,7 @@ PyType_Ready(PyTypeObject *type)
75517563
type->tp_flags |=Py_TPFLAGS_IMMUTABLETYPE;
75527564
}
75537565

7554-
returntype_ready(type,0);
7566+
returntype_ready(type,NULL,0);
75557567
}
75567568

75577569
int
@@ -7581,10 +7593,16 @@ _PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self)
75817593

75827594
static_builtin_state_init(interp,self);
75837595

7584-
intres=type_ready(self, !ismain);
7596+
PyTypeObject*def=static_builtin_get_def(self);
7597+
if (ismain) {
7598+
memcpy(def,self,sizeof(PyTypeObject));
7599+
}
7600+
7601+
intres=type_ready(self,def, !ismain);
75857602
if (res<0) {
75867603
static_builtin_state_clear(interp,self);
75877604
}
7605+
75887606
returnres;
75897607
}
75907608

@@ -10108,17 +10126,22 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
1010810126
infinite recursion here.) */
1010910127

1011010128
staticint
10111-
add_operators(PyTypeObject*type)
10129+
add_operators(PyTypeObject*type,PyTypeObject*def)
1011210130
{
1011310131
PyObject*dict=lookup_tp_dict(type);
1011410132
pytype_slotdef*p;
1011510133
PyObject*descr;
1011610134
void**ptr;
1011710135

10136+
assert(def==NULL|| (type->tp_flags&_Py_TPFLAGS_STATIC_BUILTIN));
10137+
if (def==NULL) {
10138+
def=type;
10139+
}
10140+
1011810141
for (p=slotdefs;p->name;p++) {
1011910142
if (p->wrapper==NULL)
1012010143
continue;
10121-
ptr=slotptr(type,p->offset);
10144+
ptr=slotptr(def,p->offset);
1012210145
if (!ptr|| !*ptr)
1012310146
continue;
1012410147
intr=PyDict_Contains(dict,p->name_strobj);

‎Tools/c-analyzer/cpython/globals-to-fix.tsv‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@ Objects/sliceobject.c-_Py_EllipsisObject-
305305
Python/instrumentation.c-_PyInstrumentation_DISABLE-
306306
Python/instrumentation.c-_PyInstrumentation_MISSING-
307307

308+
##-----------------------
309+
## other
310+
311+
Objects/typeobject.c-static_type_defs-
312+
308313

309314
##################################
310315
## global non-objects to fix in core code

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp