Mercurial > public > mercurial-scm > hg
comparison mercurial/extensions.py @ 36269:4088e568a411
extensions: reject any unicode strings in tables before loading
This allows us to test hg on Python 3 without disabling third-party
extensions which could pollute cmdtable for example.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 17 Feb 2018 17:24:29 +0900 |
parents | 646002338365 |
children | 521f6c7e1756 |
comparison
equal
deleted
inserted
replaced
36268:be5a6fe3643a | 36269:4088e568a411 |
---|---|
120 ui.debug('could not import %s (%s): trying %s\n' | 120 ui.debug('could not import %s (%s): trying %s\n' |
121 % (failed, util.forcebytestr(err), next)) | 121 % (failed, util.forcebytestr(err), next)) |
122 if ui.debugflag: | 122 if ui.debugflag: |
123 ui.traceback() | 123 ui.traceback() |
124 | 124 |
125 def _rejectunicode(name, xs): | |
126 if isinstance(xs, (list, set, tuple)): | |
127 for x in xs: | |
128 _rejectunicode(name, x) | |
129 elif isinstance(xs, dict): | |
130 for k, v in xs.items(): | |
131 _rejectunicode(name, k) | |
132 _rejectunicode(b'%s.%s' % (name, util.forcebytestr(k)), v) | |
133 elif isinstance(xs, type(u'')): | |
134 raise error.ProgrammingError(b"unicode %r found in %s" % (xs, name), | |
135 hint="use b'' to make it byte string") | |
136 | |
125 # attributes set by registrar.command | 137 # attributes set by registrar.command |
126 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo') | 138 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo') |
127 | 139 |
128 def _validatecmdtable(ui, cmdtable): | 140 def _validatecmdtable(ui, cmdtable): |
129 """Check if extension commands have required attributes""" | 141 """Check if extension commands have required attributes""" |
132 if getattr(f, '_deprecatedregistrar', False): | 144 if getattr(f, '_deprecatedregistrar', False): |
133 ui.deprecwarn("cmdutil.command is deprecated, use " | 145 ui.deprecwarn("cmdutil.command is deprecated, use " |
134 "registrar.command to register '%s'" % c, '4.6') | 146 "registrar.command to register '%s'" % c, '4.6') |
135 missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)] | 147 missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)] |
136 if not missing: | 148 if not missing: |
137 for option in e[1]: | |
138 default = option[2] | |
139 if isinstance(default, type(u'')): | |
140 raise error.ProgrammingError( | |
141 "option '%s.%s' has a unicode default value" | |
142 % (c, option[1]), | |
143 hint=("change the %s.%s default value to a " | |
144 "non-unicode string" % (c, option[1]))) | |
145 continue | 149 continue |
146 raise error.ProgrammingError( | 150 raise error.ProgrammingError( |
147 'missing attributes: %s' % ', '.join(missing), | 151 'missing attributes: %s' % ', '.join(missing), |
148 hint="use @command decorator to register '%s'" % c) | 152 hint="use @command decorator to register '%s'" % c) |
153 | |
154 def _validatetables(ui, mod): | |
155 """Sanity check for loadable tables provided by extension module""" | |
156 for t in ['cmdtable', 'colortable', 'configtable']: | |
157 _rejectunicode(t, getattr(mod, t, {})) | |
158 for t in ['filesetpredicate', 'internalmerge', 'revsetpredicate', | |
159 'templatefilter', 'templatefunc', 'templatekeyword']: | |
160 o = getattr(mod, t, None) | |
161 if o: | |
162 _rejectunicode(t, o._table) | |
163 _validatecmdtable(ui, getattr(mod, 'cmdtable', {})) | |
149 | 164 |
150 def load(ui, name, path): | 165 def load(ui, name, path): |
151 if name.startswith('hgext.') or name.startswith('hgext/'): | 166 if name.startswith('hgext.') or name.startswith('hgext/'): |
152 shortname = name[6:] | 167 shortname = name[6:] |
153 else: | 168 else: |
166 minver = getattr(mod, 'minimumhgversion', None) | 181 minver = getattr(mod, 'minimumhgversion', None) |
167 if minver and util.versiontuple(minver, 2) > util.versiontuple(n=2): | 182 if minver and util.versiontuple(minver, 2) > util.versiontuple(n=2): |
168 ui.warn(_('(third party extension %s requires version %s or newer ' | 183 ui.warn(_('(third party extension %s requires version %s or newer ' |
169 'of Mercurial; disabling)\n') % (shortname, minver)) | 184 'of Mercurial; disabling)\n') % (shortname, minver)) |
170 return | 185 return |
171 _validatecmdtable(ui, getattr(mod, 'cmdtable', {})) | 186 _validatetables(ui, mod) |
172 | 187 |
173 _extensions[shortname] = mod | 188 _extensions[shortname] = mod |
174 _order.append(shortname) | 189 _order.append(shortname) |
175 for fn in _aftercallbacks.get(shortname, []): | 190 for fn in _aftercallbacks.get(shortname, []): |
176 fn(loaded=True) | 191 fn(loaded=True) |