##// END OF EJS Templates
typing: add type hints to mercurial/help.py...
Matt Harbison -
r50541:2a70d1fc default
parent child Browse files
Show More
@@ -10,6 +10,18 b' import itertools'
10 10 import re
11 11 import textwrap
12 12
13 from typing import (
14 Callable,
15 Dict,
16 Iterable,
17 List,
18 Optional,
19 Set,
20 Tuple,
21 Union,
22 cast,
23 )
24
13 25 from .i18n import (
14 26 _,
15 27 gettext,
@@ -40,7 +52,16 b' from .utils import ('
40 52 stringutil,
41 53 )
42 54
43 _exclkeywords = {
55 _DocLoader = Callable[[uimod.ui], bytes]
56 # Old extensions may not register with a category
57 _HelpEntry = Union["_HelpEntryNoCategory", "_HelpEntryWithCategory"]
58 _HelpEntryNoCategory = Tuple[List[bytes], bytes, _DocLoader]
59 _HelpEntryWithCategory = Tuple[List[bytes], bytes, _DocLoader, bytes]
60 _SelectFn = Callable[[object], bool]
61 _SynonymTable = Dict[bytes, List[bytes]]
62 _TopicHook = Callable[[uimod.ui, bytes, bytes], bytes]
63
64 _exclkeywords: Set[bytes] = {
44 65 b"(ADVANCED)",
45 66 b"(DEPRECATED)",
46 67 b"(EXPERIMENTAL)",
@@ -56,7 +77,7 b' from .utils import ('
56 77 # Extensions with custom categories should insert them into this list
57 78 # after/before the appropriate item, rather than replacing the list or
58 79 # assuming absolute positions.
59 CATEGORY_ORDER = [
80 CATEGORY_ORDER: List[bytes] = [
60 81 registrar.command.CATEGORY_REPO_CREATION,
61 82 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT,
62 83 registrar.command.CATEGORY_COMMITTING,
@@ -74,7 +95,7 b' CATEGORY_ORDER = ['
74 95
75 96 # Human-readable category names. These are translated.
76 97 # Extensions with custom categories should add their names here.
77 CATEGORY_NAMES = {
98 CATEGORY_NAMES: Dict[bytes, bytes] = {
78 99 registrar.command.CATEGORY_REPO_CREATION: b'Repository creation',
79 100 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT: b'Remote repository management',
80 101 registrar.command.CATEGORY_COMMITTING: b'Change creation',
@@ -102,7 +123,7 b" TOPIC_CATEGORY_NONE = b'none'"
102 123 # Extensions with custom categories should insert them into this list
103 124 # after/before the appropriate item, rather than replacing the list or
104 125 # assuming absolute positions.
105 TOPIC_CATEGORY_ORDER = [
126 TOPIC_CATEGORY_ORDER: List[bytes] = [
106 127 TOPIC_CATEGORY_IDS,
107 128 TOPIC_CATEGORY_OUTPUT,
108 129 TOPIC_CATEGORY_CONFIG,
@@ -112,7 +133,7 b' TOPIC_CATEGORY_ORDER = ['
112 133 ]
113 134
114 135 # Human-readable topic category names. These are translated.
115 TOPIC_CATEGORY_NAMES = {
136 TOPIC_CATEGORY_NAMES: Dict[bytes, bytes] = {
116 137 TOPIC_CATEGORY_IDS: b'Mercurial identifiers',
117 138 TOPIC_CATEGORY_OUTPUT: b'Mercurial output',
118 139 TOPIC_CATEGORY_CONFIG: b'Mercurial configuration',
@@ -122,7 +143,12 b' TOPIC_CATEGORY_NAMES = {'
122 143 }
123 144
124 145
125 def listexts(header, exts, indent=1, showdeprecated=False):
146 def listexts(
147 header: bytes,
148 exts: Dict[bytes, bytes],
149 indent: int = 1,
150 showdeprecated: bool = False,
151 ) -> List[bytes]:
126 152 '''return a text listing of the given extensions'''
127 153 rst = []
128 154 if exts:
@@ -135,7 +161,7 b' def listexts(header, exts, indent=1, sho'
135 161 return rst
136 162
137 163
138 def extshelp(ui):
164 def extshelp(ui: uimod.ui) -> bytes:
139 165 rst = loaddoc(b'extensions')(ui).splitlines(True)
140 166 rst.extend(
141 167 listexts(
@@ -153,7 +179,7 b' def extshelp(ui):'
153 179 return doc
154 180
155 181
156 def parsedefaultmarker(text):
182 def parsedefaultmarker(text: bytes) -> Optional[Tuple[bytes, List[bytes]]]:
157 183 """given a text 'abc (DEFAULT: def.ghi)',
158 184 returns (b'abc', (b'def', b'ghi')). Otherwise return None"""
159 185 if text[-1:] == b')':
@@ -164,7 +190,7 b' def parsedefaultmarker(text):'
164 190 return text[:pos], item.split(b'.', 2)
165 191
166 192
167 def optrst(header, options, verbose, ui):
193 def optrst(header: bytes, options, verbose: bool, ui: uimod.ui) -> bytes:
168 194 data = []
169 195 multioccur = False
170 196 for option in options:
@@ -220,13 +246,15 b' def optrst(header, options, verbose, ui)'
220 246 return b''.join(rst)
221 247
222 248
223 def indicateomitted(rst, omitted, notomitted=None):
249 def indicateomitted(
250 rst: List[bytes], omitted: bytes, notomitted: Optional[bytes] = None
251 ) -> None:
224 252 rst.append(b'\n\n.. container:: omitted\n\n %s\n\n' % omitted)
225 253 if notomitted:
226 254 rst.append(b'\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
227 255
228 256
229 def filtercmd(ui, cmd, func, kw, doc):
257 def filtercmd(ui: uimod.ui, cmd: bytes, func, kw: bytes, doc: bytes) -> bool:
230 258 if not ui.debugflag and cmd.startswith(b"debug") and kw != b"debug":
231 259 # Debug command, and user is not looking for those.
232 260 return True
@@ -249,11 +277,13 b' def filtercmd(ui, cmd, func, kw, doc):'
249 277 return False
250 278
251 279
252 def filtertopic(ui, topic):
280 def filtertopic(ui: uimod.ui, topic: bytes) -> bool:
253 281 return ui.configbool(b'help', b'hidden-topic.%s' % topic, False)
254 282
255 283
256 def topicmatch(ui, commands, kw):
284 def topicmatch(
285 ui: uimod.ui, commands, kw: bytes
286 ) -> Dict[bytes, List[Tuple[bytes, bytes]]]:
257 287 """Return help topics matching kw.
258 288
259 289 Returns {'section': [(name, summary), ...], ...} where section is
@@ -326,10 +356,10 b' def topicmatch(ui, commands, kw):'
326 356 return results
327 357
328 358
329 def loaddoc(topic, subdir=None):
359 def loaddoc(topic: bytes, subdir: Optional[bytes] = None) -> _DocLoader:
330 360 """Return a delayed loader for help/topic.txt."""
331 361
332 def loader(ui):
362 def loader(ui: uimod.ui) -> bytes:
333 363 package = b'mercurial.helptext'
334 364 if subdir:
335 365 package += b'.' + subdir
@@ -342,7 +372,7 b' def loaddoc(topic, subdir=None):'
342 372 return loader
343 373
344 374
345 internalstable = sorted(
375 internalstable: List[_HelpEntryNoCategory] = sorted(
346 376 [
347 377 (
348 378 [b'bid-merge'],
@@ -407,7 +437,7 b' internalstable = sorted('
407 437 )
408 438
409 439
410 def internalshelp(ui):
440 def internalshelp(ui: uimod.ui) -> bytes:
411 441 """Generate the index for the "internals" topic."""
412 442 lines = [
413 443 b'To access a subtopic, use "hg help internals.{subtopic-name}"\n',
@@ -419,7 +449,7 b' def internalshelp(ui):'
419 449 return b''.join(lines)
420 450
421 451
422 helptable = sorted(
452 helptable: List[_HelpEntryWithCategory] = sorted(
423 453 [
424 454 (
425 455 [b'bundlespec'],
@@ -581,20 +611,27 b' helptable = sorted('
581 611 )
582 612
583 613 # Maps topics with sub-topics to a list of their sub-topics.
584 subtopics = {
614 subtopics: Dict[bytes, List[_HelpEntryNoCategory]] = {
585 615 b'internals': internalstable,
586 616 }
587 617
588 618 # Map topics to lists of callable taking the current topic help and
589 619 # returning the updated version
590 helphooks = {}
620 helphooks: Dict[bytes, List[_TopicHook]] = {}
591 621
592 622
593 def addtopichook(topic, rewriter):
623 def addtopichook(topic: bytes, rewriter: _TopicHook) -> None:
594 624 helphooks.setdefault(topic, []).append(rewriter)
595 625
596 626
597 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False):
627 def makeitemsdoc(
628 ui: uimod.ui,
629 topic: bytes,
630 doc: bytes,
631 marker: bytes,
632 items: Dict[bytes, bytes],
633 dedent: bool = False,
634 ) -> bytes:
598 635 """Extract docstring from the items key to function mapping, build a
599 636 single documentation block and use it to overwrite the marker in doc.
600 637 """
@@ -622,8 +659,10 b' def makeitemsdoc(ui, topic, doc, marker,'
622 659 return doc.replace(marker, entries)
623 660
624 661
625 def addtopicsymbols(topic, marker, symbols, dedent=False):
626 def add(ui, topic, doc):
662 def addtopicsymbols(
663 topic: bytes, marker: bytes, symbols, dedent: bool = False
664 ) -> None:
665 def add(ui: uimod.ui, topic: bytes, doc: bytes):
627 666 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent)
628 667
629 668 addtopichook(topic, add)
@@ -647,7 +686,7 b' addtopicsymbols('
647 686 )
648 687
649 688
650 def inserttweakrc(ui, topic, doc):
689 def inserttweakrc(ui: uimod.ui, topic: bytes, doc: bytes) -> bytes:
651 690 marker = b'.. tweakdefaultsmarker'
652 691 repl = uimod.tweakrc
653 692
@@ -658,7 +697,9 b' def inserttweakrc(ui, topic, doc):'
658 697 return re.sub(br'( *)%s' % re.escape(marker), sub, doc)
659 698
660 699
661 def _getcategorizedhelpcmds(ui, cmdtable, name, select=None):
700 def _getcategorizedhelpcmds(
701 ui: uimod.ui, cmdtable, name: bytes, select: Optional[_SelectFn] = None
702 ) -> Tuple[Dict[bytes, List[bytes]], Dict[bytes, bytes], _SynonymTable]:
662 703 # Category -> list of commands
663 704 cats = {}
664 705 # Command -> short description
@@ -687,16 +728,18 b' def _getcategorizedhelpcmds(ui, cmdtable'
687 728 return cats, h, syns
688 729
689 730
690 def _getcategorizedhelptopics(ui, topictable):
731 def _getcategorizedhelptopics(
732 ui: uimod.ui, topictable: List[_HelpEntry]
733 ) -> Tuple[Dict[bytes, List[Tuple[bytes, bytes]]], Dict[bytes, List[bytes]]]:
691 734 # Group commands by category.
692 735 topiccats = {}
693 736 syns = {}
694 737 for topic in topictable:
695 738 names, header, doc = topic[0:3]
696 739 if len(topic) > 3 and topic[3]:
697 category = topic[3]
740 category: bytes = cast(bytes, topic[3]) # help pytype
698 741 else:
699 category = TOPIC_CATEGORY_NONE
742 category: bytes = TOPIC_CATEGORY_NONE
700 743
701 744 topicname = names[0]
702 745 syns[topicname] = list(names)
@@ -709,15 +752,15 b" addtopichook(b'config', inserttweakrc)"
709 752
710 753
711 754 def help_(
712 ui,
755 ui: uimod.ui,
713 756 commands,
714 name,
715 unknowncmd=False,
716 full=True,
717 subtopic=None,
718 fullname=None,
757 name: bytes,
758 unknowncmd: bool = False,
759 full: bool = True,
760 subtopic: Optional[bytes] = None,
761 fullname: Optional[bytes] = None,
719 762 **opts
720 ):
763 ) -> bytes:
721 764 """
722 765 Generate the help for 'name' as unformatted restructured text. If
723 766 'name' is None, describe the commands available.
@@ -725,7 +768,7 b' def help_('
725 768
726 769 opts = pycompat.byteskwargs(opts)
727 770
728 def helpcmd(name, subtopic=None):
771 def helpcmd(name: bytes, subtopic: Optional[bytes]) -> List[bytes]:
729 772 try:
730 773 aliases, entry = cmdutil.findcmd(
731 774 name, commands.table, strict=unknowncmd
@@ -826,7 +869,7 b' def help_('
826 869
827 870 return rst
828 871
829 def helplist(select=None, **opts):
872 def helplist(select: Optional[_SelectFn] = None, **opts) -> List[bytes]:
830 873 cats, h, syns = _getcategorizedhelpcmds(
831 874 ui, commands.table, name, select
832 875 )
@@ -846,7 +889,7 b' def help_('
846 889 else:
847 890 rst.append(_(b'list of commands:\n'))
848 891
849 def appendcmds(cmds):
892 def appendcmds(cmds: Iterable[bytes]) -> None:
850 893 cmds = sorted(cmds)
851 894 for c in cmds:
852 895 display_cmd = c
@@ -955,7 +998,7 b' def help_('
955 998 )
956 999 return rst
957 1000
958 def helptopic(name, subtopic=None):
1001 def helptopic(name: bytes, subtopic: Optional[bytes] = None) -> List[bytes]:
959 1002 # Look for sub-topic entry first.
960 1003 header, doc = None, None
961 1004 if subtopic and name in subtopics:
@@ -998,7 +1041,7 b' def help_('
998 1041 pass
999 1042 return rst
1000 1043
1001 def helpext(name, subtopic=None):
1044 def helpext(name: bytes, subtopic: Optional[bytes] = None) -> List[bytes]:
1002 1045 try:
1003 1046 mod = extensions.find(name)
1004 1047 doc = gettext(pycompat.getdoc(mod)) or _(b'no help text available')
@@ -1040,7 +1083,9 b' def help_('
1040 1083 )
1041 1084 return rst
1042 1085
1043 def helpextcmd(name, subtopic=None):
1086 def helpextcmd(
1087 name: bytes, subtopic: Optional[bytes] = None
1088 ) -> List[bytes]:
1044 1089 cmd, ext, doc = extensions.disabledcmd(
1045 1090 ui, name, ui.configbool(b'ui', b'strict')
1046 1091 )
@@ -1127,8 +1172,14 b' def help_('
1127 1172
1128 1173
1129 1174 def formattedhelp(
1130 ui, commands, fullname, keep=None, unknowncmd=False, full=True, **opts
1131 ):
1175 ui: uimod.ui,
1176 commands,
1177 fullname: Optional[bytes],
1178 keep: Optional[Iterable[bytes]] = None,
1179 unknowncmd: bool = False,
1180 full: bool = True,
1181 **opts
1182 ) -> bytes:
1132 1183 """get help for a given topic (as a dotted name) as rendered rst
1133 1184
1134 1185 Either returns the rendered help text or raises an exception.
General Comments 0
You need to be logged in to leave comments. Login now