@@ -2439,6 +2439,8 @@ def __repr__(self) -> str:
24392439ParamDict = dict [str , "Parameter" ]
24402440ReturnConverterType = Callable [..., "CReturnConverter" ]
24412441
2442+
2443+ @dc .dataclass (repr = False )
24422444class Function :
24432445 """
24442446 Mutable duck type for inspect.Function.
@@ -2450,49 +2452,34 @@ class Function:
24502452 It will always be true that
24512453 (not docstring) or ((not docstring[0].isspace()) and (docstring.rstrip() == docstring))
24522454 """
2455+ parameters : ParamDict = dc .field (default_factory = dict )
2456+ _ : dc .KW_ONLY
2457+ name : str
2458+ module : Module
2459+ cls : Class | None = None
2460+ c_basename : str | None = None
2461+ full_name : str | None = None
2462+ return_converter : CReturnConverter
2463+ return_annotation : object = inspect .Signature .empty
2464+ docstring : str = ''
2465+ kind : str = CALLABLE
2466+ coexist : bool = False
2467+ # docstring_only means "don't generate a machine-readable
2468+ # signature, just a normal docstring". it's True for
2469+ # functions with optional groups because we can't represent
2470+ # those accurately with inspect.Signature in 3.4.
2471+ docstring_only : bool = False
24532472
2454- def __init__ (
2455- self ,
2456- parameters : ParamDict | None = None ,
2457- * ,
2458- name : str ,
2459- module : Module ,
2460- cls : Class | None = None ,
2461- c_basename : str | None = None ,
2462- full_name : str | None = None ,
2463- return_converter : CReturnConverter ,
2464- return_annotation = inspect .Signature .empty ,
2465- docstring : str | None = None ,
2466- kind : str = CALLABLE ,
2467- coexist : bool = False ,
2468- docstring_only : bool = False
2469- ) -> None :
2470- self .parameters = parameters or {}
2471- self .return_annotation = return_annotation
2472- self .name = name
2473- self .full_name = full_name
2474- self .module = module
2475- self .cls = cls
2476- self .parent = cls or module
2477- self .c_basename = c_basename
2478- self .return_converter = return_converter
2479- self .docstring = docstring or ''
2480- self .kind = kind
2481- self .coexist = coexist
2473+ def __post_init__ (self ) -> None :
2474+ self .parent : Class | Module = self .cls or self .module
24822475 self .self_converter : self_converter | None = None
2483- # docstring_only means "don't generate a machine-readable
2484- # signature, just a normal docstring". it's True for
2485- # functions with optional groups because we can't represent
2486- # those accurately with inspect.Signature in 3.4.
2487- self .docstring_only = docstring_only
2488-
2489- self .rendered_parameters = None
2476+ self .__render_parameters__ : list [Parameter ] | None = None
24902477
2491- __render_parameters__ = None
24922478 @property
2493- def render_parameters (self ):
2479+ def render_parameters (self ) -> list [ Parameter ] :
24942480 if not self .__render_parameters__ :
2495- self .__render_parameters__ = l = []
2481+ l : list [Parameter ] = []
2482+ self .__render_parameters__ = l
24962483 for p in self .parameters .values ():
24972484 p = p .copy ()
24982485 p .converter .pre_render ()
@@ -2517,49 +2504,30 @@ def methoddef_flags(self) -> str | None:
25172504 def __repr__ (self ) -> str :
25182505 return '<clinic.Function ' + self .name + '>'
25192506
2520- def copy (self , ** overrides ) -> "Function" :
2521- kwargs = {
2522- 'name' : self .name , 'module' : self .module , 'parameters' : self .parameters ,
2523- 'cls' : self .cls , 'c_basename' : self .c_basename ,
2524- 'full_name' : self .full_name ,
2525- 'return_converter' : self .return_converter , 'return_annotation' : self .return_annotation ,
2526- 'docstring' : self .docstring , 'kind' : self .kind , 'coexist' : self .coexist ,
2527- 'docstring_only' : self .docstring_only ,
2528- }
2529- kwargs .update (overrides )
2530- f = Function (** kwargs )
2507+ def copy (self , ** overrides : Any ) -> Function :
2508+ f = dc .replace (self , ** overrides )
25312509 f .parameters = {
25322510 name : value .copy (function = f )
25332511 for name , value in f .parameters .items ()
25342512 }
25352513 return f
25362514
25372515
2516+ @dc .dataclass (repr = False , slots = True )
25382517class Parameter :
25392518 """
25402519 Mutable duck type of inspect.Parameter.
25412520 """
2542-
2543- def __init__ (
2544- self ,
2545- name : str ,
2546- kind : inspect ._ParameterKind ,
2547- * ,
2548- default = inspect .Parameter .empty ,
2549- function : Function ,
2550- converter : "CConverter" ,
2551- annotation = inspect .Parameter .empty ,
2552- docstring : str | None = None ,
2553- group : int = 0
2554- ) -> None :
2555- self .name = name
2556- self .kind = kind
2557- self .default = default
2558- self .function = function
2559- self .converter = converter
2560- self .annotation = annotation
2561- self .docstring = docstring or ''
2562- self .group = group
2521+ name : str
2522+ kind : inspect ._ParameterKind
2523+ _ : dc .KW_ONLY
2524+ default : object = inspect .Parameter .empty
2525+ function : Function
2526+ converter : CConverter
2527+ annotation : object = inspect .Parameter .empty
2528+ docstring : str = ''
2529+ group : int = 0
2530+ right_bracket_count : int = dc .field (init = False , default = 0 )
25632531
25642532 def __repr__ (self ) -> str :
25652533 return '<clinic.Parameter ' + self .name + '>'
@@ -2576,18 +2544,19 @@ def is_vararg(self) -> bool:
25762544 def is_optional (self ) -> bool :
25772545 return not self .is_vararg () and (self .default is not unspecified )
25782546
2579- def copy (self , ** overrides ) -> "Parameter" :
2580- kwargs = {
2581- 'name' : self .name , 'kind' : self .kind , 'default' :self .default ,
2582- 'function' : self .function , 'converter' : self .converter , 'annotation' : self .annotation ,
2583- 'docstring' : self .docstring , 'group' : self .group ,
2584- }
2585- kwargs .update (overrides )
2586- if 'converter' not in overrides :
2547+ def copy (
2548+ self ,
2549+ / ,
2550+ * ,
2551+ converter : CConverter | None = None ,
2552+ function : Function | None = None ,
2553+ ** overrides : Any
2554+ ) -> Parameter :
2555+ function = function or self .function
2556+ if not converter :
25872557 converter = copy .copy (self .converter )
2588- converter .function = kwargs ['function' ]
2589- kwargs ['converter' ] = converter
2590- return Parameter (** kwargs )
2558+ converter .function = function
2559+ return dc .replace (self , ** overrides , function = function , converter = converter )
25912560
25922561 def get_displayname (self , i : int ) -> str :
25932562 if i == 0 :
@@ -2761,7 +2730,7 @@ def __init__(self,
27612730 # Positional args:
27622731 name : str ,
27632732 py_name : str ,
2764- function ,
2733+ function : Function ,
27652734 default : object = unspecified ,
27662735 * , # Keyword only args:
27672736 c_default : str | None = None ,
@@ -2800,7 +2769,9 @@ def __init__(self,
28002769 # about the function in the init.
28012770 # (that breaks if we get cloned.)
28022771 # so after this change we will noisily fail.
2803- self .function = LandMine ("Don't access members of self.function inside converter_init!" )
2772+ self .function : Function | LandMine = LandMine (
2773+ "Don't access members of self.function inside converter_init!"
2774+ )
28042775 self .converter_init (** kwargs )
28052776 self .function = function
28062777
@@ -2810,7 +2781,7 @@ def converter_init(self):
28102781 def is_optional (self ) -> bool :
28112782 return (self .default is not unspecified )
28122783
2813- def _render_self (self , parameter : str , data : CRenderData ) -> None :
2784+ def _render_self (self , parameter : Parameter , data : CRenderData ) -> None :
28142785 self .parameter = parameter
28152786 name = self .parser_name
28162787
@@ -2870,7 +2841,7 @@ def _render_non_self(self, parameter, data):
28702841 if cleanup :
28712842 data .cleanup .append ('/* Cleanup for ' + name + ' */\n ' + cleanup .rstrip () + "\n " )
28722843
2873- def render (self , parameter : str , data : CRenderData ) -> None :
2844+ def render (self , parameter : Parameter , data : CRenderData ) -> None :
28742845 """
28752846 parameter is a clinic.Parameter instance.
28762847 data is a CRenderData instance.
@@ -5246,7 +5217,7 @@ def format_docstring(self):
52465217 assert isinstance (parameters [0 ].converter , self_converter )
52475218 # self is always positional-only.
52485219 assert parameters [0 ].is_positional_only ()
5249- parameters [0 ].right_bracket_count = 0
5220+ assert parameters [0 ].right_bracket_count = = 0
52505221 positional_only = True
52515222 for p in parameters [1 :]:
52525223 if not p .is_positional_only ():
0 commit comments