163 hint=b"use b'' to make it byte string", |
163 hint=b"use b'' to make it byte string", |
164 ) |
164 ) |
165 |
165 |
166 |
166 |
167 # attributes set by registrar.command |
167 # attributes set by registrar.command |
168 _cmdfuncattrs = (b'norepo', b'optionalrepo', b'inferrepo') |
168 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo') |
169 |
169 |
170 |
170 |
171 def _validatecmdtable(ui, cmdtable): |
171 def _validatecmdtable(ui, cmdtable): |
172 """Check if extension commands have required attributes""" |
172 """Check if extension commands have required attributes""" |
173 for c, e in cmdtable.items(): |
173 for c, e in cmdtable.items(): |
174 f = e[0] |
174 f = e[0] |
175 missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)] |
175 missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)] |
176 if not missing: |
176 if not missing: |
177 continue |
177 continue |
178 raise error.ProgrammingError( |
178 msg = b'missing attributes: %s' |
179 b'missing attributes: %s' % b', '.join(missing), |
179 msg %= b', '.join([stringutil.forcebytestr(m) for m in missing]) |
180 hint=b"use @command decorator to register '%s'" % c, |
180 hint = b"use @command decorator to register '%s'" % c |
181 ) |
181 raise error.ProgrammingError(msg, hint=hint) |
182 |
182 |
183 |
183 |
184 def _validatetables(ui, mod): |
184 def _validatetables(ui, mod): |
185 """Sanity check for loadable tables provided by extension module""" |
185 """Sanity check for loadable tables provided by extension module""" |
186 for t in ['cmdtable', 'colortable', 'configtable']: |
186 for t in ['cmdtable', 'colortable', 'configtable']: |