Skip to content

Commit 0c39c87

Browse files
committed
Switch to tp_new instead of tp_alloc. Enables bytearray.
Use Py_SINGLETON so it inlines.
1 parent 31cffb5 commit 0c39c87

2 files changed

Lines changed: 15 additions & 16 deletions

File tree

Modules/clinic/_testclinic.c.h

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/clinic/libclinic/parse_args.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
243241
VECTORCALL_FINALE_MARKERS_INIT: Final[dict[str, str]] = {
244242
"init_declarations": "PyObject *self;\nint _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

Comments
 (0)