@@ -235,16 +235,14 @@ def declare_parser(
235235 "{return_value} = {c_basename}_impl({vectorcall_impl_arguments});" ,
236236 "init_result_check" : "" ,
237237}
238- # METHOD_INIT: tp_alloc self, let the int-returning impl initialize it, and
239- # return it. The locals are declared up front so a label can precede
240- # {self_alloc} (C11). Skipping tp_new requires it be PyType_GenericNew, which
241- # cannot be asserted: a Windows extension module sees a different address for
242- # a dllimport function in a static initializer than in a comparison.
238+ # METHOD_INIT: Create self through tp_new. In vectorcall we have no tuple of
239+ # args and want to void constructing one so pass the empty tuple. This is okay
240+ # for PyType_GenericNew which ignores args.
243241VECTORCALL_FINALE_MARKERS_INIT : Final [dict [str , str ]] = {
244242 "init_declarations" : "PyObject *self;\n int _result;" ,
245243 "self_alloc" : libclinic .normalize_snippet ("""
246- self = _PyType_CAST(type)->tp_alloc(
247- _PyType_CAST(type), 0 );
244+ self = _PyType_CAST(type)->tp_new(_PyType_CAST(type),
245+ (PyObject *)&_Py_SINGLETON(tuple_empty), NULL );
248246 if (self == NULL) {{
249247 goto exit;
250248 }}
@@ -1414,8 +1412,8 @@ def create_template_dict(self) -> dict[str, str]:
14141412 def _vectorcall_type_check (self ) -> list [str ]:
14151413 """Assert `type` is the one type this vectorcall was generated for.
14161414
1417- The generated code is only correct for that type: __init__ allocates
1418- with tp_alloc rather than calling tp_new . tp_vectorcall is not
1415+ The generated code is only correct for that type: __init__ calls
1416+ tp_new with no arguments, then the impl . tp_vectorcall is not
14191417 inherited, so subclasses never reach it; the assert catches C code
14201418 installing the function on a second type.
14211419 """
@@ -1453,6 +1451,7 @@ def _assemble_vectorcall(self, preamble: str, fields: tuple[str, ...],
14531451
14541452 if self .func .kind is METHOD_INIT :
14551453 markers = VECTORCALL_FINALE_MARKERS_INIT
1454+ self .codegen .add_include ('pycore_runtime.h' , '_Py_SINGLETON()' )
14561455 else :
14571456 markers = VECTORCALL_FINALE_MARKERS_NEW
14581457 code = libclinic .linear_format ("\n " .join (lines ), ** markers )
@@ -1508,8 +1507,8 @@ def _vectorcall_delegate_to_helper(self, nkw: str) -> str:
15081507 receiver = "self"
15091508 bind_result = "_result = "
15101509 prologue = libclinic .normalize_snippet ("""
1511- self = _PyType_CAST(type)->tp_alloc(
1512- _PyType_CAST(type), 0 );
1510+ self = _PyType_CAST(type)->tp_new(_PyType_CAST(type),
1511+ (PyObject *)&_Py_SINGLETON(tuple_empty), NULL );
15131512 if (self == NULL) {{
15141513 return NULL;
15151514 }}
0 commit comments