@@ -4595,6 +4595,7 @@ def reset(self) -> None:
4595
4595
self .indent = IndentStack ()
4596
4596
self .kind = CALLABLE
4597
4597
self .coexist = False
4598
+ self .forced_text_signature : str | None = None
4598
4599
self .parameter_continuation = ''
4599
4600
self .preserve_output = False
4600
4601
@@ -4735,6 +4736,11 @@ def at_coexist(self) -> None:
4735
4736
fail ("Called @coexist twice!" )
4736
4737
self .coexist = True
4737
4738
4739
+ def at_text_signature (self , text_signature : str ) -> None :
4740
+ if self .forced_text_signature :
4741
+ fail ("Called @text_signature twice!" )
4742
+ self .forced_text_signature = text_signature
4743
+
4738
4744
def parse (self , block : Block ) -> None :
4739
4745
self .reset ()
4740
4746
self .block = block
@@ -5515,142 +5521,145 @@ def format_docstring(self) -> str:
5515
5521
add (f .cls .name )
5516
5522
else :
5517
5523
add (f .name )
5518
- add ('(' )
5519
-
5520
- # populate "right_bracket_count" field for every parameter
5521
- assert parameters , "We should always have a self parameter. " + repr (f )
5522
- assert isinstance (parameters [0 ].converter , self_converter )
5523
- # self is always positional-only.
5524
- assert parameters [0 ].is_positional_only ()
5525
- assert parameters [0 ].right_bracket_count == 0
5526
- positional_only = True
5527
- for p in parameters [1 :]:
5528
- if not p .is_positional_only ():
5529
- positional_only = False
5530
- else :
5531
- assert positional_only
5532
- if positional_only :
5533
- p .right_bracket_count = abs (p .group )
5534
- else :
5535
- # don't put any right brackets around non-positional-only parameters, ever.
5536
- p .right_bracket_count = 0
5537
-
5538
- right_bracket_count = 0
5539
-
5540
- def fix_right_bracket_count (desired : int ) -> str :
5541
- nonlocal right_bracket_count
5542
- s = ''
5543
- while right_bracket_count < desired :
5544
- s += '['
5545
- right_bracket_count += 1
5546
- while right_bracket_count > desired :
5547
- s += ']'
5548
- right_bracket_count -= 1
5549
- return s
5550
-
5551
- need_slash = False
5552
- added_slash = False
5553
- need_a_trailing_slash = False
5554
-
5555
- # we only need a trailing slash:
5556
- # * if this is not a "docstring_only" signature
5557
- # * and if the last *shown* parameter is
5558
- # positional only
5559
- if not f .docstring_only :
5560
- for p in reversed (parameters ):
5561
- if not p .converter .show_in_signature :
5562
- continue
5563
- if p .is_positional_only ():
5564
- need_a_trailing_slash = True
5565
- break
5524
+ if self .forced_text_signature :
5525
+ add (self .forced_text_signature )
5526
+ else :
5527
+ add ('(' )
5528
+
5529
+ # populate "right_bracket_count" field for every parameter
5530
+ assert parameters , "We should always have a self parameter. " + repr (f )
5531
+ assert isinstance (parameters [0 ].converter , self_converter )
5532
+ # self is always positional-only.
5533
+ assert parameters [0 ].is_positional_only ()
5534
+ assert parameters [0 ].right_bracket_count == 0
5535
+ positional_only = True
5536
+ for p in parameters [1 :]:
5537
+ if not p .is_positional_only ():
5538
+ positional_only = False
5539
+ else :
5540
+ assert positional_only
5541
+ if positional_only :
5542
+ p .right_bracket_count = abs (p .group )
5543
+ else :
5544
+ # don't put any right brackets around non-positional-only parameters, ever.
5545
+ p .right_bracket_count = 0
5546
+
5547
+ right_bracket_count = 0
5548
+
5549
+ def fix_right_bracket_count (desired : int ) -> str :
5550
+ nonlocal right_bracket_count
5551
+ s = ''
5552
+ while right_bracket_count < desired :
5553
+ s += '['
5554
+ right_bracket_count += 1
5555
+ while right_bracket_count > desired :
5556
+ s += ']'
5557
+ right_bracket_count -= 1
5558
+ return s
5559
+
5560
+ need_slash = False
5561
+ added_slash = False
5562
+ need_a_trailing_slash = False
5563
+
5564
+ # we only need a trailing slash:
5565
+ # * if this is not a "docstring_only" signature
5566
+ # * and if the last *shown* parameter is
5567
+ # positional only
5568
+ if not f .docstring_only :
5569
+ for p in reversed (parameters ):
5570
+ if not p .converter .show_in_signature :
5571
+ continue
5572
+ if p .is_positional_only ():
5573
+ need_a_trailing_slash = True
5574
+ break
5566
5575
5567
5576
5568
- added_star = False
5577
+ added_star = False
5569
5578
5570
- first_parameter = True
5571
- last_p = parameters [- 1 ]
5572
- line_length = len ('' .join (text ))
5573
- indent = " " * line_length
5574
- def add_parameter (text : str ) -> None :
5575
- nonlocal line_length
5576
- nonlocal first_parameter
5577
- if first_parameter :
5578
- s = text
5579
- first_parameter = False
5580
- else :
5581
- s = ' ' + text
5582
- if line_length + len (s ) >= 72 :
5583
- add ('\n ' )
5584
- add (indent )
5585
- line_length = len (indent )
5579
+ first_parameter = True
5580
+ last_p = parameters [- 1 ]
5581
+ line_length = len ('' .join (text ))
5582
+ indent = " " * line_length
5583
+ def add_parameter (text : str ) -> None :
5584
+ nonlocal line_length
5585
+ nonlocal first_parameter
5586
+ if first_parameter :
5586
5587
s = text
5587
- line_length += len (s )
5588
- add (s )
5589
-
5590
- for p in parameters :
5591
- if not p .converter .show_in_signature :
5592
- continue
5593
- assert p .name
5588
+ first_parameter = False
5589
+ else :
5590
+ s = ' ' + text
5591
+ if line_length + len (s ) >= 72 :
5592
+ add ('\n ' )
5593
+ add (indent )
5594
+ line_length = len (indent )
5595
+ s = text
5596
+ line_length += len (s )
5597
+ add (s )
5598
+
5599
+ for p in parameters :
5600
+ if not p .converter .show_in_signature :
5601
+ continue
5602
+ assert p .name
5594
5603
5595
- is_self = isinstance (p .converter , self_converter )
5596
- if is_self and f .docstring_only :
5597
- # this isn't a real machine-parsable signature,
5598
- # so let's not print the "self" parameter
5599
- continue
5604
+ is_self = isinstance (p .converter , self_converter )
5605
+ if is_self and f .docstring_only :
5606
+ # this isn't a real machine-parsable signature,
5607
+ # so let's not print the "self" parameter
5608
+ continue
5600
5609
5601
- if p .is_positional_only ():
5602
- need_slash = not f .docstring_only
5603
- elif need_slash and not (added_slash or p .is_positional_only ()):
5604
- added_slash = True
5605
- add_parameter ('/,' )
5606
-
5607
- if p .is_keyword_only () and not added_star :
5608
- added_star = True
5609
- add_parameter ('*,' )
5610
-
5611
- p_add , p_output = text_accumulator ()
5612
- p_add (fix_right_bracket_count (p .right_bracket_count ))
5613
-
5614
- if isinstance (p .converter , self_converter ):
5615
- # annotate first parameter as being a "self".
5616
- #
5617
- # if inspect.Signature gets this function,
5618
- # and it's already bound, the self parameter
5619
- # will be stripped off.
5620
- #
5621
- # if it's not bound, it should be marked
5622
- # as positional-only.
5623
- #
5624
- # note: we don't print "self" for __init__,
5625
- # because this isn't actually the signature
5626
- # for __init__. (it can't be, __init__ doesn't
5627
- # have a docstring.) if this is an __init__
5628
- # (or __new__), then this signature is for
5629
- # calling the class to construct a new instance.
5630
- p_add ('$' )
5610
+ if p .is_positional_only ():
5611
+ need_slash = not f .docstring_only
5612
+ elif need_slash and not (added_slash or p .is_positional_only ()):
5613
+ added_slash = True
5614
+ add_parameter ('/,' )
5615
+
5616
+ if p .is_keyword_only () and not added_star :
5617
+ added_star = True
5618
+ add_parameter ('*,' )
5619
+
5620
+ p_add , p_output = text_accumulator ()
5621
+ p_add (fix_right_bracket_count (p .right_bracket_count ))
5622
+
5623
+ if isinstance (p .converter , self_converter ):
5624
+ # annotate first parameter as being a "self".
5625
+ #
5626
+ # if inspect.Signature gets this function,
5627
+ # and it's already bound, the self parameter
5628
+ # will be stripped off.
5629
+ #
5630
+ # if it's not bound, it should be marked
5631
+ # as positional-only.
5632
+ #
5633
+ # note: we don't print "self" for __init__,
5634
+ # because this isn't actually the signature
5635
+ # for __init__. (it can't be, __init__ doesn't
5636
+ # have a docstring.) if this is an __init__
5637
+ # (or __new__), then this signature is for
5638
+ # calling the class to construct a new instance.
5639
+ p_add ('$' )
5631
5640
5632
- if p .is_vararg ():
5633
- p_add ("*" )
5641
+ if p .is_vararg ():
5642
+ p_add ("*" )
5634
5643
5635
- name = p .converter .signature_name or p .name
5636
- p_add (name )
5644
+ name = p .converter .signature_name or p .name
5645
+ p_add (name )
5637
5646
5638
- if not p .is_vararg () and p .converter .is_optional ():
5639
- p_add ('=' )
5640
- value = p .converter .py_default
5641
- if not value :
5642
- value = repr (p .converter .default )
5643
- p_add (value )
5647
+ if not p .is_vararg () and p .converter .is_optional ():
5648
+ p_add ('=' )
5649
+ value = p .converter .py_default
5650
+ if not value :
5651
+ value = repr (p .converter .default )
5652
+ p_add (value )
5644
5653
5645
- if (p != last_p ) or need_a_trailing_slash :
5646
- p_add (',' )
5654
+ if (p != last_p ) or need_a_trailing_slash :
5655
+ p_add (',' )
5647
5656
5648
- add_parameter (p_output ())
5657
+ add_parameter (p_output ())
5649
5658
5650
- add (fix_right_bracket_count (0 ))
5651
- if need_a_trailing_slash :
5652
- add_parameter ('/' )
5653
- add (')' )
5659
+ add (fix_right_bracket_count (0 ))
5660
+ if need_a_trailing_slash :
5661
+ add_parameter ('/' )
5662
+ add (')' )
5654
5663
5655
5664
# PEP 8 says:
5656
5665
#
0 commit comments