@@ -636,6 +636,10 @@ def output_templates(self, f):
636636 assert parameters
637637 assert isinstance (parameters [0 ].converter , self_converter )
638638 del parameters [0 ]
639+ requires_defining_class = False
640+ if parameters and isinstance (parameters [0 ].converter , defining_class_converter ):
641+ requires_defining_class = True
642+ del parameters [0 ]
639643 converters = [p .converter for p in parameters ]
640644
641645 has_option_groups = parameters and (parameters [0 ].group or parameters [- 1 ].group )
@@ -657,10 +661,6 @@ def output_templates(self, f):
657661 if not p .is_optional ():
658662 min_pos = i
659663
660- requires_defining_class = any (
661- isinstance (p .converter , defining_class_converter )
662- for p in parameters )
663-
664664 meth_o = (len (parameters ) == 1 and
665665 parameters [0 ].is_positional_only () and
666666 not converters [0 ].is_optional () and
@@ -763,24 +763,40 @@ def parser_body(prototype, *fields, declarations=''):
763763 return linear_format (output (), parser_declarations = declarations )
764764
765765 if not parameters :
766- # no parameters, METH_NOARGS
766+ if not requires_defining_class :
767+ # no parameters, METH_NOARGS
768+ flags = "METH_NOARGS"
767769
768- flags = "METH_NOARGS"
770+ parser_prototype = normalize_snippet ("""
771+ static PyObject *
772+ {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
773+ """ )
774+ parser_code = []
769775
770- parser_prototype = normalize_snippet ("""
771- static PyObject *
772- {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
773- """ )
774- parser_definition = parser_prototype
776+ else :
777+ assert not new_or_init
775778
776- if default_return_converter :
777- parser_definition = parser_prototype + '\n ' + normalize_snippet ("""
778- {{
779- return {c_basename}_impl({impl_arguments});
779+ flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS"
780+
781+ parser_prototype = parser_prototype_def_class
782+ return_error = ('return NULL;' if default_return_converter
783+ else 'goto exit;' )
784+ parser_code = [normalize_snippet ("""
785+ if (nargs) {{
786+ PyErr_SetString(PyExc_TypeError, "{name}() takes no arguments");
787+ %s
780788 }}
781- """ )
789+ """ % return_error , indent = 4 )]
790+
791+ if default_return_converter :
792+ parser_definition = '\n ' .join ([
793+ parser_prototype ,
794+ '{{' ,
795+ * parser_code ,
796+ ' return {c_basename}_impl({impl_arguments});' ,
797+ '}}' ])
782798 else :
783- parser_definition = parser_body (parser_prototype )
799+ parser_definition = parser_body (parser_prototype , * parser_code )
784800
785801 elif meth_o :
786802 flags = "METH_O"
@@ -939,6 +955,9 @@ def parser_body(prototype, *fields, declarations=''):
939955
940956 add_label = None
941957 for i , p in enumerate (parameters ):
958+ if isinstance (p .converter , defining_class_converter ):
959+ raise ValueError ("defining_class should be the first "
960+ "parameter (after self)" )
942961 displayname = p .get_displayname (i + 1 )
943962 parsearg = p .converter .parse_arg (argname_fmt % i , displayname )
944963 if parsearg is None :
0 commit comments