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

Commitc6dbfbb

Browse files
[3.13]gh-117482: Fix Builtin Types Slot Wrappers (gh-121630)
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 parent38c4028 commitc6dbfbb

File tree

4 files changed

+69
-10
lines changed

4 files changed

+69
-10
lines changed

‎Include/internal/pycore_typeobject.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct _types_runtime_state {
3333
struct {
3434
struct {
3535
PyTypeObject*type;
36+
PyTypeObjectdef;
3637
int64_tinterp_count;
3738
}types[_Py_MAX_MANAGED_STATIC_TYPES];
3839
}managed_static;

‎Lib/test/test_types.py‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
importpickle
1111
importlocale
1212
importsys
13+
importtextwrap
1314
importtypes
1415
importunittest.mock
1516
importweakref
@@ -2345,5 +2346,40 @@ def ex(a, /, b, *, c):
23452346
)
23462347

23472348

2349+
classSubinterpreterTests(unittest.TestCase):
2350+
2351+
@classmethod
2352+
defsetUpClass(cls):
2353+
globalinterpreters
2354+
try:
2355+
fromtest.supportimportinterpreters
2356+
exceptModuleNotFoundError:
2357+
raiseunittest.SkipTest('subinterpreters required')
2358+
importtest.support.interpreters.channels
2359+
2360+
@cpython_only
2361+
deftest_slot_wrappers(self):
2362+
rch,sch=interpreters.channels.create()
2363+
2364+
# For now it's sufficient to check int.__str__.
2365+
# See https://github.com/python/cpython/issues/117482
2366+
# and https://github.com/python/cpython/pull/117660.
2367+
script=textwrap.dedent('''
2368+
text = repr(int.__str__)
2369+
sch.send_nowait(text)
2370+
''')
2371+
2372+
exec(script)
2373+
expected=rch.recv()
2374+
2375+
interp=interpreters.create()
2376+
interp.exec('from test.support import interpreters')
2377+
interp.prepare_main(sch=sch)
2378+
interp.exec(script)
2379+
results=rch.recv()
2380+
2381+
self.assertEqual(results,expected)
2382+
2383+
23482384
if__name__=='__main__':
23492385
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: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,16 @@ managed_static_type_state_clear(PyInterpreterState *interp, PyTypeObject *self,
314314
}
315315
}
316316

317+
staticPyTypeObject*
318+
managed_static_type_get_def(PyTypeObject*self,intisbuiltin)
319+
{
320+
size_tindex=managed_static_type_index_get(self);
321+
size_tfull_index=isbuiltin
322+
?index
323+
:index+_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES;
324+
return&_PyRuntime.types.managed_static.types[full_index].def;
325+
}
326+
317327
// Also see _PyStaticType_InitBuiltin() and _PyStaticType_FiniBuiltin().
318328

319329
/* end static builtin helpers */
@@ -5668,7 +5678,6 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type,
56685678

56695679
_PyStaticType_ClearWeakRefs(interp,type);
56705680
managed_static_type_state_clear(interp,type,isbuiltin,final);
5671-
/* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
56725681
}
56735682

56745683
void
@@ -7671,7 +7680,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
76717680
return0;
76727681
}
76737682

7674-
staticintadd_operators(PyTypeObject*);
7683+
staticintadd_operators(PyTypeObject*,PyTypeObject*);
76757684
staticintadd_tp_new_wrapper(PyTypeObject*type);
76767685

76777686
#defineCOLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
@@ -7836,10 +7845,10 @@ type_dict_set_doc(PyTypeObject *type)
78367845

78377846

78387847
staticint
7839-
type_ready_fill_dict(PyTypeObject*type)
7848+
type_ready_fill_dict(PyTypeObject*type,PyTypeObject*def)
78407849
{
78417850
/* Add type-specific descriptors to tp_dict */
7842-
if (add_operators(type)<0) {
7851+
if (add_operators(type,def)<0) {
78437852
return-1;
78447853
}
78457854
if (type_add_methods(type)<0) {
@@ -8158,7 +8167,7 @@ type_ready_post_checks(PyTypeObject *type)
81588167

81598168

81608169
staticint
8161-
type_ready(PyTypeObject*type,intinitial)
8170+
type_ready(PyTypeObject*type,PyTypeObject*def,intinitial)
81628171
{
81638172
ASSERT_TYPE_LOCK_HELD();
81648173

@@ -8197,7 +8206,7 @@ type_ready(PyTypeObject *type, int initial)
81978206
if (type_ready_set_new(type,initial)<0) {
81988207
gotoerror;
81998208
}
8200-
if (type_ready_fill_dict(type)<0) {
8209+
if (type_ready_fill_dict(type,def)<0) {
82018210
gotoerror;
82028211
}
82038212
if (initial) {
@@ -8254,7 +8263,7 @@ PyType_Ready(PyTypeObject *type)
82548263
intres;
82558264
BEGIN_TYPE_LOCK();
82568265
if (!(type->tp_flags&Py_TPFLAGS_READY)) {
8257-
res=type_ready(type,1);
8266+
res=type_ready(type,NULL,1);
82588267
}else {
82598268
res=0;
82608269
assert(_PyType_CheckConsistency(type));
@@ -8290,14 +8299,20 @@ init_static_type(PyInterpreterState *interp, PyTypeObject *self,
82908299

82918300
managed_static_type_state_init(interp,self,isbuiltin,initial);
82928301

8302+
PyTypeObject*def=managed_static_type_get_def(self,isbuiltin);
8303+
if (initial) {
8304+
memcpy(def,self,sizeof(PyTypeObject));
8305+
}
8306+
82938307
intres;
82948308
BEGIN_TYPE_LOCK();
8295-
res=type_ready(self,initial);
8309+
res=type_ready(self,def,initial);
82968310
END_TYPE_LOCK();
82978311
if (res<0) {
82988312
_PyStaticType_ClearWeakRefs(interp,self);
82998313
managed_static_type_state_clear(interp,self,isbuiltin,initial);
83008314
}
8315+
83018316
returnres;
83028317
}
83038318

@@ -10885,17 +10900,22 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
1088510900
infinite recursion here.) */
1088610901

1088710902
staticint
10888-
add_operators(PyTypeObject*type)
10903+
add_operators(PyTypeObject*type,PyTypeObject*def)
1088910904
{
1089010905
PyObject*dict=lookup_tp_dict(type);
1089110906
pytype_slotdef*p;
1089210907
PyObject*descr;
1089310908
void**ptr;
1089410909

10910+
assert(def==NULL|| (type->tp_flags&_Py_TPFLAGS_STATIC_BUILTIN));
10911+
if (def==NULL) {
10912+
def=type;
10913+
}
10914+
1089510915
for (p=slotdefs;p->name;p++) {
1089610916
if (p->wrapper==NULL)
1089710917
continue;
10898-
ptr=slotptr(type,p->offset);
10918+
ptr=slotptr(def,p->offset);
1089910919
if (!ptr|| !*ptr)
1090010920
continue;
1090110921
intr=PyDict_Contains(dict,p->name_strobj);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp