11
11
unspecified , fail , warn , Sentinels , VersionTuple )
12
12
from libclinic .function import (
13
13
GETTER , SETTER , METHOD_INIT , METHOD_NEW )
14
- from libclinic .crenderdata import CRenderData , TemplateDict
14
+ from libclinic .codegen import CRenderData , TemplateDict , Codegen
15
15
from libclinic .language import Language
16
16
from libclinic .function import (
17
17
Module , Class , Function , Parameter ,
@@ -26,15 +26,15 @@ def declare_parser(
26
26
f : Function ,
27
27
* ,
28
28
hasformat : bool = False ,
29
- clinic : Clinic ,
30
- limited_capi : bool ,
29
+ codegen : Codegen ,
31
30
) -> str :
32
31
"""
33
32
Generates the code template for a static local PyArg_Parser variable,
34
33
with an initializer. For core code (incl. builtin modules) the
35
34
kwtuple field is also statically initialized. Otherwise
36
35
it is initialized at runtime.
37
36
"""
37
+ limited_capi = codegen .limited_capi
38
38
if hasformat :
39
39
fname = ''
40
40
format_ = '.format = "{format_units}:{name}",'
@@ -80,8 +80,8 @@ def declare_parser(
80
80
""" % num_keywords
81
81
82
82
condition = '#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)'
83
- clinic .add_include ('pycore_gc.h' , 'PyGC_Head' , condition = condition )
84
- clinic .add_include ('pycore_runtime.h' , '_Py_ID()' , condition = condition )
83
+ codegen .add_include ('pycore_gc.h' , 'PyGC_Head' , condition = condition )
84
+ codegen .add_include ('pycore_runtime.h' , '_Py_ID()' , condition = condition )
85
85
86
86
declarations += """
87
87
static const char * const _keywords[] = {{{keywords_c} NULL}};
@@ -317,14 +317,14 @@ def deprecate_keyword_use(
317
317
self ,
318
318
func : Function ,
319
319
params : dict [int , Parameter ],
320
- argname_fmt : str | None ,
320
+ argname_fmt : str | None = None ,
321
321
* ,
322
322
fastcall : bool ,
323
- limited_capi : bool ,
324
- clinic : Clinic ,
323
+ codegen : Codegen ,
325
324
) -> str :
326
325
assert len (params ) > 0
327
326
last_param = next (reversed (params .values ()))
327
+ limited_capi = codegen .limited_capi
328
328
329
329
# Format the deprecation message.
330
330
containscheck = ""
@@ -336,11 +336,11 @@ def deprecate_keyword_use(
336
336
elif fastcall :
337
337
conditions .append (f"nargs < { i + 1 } && PySequence_Contains(kwnames, &_Py_ID({ p .name } ))" )
338
338
containscheck = "PySequence_Contains"
339
- clinic .add_include ('pycore_runtime.h' , '_Py_ID()' )
339
+ codegen .add_include ('pycore_runtime.h' , '_Py_ID()' )
340
340
else :
341
341
conditions .append (f"nargs < { i + 1 } && PyDict_Contains(kwargs, &_Py_ID({ p .name } ))" )
342
342
containscheck = "PyDict_Contains"
343
- clinic .add_include ('pycore_runtime.h' , '_Py_ID()' )
343
+ codegen .add_include ('pycore_runtime.h' , '_Py_ID()' )
344
344
else :
345
345
conditions = [f"nargs < { i + 1 } " ]
346
346
condition = ") || (" .join (conditions )
@@ -399,7 +399,7 @@ def deprecate_keyword_use(
399
399
def output_templates (
400
400
self ,
401
401
f : Function ,
402
- clinic : Clinic
402
+ codegen : Codegen ,
403
403
) -> dict [str , str ]:
404
404
parameters = list (f .parameters .values ())
405
405
assert parameters
@@ -412,7 +412,7 @@ def output_templates(
412
412
converters = [p .converter for p in parameters ]
413
413
414
414
if f .critical_section :
415
- clinic .add_include ('pycore_critical_section.h' , 'Py_BEGIN_CRITICAL_SECTION()' )
415
+ codegen .add_include ('pycore_critical_section.h' , 'Py_BEGIN_CRITICAL_SECTION()' )
416
416
has_option_groups = parameters and (parameters [0 ].group or parameters [- 1 ].group )
417
417
simple_return = (f .return_converter .type == 'PyObject *'
418
418
and not f .critical_section )
@@ -517,7 +517,7 @@ def parser_body(
517
517
parser_declarations = declarations )
518
518
519
519
fastcall = not new_or_init
520
- limited_capi = clinic .limited_capi
520
+ limited_capi = codegen .limited_capi
521
521
if limited_capi and (pseudo_args or
522
522
(any (p .is_optional () for p in parameters ) and
523
523
any (p .is_keyword_only () and not p .is_optional () for p in parameters )) or
@@ -673,8 +673,8 @@ def parser_body(
673
673
""" ,
674
674
indent = 4 ))
675
675
else :
676
- clinic .add_include ('pycore_modsupport.h' ,
677
- '_PyArg_CheckPositional()' )
676
+ codegen .add_include ('pycore_modsupport.h' ,
677
+ '_PyArg_CheckPositional()' )
678
678
parser_code = [libclinic .normalize_snippet (f"""
679
679
if (!_PyArg_CheckPositional("{{name}}", { nargs } , { min_pos } , { max_args } )) {{{{
680
680
goto exit;
@@ -735,8 +735,8 @@ def parser_body(
735
735
if limited_capi :
736
736
fastcall = False
737
737
if fastcall :
738
- clinic .add_include ('pycore_modsupport.h' ,
739
- '_PyArg_ParseStack()' )
738
+ codegen .add_include ('pycore_modsupport.h' ,
739
+ '_PyArg_ParseStack()' )
740
740
parser_code = [libclinic .normalize_snippet ("""
741
741
if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}",
742
742
{parse_arguments})) {{
@@ -773,17 +773,17 @@ def parser_body(
773
773
fastcall = False
774
774
else :
775
775
if vararg == self .NO_VARARG :
776
- clinic .add_include ('pycore_modsupport.h' ,
777
- '_PyArg_UnpackKeywords()' )
776
+ codegen .add_include ('pycore_modsupport.h' ,
777
+ '_PyArg_UnpackKeywords()' )
778
778
args_declaration = "_PyArg_UnpackKeywords" , "%s, %s, %s" % (
779
779
min_pos ,
780
780
max_pos ,
781
781
min_kw_only
782
782
)
783
783
nargs = "nargs"
784
784
else :
785
- clinic .add_include ('pycore_modsupport.h' ,
786
- '_PyArg_UnpackKeywordsWithVararg()' )
785
+ codegen .add_include ('pycore_modsupport.h' ,
786
+ '_PyArg_UnpackKeywordsWithVararg()' )
787
787
args_declaration = "_PyArg_UnpackKeywordsWithVararg" , "%s, %s, %s, %s" % (
788
788
min_pos ,
789
789
max_pos ,
@@ -796,8 +796,7 @@ def parser_body(
796
796
flags = "METH_FASTCALL|METH_KEYWORDS"
797
797
parser_prototype = self .PARSER_PROTOTYPE_FASTCALL_KEYWORDS
798
798
argname_fmt = 'args[%d]'
799
- declarations = declare_parser (f , clinic = clinic ,
800
- limited_capi = clinic .limited_capi )
799
+ declarations = declare_parser (f , codegen = codegen )
801
800
declarations += "\n PyObject *argsbuf[%s];" % len (converters )
802
801
if has_optional_kw :
803
802
declarations += "\n Py_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (nargs , min_pos + min_kw_only )
@@ -812,8 +811,7 @@ def parser_body(
812
811
flags = "METH_VARARGS|METH_KEYWORDS"
813
812
parser_prototype = self .PARSER_PROTOTYPE_KEYWORD
814
813
argname_fmt = 'fastargs[%d]'
815
- declarations = declare_parser (f , clinic = clinic ,
816
- limited_capi = clinic .limited_capi )
814
+ declarations = declare_parser (f , codegen = codegen )
325D
817
815
declarations += "\n PyObject *argsbuf[%s];" % len (converters )
818
816
declarations += "\n PyObject * const *fastargs;"
819
817
declarations += "\n Py_ssize_t nargs = PyTuple_GET_SIZE(args);"
@@ -832,10 +830,10 @@ def parser_body(
832
830
833
831
if parser_code is not None :
834
832
if deprecated_keywords :
835
- code = self .deprecate_keyword_use (f , deprecated_keywords , argname_fmt ,
836
- clinic = clinic ,
837
- fastcall = fastcall ,
838
- limited_capi = limited_capi )
833
+ code = self .deprecate_keyword_use (f , deprecated_keywords ,
834
+ argname_fmt ,
835
+ codegen = codegen ,
836
+ fastcall = fastcall )
839
837
parser_code .append (code )
840
838
841
839
add_label : str | None = None
@@ -903,9 +901,8 @@ def parser_body(
903
901
for parameter in parameters :
904
902
parameter .converter .use_converter ()
905
903
906
- declarations = declare_parser (f , clinic = clinic ,
907
- hasformat = True ,
908
- limited_capi = limited_capi )
904
+ declarations = declare_parser (f , codegen = codegen ,
905
+ hasformat = True )
909
906
if limited_capi :
910
907
# positional-or-keyword arguments
911
908
assert not fastcall
@@ -921,17 +918,17 @@ def parser_body(
921
918
declarations += "\n Py_ssize_t nargs = PyTuple_Size(args);"
922
919
923
920
elif fastcall :
924
- clinic .add_include ('pycore_modsupport.h' ,
925
- '_PyArg_ParseStackAndKeywords()' )
921
+ codegen .add_include ('pycore_modsupport.h' ,
922
+ '_PyArg_ParseStackAndKeywords()' )
926
923
parser_code = [libclinic .normalize_snippet ("""
927
924
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma}
928
925
{parse_arguments})) {{
929
926
goto exit;
930
927
}}
931
928
""" , indent = 4 )]
932
929
else :
933
- clinic .add_include ('pycore_modsupport.h' ,
934
- '_PyArg_ParseTupleAndKeywordsFast()' )
930
+ codegen .add_include ('pycore_modsupport.h' ,
931
+ '_PyArg_ParseTupleAndKeywordsFast()' )
935
932
parser_code = [libclinic .normalize_snippet ("""
936
933
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
937
934
{parse_arguments})) {{
@@ -941,10 +938,9 @@ def parser_body(
941
938
if deprecated_positionals or deprecated_keywords :
942
939
declarations += "\n Py_ssize_t nargs = PyTuple_GET_SIZE(args);"
943
940
if deprecated_keywords :
944
- code = self .deprecate_keyword_use (f , deprecated_keywords , None ,
945
- clinic = clinic ,
946
- fastcall = fastcall ,
947
- limited_capi = limited_capi )
941
+ code = self .deprecate_keyword_use (f , deprecated_keywords ,
942
+ codegen = codegen ,
943
+ fastcall = fastcall )
948
944
parser_code .append (code )
949
945
950
946
if deprecated_positionals :
@@ -960,9 +956,9 @@ def parser_body(
960
956
# Copy includes from parameters to Clinic after parse_arg() has been
961
957
# called above.
962
958
for converter in converters :
963
- for include in converter .includes :
964
- clinic .add_include (include .filename , include .reason ,
965
- condition = include .condition )
959
+ for include in converter .get_includes () :
960
+ codegen .add_include (include .filename , include .reason ,
961
+ condition = include .condition )
966
962
967
963
if new_or_init :
968
964
methoddef_define = ''
@@ -984,16 +980,16 @@ def parser_body(
984
980
985
981
if not parses_keywords :
986
982
declarations = '{base_type_ptr}'
987
- clinic .add_include ('pycore_modsupport.h' ,
988
- '_PyArg_NoKeywords()' )
983
+ codegen .add_include ('pycore_modsupport.h' ,
984
+ '_PyArg_NoKeywords()' )
989
985
fields .insert (0 , libclinic .normalize_snippet ("""
990
986
if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs)) {{
991
987
goto exit;
992
988
}}
993
989
""" , indent = 4 ))
994
990
if not parses_positional :
995
- clinic .add_include ('pycore_modsupport.h' ,
996
- '_PyArg_NoPositional()' )
991
+ codegen .add_include ('pycore_modsupport.h' ,
992
+ '_PyArg_NoPositional()' )
997
993
fields .insert (0 , libclinic .normalize_snippet ("""
998
994
if ({self_type_check}!_PyArg_NoPositional("{name}", args)) {{
999
995
goto exit;
@@ -1030,8 +1026,7 @@ def parser_body(
1030
1026
cpp_if = "#if " + conditional
1031
1027
cpp_endif = "#endif /* " + conditional + " */"
1032
1028
1033
- if methoddef_define and f .full_name not in clinic .ifndef_symbols :
1034
- clinic .ifndef_symbols .add (f .full_name )
1029
+ if methoddef_define and codegen .add_ifndef_symbol (f .full_name ):
1035
1030
methoddef_ifndef = self .METHODDEF_PROTOTYPE_IFNDEF
1036
1031
1037
1032
# add ';' to the end of parser_prototype and impl_prototype
@@ -1190,16 +1185,17 @@ def render_function(
1190
1185
clinic : Clinic ,
1191
1186
f : Function | None
1192
1187
) -> str :
1193
- if f is None or clinic is None :
1188
+ if f is None :
1194
1189
return ""
1195
1190
1191
+ codegen = clinic .codegen
1196
1192
data = CRenderData ()
1197
1193
1198
1194
assert f .parameters , "We should always have a 'self' at this point!"
1199
1195
parameters = f .render_parameters
1200
1196
converters = [p .converter for p in parameters ]
1201
1197
1202
- templates = self .output_templates (f , clinic )
1198
+ templates = self .output_templates (f , codegen )
1203
1199
1204
1200
f_self = parameters [0 ]
1205
1201
selfless = parameters [1 :]
@@ -1323,7 +1319,7 @@ def render_function(
1323
1319
1324
1320
if has_option_groups :
1325
1321
self .render_option_group_parsing (f , template_dict ,
1326
- limited_capi = clinic .limited_capi )
1322
+ limited_capi = codegen .limited_capi )
1327
1323
1328
1324
# buffers, not destination
1329
1325
for name , destination in clinic .destination_buffers .items ():
0 commit comments