@@ -4864,11 +4864,21 @@ def state_parameter(self, line: str | None) -> None:
48644864 self .parameter_continuation = line [:- 1 ]
48654865 return
48664866
4867- line = line .lstrip ()
4868-
4869- if line in ('*' , '/' , '[' , ']' ):
4870- self .parse_special_symbol (line )
4871- return
4867+ func = self .function
4868+ match line .lstrip ():
4869+ case '*' :
4870+ self .parse_star (func )
4871+ case '[' :
4872+ self .parse_opening_square_bracket (func )
4873+ case ']' :
4874+ self .parse_closing_square_bracket (func )
4875+ case '/' :
4876+ self .parse_slash (func )
4877+ case param :
4878+ self .parse_parameter (param )
4879+
4880+ def parse_parameter (self , line : str ) -> None :
4881+ assert self .function is not None
48724882
48734883 match self .parameter_state :
48744884 case ParamState .START | ParamState .REQUIRED :
@@ -5146,57 +5156,71 @@ def parse_converter(
51465156 "Annotations must be either a name, a function call, or a string."
51475157 )
51485158
5149- def parse_special_symbol (self , symbol ):
5150- if symbol == '*' :
5151- if self .keyword_only :
5152- fail ("Function " + self .function .name + " uses '*' more than once." )
5153- self .keyword_only = True
5154- elif symbol == '[' :
5155- match self .parameter_state :
5156- case ParamState .START | ParamState .LEFT_SQUARE_BEFORE :
5157- self .parameter_state = ParamState .LEFT_SQUARE_BEFORE
5158- case ParamState .REQUIRED | ParamState .GROUP_AFTER :
5159- self .parameter_state = ParamState .GROUP_AFTER
5160- case st :
5161- fail (f"Function { self .function .name } has an unsupported group configuration. (Unexpected state { st } .b)" )
5162- self .group += 1
5163- self .function .docstring_only = True
5164- elif symbol == ']' :
5165- if not self .group :
5166- fail ("Function " + self .function .name + " has a ] without a matching [." )
5167- if not any (p .group == self .group for p in self .function .parameters .values ()):
5168- fail ("Function " + self .function .name + " has an empty group.\n All groups must contain at least one parameter." )
5169- self .group -= 1
5170- match self .parameter_state :
5171- case ParamState .LEFT_SQUARE_BEFORE | ParamState .GROUP_BEFORE :
5172- self .parameter_state = ParamState .GROUP_BEFORE
5173- case ParamState .GROUP_AFTER | ParamState .RIGHT_SQUARE_AFTER :
5174- self .parameter_state = ParamState .RIGHT_SQUARE_AFTER
5175- case st :
5176- fail (f"Function { self .function .name } has an unsupported group configuration. (Unexpected state { st } .c)" )
5177- elif symbol == '/' :
5178- if self .positional_only :
5179- fail ("Function " + self .function .name + " uses '/' more than once." )
5180- self .positional_only = True
5181- # REQUIRED and OPTIONAL are allowed here, that allows positional-only without option groups
5182- # to work (and have default values!)
5183- allowed = {
5184- ParamState .REQUIRED ,
5185- ParamState .OPTIONAL ,
5186- ParamState .RIGHT_SQUARE_AFTER ,
5187- ParamState .GROUP_BEFORE ,
5188- }
5189- if (self .parameter_state not in allowed ) or self .group :
5190- fail (f"Function { self .function .name } has an unsupported group configuration. (Unexpected state { self .parameter_state } .d)" )
5191- if self .keyword_only :
5192- fail ("Function " + self .function .name + " mixes keyword-only and positional-only parameters, which is unsupported." )
5193- # fixup preceding parameters
5194- for p in self .function .parameters .values ():
5195- if p .is_vararg ():
5196- continue
5197- if (p .kind != inspect .Parameter .POSITIONAL_OR_KEYWORD and not isinstance (p .converter , self_converter )):
5198- fail ("Function " + self .function .name + " mixes keyword-only and positional-only parameters, which is unsupported." )
5199- p .kind = inspect .Parameter .POSITIONAL_ONLY
5159+ def parse_star (self , function : Function ) -> None :
5160+ """Parse keyword-only parameter marker '*'."""
5161+ if self .keyword_only :
5162+ fail (f"Function { function .name } uses '*' more than once." )
5163+ self .keyword_only = True
5164+
5165+ def parse_opening_square_bracket (self , function : Function ) -> None :
5166+ """Parse opening parameter group symbol '['."""
5167+ match self .parameter_state :
5168+ case ParamState .START | ParamState .LEFT_SQUARE_BEFORE :
5169+ self .parameter_state = ParamState .LEFT_SQUARE_BEFORE
5170+ case ParamState .REQUIRED | ParamState .GROUP_AFTER :
5171+ self .parameter_state = ParamState .GROUP_AFTER
5172+ case st :
5173+ fail (f"Function { function .name } has an unsupported group configuration. "
5174+ f"(Unexpected state { st } .b)" )
5175+ self .group += 1
5176+ function .docstring_only = True
5177+
5178+ def parse_closing_square_bracket (self , function : Function ) -> None :
5179+ """Parse closing parameter group symbol ']'."""
5180+ if not self .group :
5181+ fail (f"Function { function .name } has a ] without a matching [." )
5182+ if not any (p .group == self .group for p in function .parameters .values ()):
5183+ fail (f"Function { function .name } has an empty group.\n "
5184+ "All groups must contain at least one parameter." )
5185+ self .group -= 1
5186+ match self .parameter_state :
5187+ case ParamState .LEFT_SQUARE_BEFORE | ParamState .GROUP_BEFORE :
5188+ self .parameter_state = ParamState .GROUP_BEFORE
5189+ case ParamState .GROUP_AFTER | ParamState .RIGHT_SQUARE_AFTER :
5190+ self .parameter_state = ParamState .RIGHT_SQUARE_AFTER
5191+ case st :
5192+ fail (f"Function { function .name } has an unsupported group configuration. "
5193+ f"(Unexpected state { st } .c)" )
5194+
5195+ def parse_slash (self , function : Function ) -> None :
5196+ """Parse positional-only parameter marker '/'."""
5197+ if self .positional_only :
5198+ fail (f"Function { function .name } uses '/' more than once." )
5199+ self .positional_only = True
5200+ # REQUIRED and OPTIONAL are allowed here, that allows positional-only
5201+ # without option groups to work (and have default values!)
5202+ allowed = {
5203+ ParamState .REQUIRED ,
5204+ ParamState .OPTIONAL ,
5205+ ParamState .RIGHT_SQUARE_AFTER ,
5206+ ParamState .GROUP_BEFORE ,
5207+ }
5208+ if (self .parameter_state not in allowed ) or self .group :
5209+ fail (f"Function { function .name } has an unsupported group configuration. "
5210+ f"(Unexpected state { self .parameter_state } .d)" )
5211+ if self .keyword_only :
5212+ fail (f"Function { function .name } mixes keyword-only and "
5213+ "positional-only parameters, which is unsupported." )
5214+ # fixup preceding parameters
5215+ for p in function .parameters .values ():
5216+ if p .is_vararg ():
5217+ continue
5218+ if (p .kind is not inspect .Parameter .POSITIONAL_OR_KEYWORD and
5219+ not isinstance (p .converter , self_converter )
5220+ ):
5221+ fail (f"Function { function .name } mixes keyword-only and "
5222+ "positional-only parameters, which is unsupported." )
5223+ p .kind = inspect .Parameter .POSITIONAL_ONLY
52005224
52015225 def state_parameter_docstring_start (self , line : str | None ) -> None :
52025226 self .parameter_docstring_indent = len (self .indent .margin )
0 commit comments