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) |