@@ -877,43 +877,16 @@ def parse_parameter(self, line: str) -> None:
877877
878878 # handle "as" for parameters too
879879 c_name = None
880- name , have_as_token , trailing = line .partition (' as ' )
881- if have_as_token :
882- name = name .strip ()
883- if ' ' not in name :
884- fields = trailing .strip ().split (' ' )
885- if not fields :
886- fail ("Invalid 'as' clause!" )
887- c_name = fields [0 ]
888- if c_name .endswith (':' ):
889- name += ':'
890- c_name = c_name [:- 1 ]
891- fields [0 ] = name
892- line = ' ' .join (fields )
893-
894- default : str | None
895- base , equals , default = line .rpartition ('=' )
896- if not equals :
897- base = default
898- default = None
899-
900- module = None
880+ m = re .match (r'(?:\* *)?\w+( +as +(\w+))' , line )
881+ if m :
882+ c_name = m [2 ]
883+ line = line [:m .start (1 )] + line [m .end (1 ):]
884+
901885 try :
902- ast_input = f"def x({ base } ): pass"
886+ ast_input = f"def x({ line } \n ): pass"
903887 module = ast .parse (ast_input )
904888 except SyntaxError :
905- try :
906- # the last = was probably inside a function call, like
907- # c: int(accept={str})
908- # so assume there was no actual default value.
909- default = None
910- ast_input = f"def x({ line } ): pass"
911- module = ast .parse (ast_input )
912- except SyntaxError :
913- pass
914- if not module :
915- fail (f"Function { self .function .name !r} has an invalid parameter declaration:\n \t " ,
916- repr (line ))
889+ fail (f"Function { self .function .name !r} has an invalid parameter declaration: { line !r} " )
917890
918891 function = module .body [0 ]
919892 assert isinstance (function , ast .FunctionDef )
@@ -922,9 +895,6 @@ def parse_parameter(self, line: str) -> None:
922895 if len (function_args .args ) > 1 :
923896 fail (f"Function { self .function .name !r} has an "
924897 f"invalid parameter declaration (comma?): { line !r} " )
925- if function_args .defaults or function_args .kw_defaults :
926- fail (f"Function { self .function .name !r} has an "
927- f"invalid parameter declaration (default value?): { line !r} " )
928898 if function_args .kwarg :
929899 fail (f"Function { self .function .name !r} has an "
930900 f"invalid parameter declaration (**kwargs?): { line !r} " )
@@ -944,7 +914,7 @@ def parse_parameter(self, line: str) -> None:
944914 name = 'varpos_' + name
945915
946916 value : object
947- if not default :
917+ if not function_args . defaults :
948918 if is_vararg :
949919 value = NULL
950920 else :
@@ -955,17 +925,13 @@ def parse_parameter(self, line: str) -> None:
955925 if 'py_default' in kwargs :
956926 fail ("You can't specify py_default without specifying a default value!" )
957927 else :
958- if is_vararg :
959- fail ( "Vararg can't take a default value!" )
928+ expr = function_args . defaults [ 0 ]
929+ default = ast_input [ expr . col_offset : expr . end_col_offset ]. strip ( )
960930
961931 if self .parameter_state is ParamState .REQUIRED :
962932 self .parameter_state = ParamState .OPTIONAL
963- default = default .strip ()
964933 bad = False
965- ast_input = f"x = { default } "
966934 try :
967- module = ast .parse (ast_input )
968-
969935 if 'c_default' not in kwargs :
970936 # we can only represent very simple data values in C.
971937 # detect whether default is okay, via a denylist
@@ -992,13 +958,14 @@ def bad_node(self, node: ast.AST) -> None:
992958 visit_Starred = bad_node
993959
994960 denylist = DetectBadNodes ()
995- denylist .visit (module )
961+ denylist .visit (expr )
996962 bad = denylist .bad
997963 else :
998964 # if they specify a c_default, we can be more lenient about the default value.
999965 # but at least make an attempt at ensuring it's a valid expression.
966+ code = compile (ast .Expression (expr ), '<expr>' , 'eval' )
1000967 try :
1001- value = eval (default )
968+ value = eval (code )
1002969 except NameError :
1003970 pass # probably a named constant
1004971 except Exception as e :
@@ -1010,9 +977,6 @@ def bad_node(self, node: ast.AST) -> None:
1010977 if bad :
1011978 fail (f"Unsupported expression as default value: { default !r} " )
1012979
1013- assignment = module .body [0 ]
1014- assert isinstance (assignment , ast .Assign )
1015- expr = assignment .value
1016980 # mild hack: explicitly support NULL as a default value
1017981 c_default : str | None
1018982 if isinstance (expr , ast .Name ) and expr .id == 'NULL' :
@@ -1064,8 +1028,6 @@ def bad_node(self, node: ast.AST) -> None:
10641028 else :
10651029 c_default = py_default
10661030
1067- except SyntaxError as e :
1068- fail (f"Syntax error: { e .text !r} " )
10691031 except (ValueError , AttributeError ):
10701032 value = unknown
10711033 c_default = kwargs .get ("c_default" )
0 commit comments