##// END OF EJS Templates
typing: add typehints to mercurial/diffutil.py...
Matt Harbison -
r51142:b8cac4e3 stable
parent child Browse files
Show More
@@ -1,135 +1,157 b''
1 # diffutil.py - utility functions related to diff and patch
1 # diffutil.py - utility functions related to diff and patch
2 #
2 #
3 # Copyright 2006 Brendan Cully <brendan@kublai.com>
3 # Copyright 2006 Brendan Cully <brendan@kublai.com>
4 # Copyright 2007 Chris Mason <chris.mason@oracle.com>
4 # Copyright 2007 Chris Mason <chris.mason@oracle.com>
5 # Copyright 2018 Octobus <octobus@octobus.net>
5 # Copyright 2018 Octobus <octobus@octobus.net>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 import typing
11
12 from typing import (
13 Any,
14 Dict,
15 Optional,
16 )
10
17
11 from .i18n import _
18 from .i18n import _
12
19
13 from . import (
20 from . import (
14 mdiff,
21 mdiff,
15 pycompat,
22 pycompat,
16 )
23 )
17
24
25 if typing.TYPE_CHECKING:
26 from . import ui as uimod
27
28 # TODO: narrow the value after the config module is typed
29 _Opts = Dict[bytes, Any]
30
18
31
19 def diffallopts(
32 def diffallopts(
20 ui, opts=None, untrusted=False, section=b'diff', configprefix=b''
33 ui: "uimod.ui",
21 ):
34 opts: Optional[_Opts] = None,
35 untrusted: bool = False,
36 section: bytes = b'diff',
37 configprefix: bytes = b'',
38 ) -> mdiff.diffopts:
22 '''return diffopts with all features supported and parsed'''
39 '''return diffopts with all features supported and parsed'''
23 return difffeatureopts(
40 return difffeatureopts(
24 ui,
41 ui,
25 opts=opts,
42 opts=opts,
26 untrusted=untrusted,
43 untrusted=untrusted,
27 section=section,
44 section=section,
28 git=True,
45 git=True,
29 whitespace=True,
46 whitespace=True,
30 formatchanging=True,
47 formatchanging=True,
31 configprefix=configprefix,
48 configprefix=configprefix,
32 )
49 )
33
50
34
51
35 def difffeatureopts(
52 def difffeatureopts(
36 ui,
53 ui: "uimod.ui",
37 opts=None,
54 opts: Optional[_Opts] = None,
38 untrusted=False,
55 untrusted: bool = False,
39 section=b'diff',
56 section: bytes = b'diff',
40 git=False,
57 git: bool = False,
41 whitespace=False,
58 whitespace: bool = False,
42 formatchanging=False,
59 formatchanging: bool = False,
43 configprefix=b'',
60 configprefix: bytes = b'',
44 ):
61 ) -> mdiff.diffopts:
45 """return diffopts with only opted-in features parsed
62 """return diffopts with only opted-in features parsed
46
63
47 Features:
64 Features:
48 - git: git-style diffs
65 - git: git-style diffs
49 - whitespace: whitespace options like ignoreblanklines and ignorews
66 - whitespace: whitespace options like ignoreblanklines and ignorews
50 - formatchanging: options that will likely break or cause correctness issues
67 - formatchanging: options that will likely break or cause correctness issues
51 with most diff parsers
68 with most diff parsers
52 """
69 """
53
70
54 def get(key, name=None, getter=ui.configbool, forceplain=None):
71 def get(
72 key: bytes,
73 name: Optional[bytes] = None,
74 getter=ui.configbool,
75 forceplain: Optional[bool] = None,
76 ) -> Any:
55 if opts:
77 if opts:
56 v = opts.get(key)
78 v = opts.get(key)
57 # diffopts flags are either None-default (which is passed
79 # diffopts flags are either None-default (which is passed
58 # through unchanged, so we can identify unset values), or
80 # through unchanged, so we can identify unset values), or
59 # some other falsey default (eg --unified, which defaults
81 # some other falsey default (eg --unified, which defaults
60 # to an empty string). We only want to override the config
82 # to an empty string). We only want to override the config
61 # entries from hgrc with command line values if they
83 # entries from hgrc with command line values if they
62 # appear to have been set, which is any truthy value,
84 # appear to have been set, which is any truthy value,
63 # True, or False.
85 # True, or False.
64 if v or isinstance(v, bool):
86 if v or isinstance(v, bool):
65 return v
87 return v
66 if forceplain is not None and ui.plain():
88 if forceplain is not None and ui.plain():
67 return forceplain
89 return forceplain
68 return getter(
90 return getter(
69 section, configprefix + (name or key), untrusted=untrusted
91 section, configprefix + (name or key), untrusted=untrusted
70 )
92 )
71
93
72 # core options, expected to be understood by every diff parser
94 # core options, expected to be understood by every diff parser
73 buildopts = {
95 buildopts = {
74 b'nodates': get(b'nodates'),
96 b'nodates': get(b'nodates'),
75 b'showfunc': get(b'show_function', b'showfunc'),
97 b'showfunc': get(b'show_function', b'showfunc'),
76 b'context': get(b'unified', getter=ui.config),
98 b'context': get(b'unified', getter=ui.config),
77 }
99 }
78 buildopts[b'xdiff'] = ui.configbool(b'experimental', b'xdiff')
100 buildopts[b'xdiff'] = ui.configbool(b'experimental', b'xdiff')
79
101
80 if git:
102 if git:
81 buildopts[b'git'] = get(b'git')
103 buildopts[b'git'] = get(b'git')
82
104
83 # since this is in the experimental section, we need to call
105 # since this is in the experimental section, we need to call
84 # ui.configbool directory
106 # ui.configbool directory
85 buildopts[b'showsimilarity'] = ui.configbool(
107 buildopts[b'showsimilarity'] = ui.configbool(
86 b'experimental', b'extendedheader.similarity'
108 b'experimental', b'extendedheader.similarity'
87 )
109 )
88
110
89 # need to inspect the ui object instead of using get() since we want to
111 # need to inspect the ui object instead of using get() since we want to
90 # test for an int
112 # test for an int
91 hconf = ui.config(b'experimental', b'extendedheader.index')
113 hconf = ui.config(b'experimental', b'extendedheader.index')
92 if hconf is not None:
114 if hconf is not None:
93 hlen = None
115 hlen = None
94 try:
116 try:
95 # the hash config could be an integer (for length of hash) or a
117 # the hash config could be an integer (for length of hash) or a
96 # word (e.g. short, full, none)
118 # word (e.g. short, full, none)
97 hlen = int(hconf)
119 hlen = int(hconf)
98 if hlen < 0 or hlen > 40:
120 if hlen < 0 or hlen > 40:
99 msg = _(b"invalid length for extendedheader.index: '%d'\n")
121 msg = _(b"invalid length for extendedheader.index: '%d'\n")
100 ui.warn(msg % hlen)
122 ui.warn(msg % hlen)
101 except ValueError:
123 except ValueError:
102 # default value
124 # default value
103 if hconf == b'short' or hconf == b'':
125 if hconf == b'short' or hconf == b'':
104 hlen = 12
126 hlen = 12
105 elif hconf == b'full':
127 elif hconf == b'full':
106 hlen = 40
128 hlen = 40
107 elif hconf != b'none':
129 elif hconf != b'none':
108 msg = _(b"invalid value for extendedheader.index: '%s'\n")
130 msg = _(b"invalid value for extendedheader.index: '%s'\n")
109 ui.warn(msg % hconf)
131 ui.warn(msg % hconf)
110 finally:
132 finally:
111 buildopts[b'index'] = hlen
133 buildopts[b'index'] = hlen
112
134
113 if whitespace:
135 if whitespace:
114 buildopts[b'ignorews'] = get(b'ignore_all_space', b'ignorews')
136 buildopts[b'ignorews'] = get(b'ignore_all_space', b'ignorews')
115 buildopts[b'ignorewsamount'] = get(
137 buildopts[b'ignorewsamount'] = get(
116 b'ignore_space_change', b'ignorewsamount'
138 b'ignore_space_change', b'ignorewsamount'
117 )
139 )
118 buildopts[b'ignoreblanklines'] = get(
140 buildopts[b'ignoreblanklines'] = get(
119 b'ignore_blank_lines', b'ignoreblanklines'
141 b'ignore_blank_lines', b'ignoreblanklines'
120 )
142 )
121 buildopts[b'ignorewseol'] = get(b'ignore_space_at_eol', b'ignorewseol')
143 buildopts[b'ignorewseol'] = get(b'ignore_space_at_eol', b'ignorewseol')
122 if formatchanging:
144 if formatchanging:
123 buildopts[b'text'] = opts and opts.get(b'text')
145 buildopts[b'text'] = opts and opts.get(b'text')
124 binary = None if opts is None else opts.get(b'binary')
146 binary = None if opts is None else opts.get(b'binary')
125 buildopts[b'nobinary'] = (
147 buildopts[b'nobinary'] = (
126 not binary
148 not binary
127 if binary is not None
149 if binary is not None
128 else get(b'nobinary', forceplain=False)
150 else get(b'nobinary', forceplain=False)
129 )
151 )
130 buildopts[b'noprefix'] = get(b'noprefix', forceplain=False)
152 buildopts[b'noprefix'] = get(b'noprefix', forceplain=False)
131 buildopts[b'worddiff'] = get(
153 buildopts[b'worddiff'] = get(
132 b'word_diff', b'word-diff', forceplain=False
154 b'word_diff', b'word-diff', forceplain=False
133 )
155 )
134
156
135 return mdiff.diffopts(**pycompat.strkwargs(buildopts))
157 return mdiff.diffopts(**pycompat.strkwargs(buildopts))
General Comments 0
You need to be logged in to leave comments. Login now