@@ -1075,22 +1075,7 @@ def _generate_vc_parsing_code(self) -> list[str]:
10751075 def emit (text : str , indent : int = 4 ) -> None :
10761076 parser_code .append (snippet (text , indent = indent ))
10771077
1078- if no_params :
1079- self .codegen .add_include ('pycore_modsupport.h' ,
1080- '_PyArg_NoKwnames()' )
1081- emit ("""
1082- if (!_PyArg_NoKwnames("{name}", kwnames)) {{
1083- goto exit;
1084- }}
1085- if (nargs != 0) {{
1086- PyErr_Format(PyExc_TypeError,
1087- "{name}() takes no arguments (%zd given)",
1088- nargs);
1089- goto exit;
1090- }}
1091- """ )
1092- return parser_code
1093- elif all_pos_only :
1078+ if no_params or all_pos_only :
10941079 self .codegen .add_include ('pycore_modsupport.h' ,
10951080 '_PyArg_NoKwnames()' )
10961081 emit ("""
@@ -1099,21 +1084,30 @@ def emit(text: str, indent: int = 4) -> None:
10991084 }}
11001085 """ )
11011086
1087+ if no_params :
1088+ emit ("""
1089+ if (nargs != 0) {{
1090+ PyErr_Format(PyExc_TypeError,
1091+ "{name}() takes no arguments (%zd given)",
1092+ nargs);
1093+ goto exit;
1094+ }}
1095+ """ )
1096+ return parser_code
1097+
11021098 pos_code , success = self ._generate_vc_pos_only_code ()
11031099 if not success :
11041100 for parameter in self .parameters :
11051101 parameter .converter .use_converter ()
11061102 self .codegen .add_include ('pycore_modsupport.h' ,
11071103 '_PyArg_ParseStack()' )
1108- return [snippet ("""
1109- if (!_PyArg_NoKwnames("{name}", kwnames)) {{
1110- goto exit;
1111- }}
1104+ emit ("""
11121105 if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}",
11131106 {parse_arguments})) {{
11141107 goto exit;
11151108 }}
1116- """ , indent = 4 )]
1109+ """ )
1110+ return parser_code
11171111 parser_code .extend (pos_code )
11181112 return parser_code
11191113 else :
@@ -1203,47 +1197,40 @@ def emit(text: str, indent: int = 4) -> None:
12031197
12041198 return parser_code
12051199
1206- def generate_vectorcall (self ) -> str :
1207- """Generate a vectorcall function for __init__ or __new__."""
1208- func = self .func
1200+ def _vc_prototype (self ) -> str :
12091201 vc_basename = self ._vc_basename ()
1210-
1211- # Generate argument parsing code (FASTCALL-style)
1212- parsing_code = self ._generate_vc_parsing_code ()
1213-
1214- # Build the function prototype
1215- prototype = libclinic .normalize_snippet (f"""
1202+ return libclinic .normalize_snippet (f"""
12161203 static PyObject *
12171204 { vc_basename } (PyObject *type, PyObject *const *args,
12181205 size_t nargsf, PyObject *kwnames)
12191206 """ )
12201207
1221- # Build the preamble
1222- preamble = libclinic .normalize_snippet ("""
1208+ def _vc_preamble ( self ) -> str :
1209+ return libclinic .normalize_snippet ("""
12231210 {{
12241211 PyObject *return_value = NULL;
12251212 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
12261213 {declarations}
12271214 {initializers}
12281215 """ ) + "\n "
12291216
1230- # Exact type check (if vectorcall_exact_only)
1231- exact_check = ""
1232- if func .vectorcall and func .vectorcall .exact_only and func .cls :
1233- type_obj = func . cls . type_object
1234- self . codegen . add_include ( 'pycore_call.h' ,
1235- '_PyObject_MakeTpCall()' )
1236- exact_check = libclinic .normalize_snippet (f"""
1237- if (_PyType_CAST(type) != { type_obj } ) {{{{
1238- PyThreadState *tstate = _PyThreadState_GET();
1239- return _PyObject_MakeTpCall(tstate, type, args,
1240- nargs, kwnames);
1241- }}}}
1242- """ , indent = 4 )
1243-
1244- # Build the finale (impl call + return)
1245- if func .kind is METHOD_INIT :
1246- finale = libclinic .normalize_snippet ("""
1217+ def _vc_exact_check ( self ) -> str :
1218+ func = self . func
1219+ if not ( func .vectorcall and func .vectorcall .exact_only and func .cls ) :
1220+ return ""
1221+ type_obj = func . cls . type_object
1222+ self . codegen . add_include ( 'pycore_call.h' , '_PyObject_MakeTpCall()' )
1223+ return libclinic .normalize_snippet (f"""
1224+ if (_PyType_CAST(type) != { type_obj } ) {{{{
1225+ PyThreadState *tstate = _PyThreadState_GET();
1226+ return _PyObject_MakeTpCall(tstate, type, args,
1227+ nargs, kwnames);
1228+ }}}}
1229+ """ , indent = 4 )
1230+
1231+ def _vc_finale ( self ) -> str :
1232+ if self . func .kind is METHOD_INIT :
1233+ return libclinic .normalize_snippet ("""
12471234 {modifications}
12481235 {lock}
12491236 {{
@@ -1269,7 +1256,7 @@ def generate_vectorcall(self) -> str:
12691256 """ )
12701257 else :
12711258 # METHOD_NEW
1272- finale = libclinic .normalize_snippet ("""
1259+ return libclinic .normalize_snippet ("""
12731260 {modifications}
12741261 {lock}
12751262 return_value = {c_basename}_impl({vc_impl_arguments});
@@ -1283,13 +1270,18 @@ def generate_vectorcall(self) -> str:
12831270 }}
12841271 """ )
12851272
1286- # Assemble the full function
1287- lines = [prototype ]
1288- lines .append (preamble )
1273+ def generate_vectorcall (self ) -> str :
1274+ """Generate a vectorcall function for __init__ or __new__."""
1275+ parsing_code = self ._generate_vc_parsing_code ()
1276+
1277+ lines = [self ._vc_prototype (), self ._vc_preamble ()]
1278+
1279+ exact_check = self ._vc_exact_check ()
12891280 if exact_check :
12901281 lines .append (exact_check )
1282+
12911283 lines .extend (parsing_code )
1292- lines .append (finale )
1284+ lines .append (self . _vc_finale () )
12931285
12941286 code = libclinic .linear_format (
12951287 "\n " .join (lines ),
0 commit comments