There is nothing specific about expressions in this exception, the following patch will use it without expressions.
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- scripts/qapi.py | 146 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 21bc32f..4d1b0e4 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -110,11 +110,11 @@ class QAPISchemaError(Exception): "%s:%d:%d: %s" % (self.fname, self.line, self.col, self.msg) -class QAPIExprError(Exception): - def __init__(self, expr_info, msg): +class QAPILineError(Exception): + def __init__(self, info, msg): Exception.__init__(self) - assert expr_info - self.info = expr_info + assert info + self.info = info self.msg = msg def __str__(self): @@ -140,24 +140,24 @@ class QAPISchemaParser(object): self.accept() while self.tok is not None: - expr_info = {'file': fname, 'line': self.line, - 'parent': self.incl_info} + info = {'file': fname, 'line': self.line, + 'parent': self.incl_info} expr = self.get_expr(False) if isinstance(expr, dict) and "include" in expr: if len(expr) != 1: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Invalid 'include' directive") include = expr["include"] if not isinstance(include, str): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Value of 'include' must be a string") incl_abs_fname = os.path.join(os.path.dirname(abs_fname), include) # catch inclusion cycle - inf = expr_info + inf = info while inf: if incl_abs_fname == os.path.abspath(inf['file']): - raise QAPIExprError(expr_info, "Inclusion loop for %s" + raise QAPILineError(info, "Inclusion loop for %s" % include) inf = inf['parent'] # skip multiple include of the same file @@ -166,14 +166,14 @@ class QAPISchemaParser(object): try: fobj = open(incl_abs_fname, 'r') except IOError as e: - raise QAPIExprError(expr_info, + raise QAPILineError(info, '%s: %s' % (e.strerror, include)) exprs_include = QAPISchemaParser(fobj, previously_included, - expr_info) + info) self.exprs.extend(exprs_include.exprs) else: expr_elem = {'expr': expr, - 'info': expr_info} + 'info': info} self.exprs.append(expr_elem) def accept(self): @@ -375,18 +375,18 @@ valid_name = re.compile('^(__[a-zA-Z0-9.-]+_)?' '[a-zA-Z][a-zA-Z0-9_-]*$') -def check_name(expr_info, source, name, allow_optional=False, +def check_name(info, source, name, allow_optional=False, enum_member=False): global valid_name membername = name if not isinstance(name, str): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s requires a string name" % source) if name.startswith('*'): membername = name[1:] if not allow_optional: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s does not allow optional name '%s'" % (source, name)) # Enum members can start with a digit, because the generated C @@ -397,7 +397,7 @@ def check_name(expr_info, source, name, allow_optional=False, # and 'q_obj_*' implicit type names. if not valid_name.match(membername) or \ c_name(membername, False).startswith('q_'): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s uses invalid name '%s'" % (source, name)) @@ -407,11 +407,11 @@ def add_name(name, info, meta, implicit=False): # FIXME should reject names that differ only in '_' vs. '.' # vs. '-', because they're liable to clash in generated C. if name in all_names: - raise QAPIExprError(info, + raise QAPILineError(info, "%s '%s' is already defined" % (all_names[name], name)) if not implicit and (name.endswith('Kind') or name.endswith('List')): - raise QAPIExprError(info, + raise QAPILineError(info, "%s '%s' should not end in '%s'" % (meta, name, name[-4:])) all_names[name] = meta @@ -465,7 +465,7 @@ def is_enum(name): return find_enum(name) is not None -def check_type(expr_info, source, value, allow_array=False, +def check_type(info, source, value, allow_array=False, allow_dict=False, allow_optional=False, allow_metas=[]): global all_names @@ -476,10 +476,10 @@ def check_type(expr_info, source, value, allow_array=False, # Check if array type for value is okay if isinstance(value, list): if not allow_array: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s cannot be an array" % source) if len(value) != 1 or not isinstance(value[0], str): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s: array type must contain single type name" % source) value = value[0] @@ -487,58 +487,58 @@ def check_type(expr_info, source, value, allow_array=False, # Check if type name for value is okay if isinstance(value, str): if value not in all_names: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s uses unknown type '%s'" % (source, value)) if not all_names[value] in allow_metas: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s cannot use %s type '%s'" % (source, all_names[value], value)) return if not allow_dict: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s should be a type name" % source) if not isinstance(value, OrderedDict): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "%s should be a dictionary or type name" % source) # value is a dictionary, check that each member is okay for (key, arg) in value.items(): - check_name(expr_info, "Member of %s" % source, key, + check_name(info, "Member of %s" % source, key, allow_optional=allow_optional) if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Member of %s uses reserved name '%s'" % (source, key)) # Todo: allow dictionaries to represent default values of # an optional argument. - check_type(expr_info, "Member '%s' of %s" % (key, source), arg, + check_type(info, "Member '%s' of %s" % (key, source), arg, allow_array=True, allow_metas=['built-in', 'union', 'alternate', 'struct', 'enum']) -def check_command(expr, expr_info): +def check_command(expr, info): name = expr['command'] boxed = expr.get('boxed', False) args_meta = ['struct'] if boxed: args_meta += ['union', 'alternate'] - check_type(expr_info, "'data' for command '%s'" % name, + check_type(info, "'data' for command '%s'" % name, expr.get('data'), allow_dict=not boxed, allow_optional=True, allow_metas=args_meta) returns_meta = ['union', 'struct'] if name in returns_whitelist: returns_meta += ['built-in', 'alternate', 'enum'] - check_type(expr_info, "'returns' for command '%s'" % name, + check_type(info, "'returns' for command '%s'" % name, expr.get('returns'), allow_array=True, allow_optional=True, allow_metas=returns_meta) -def check_event(expr, expr_info): +def check_event(expr, info): global events name = expr['event'] boxed = expr.get('boxed', False) @@ -547,12 +547,12 @@ def check_event(expr, expr_info): if boxed: meta += ['union', 'alternate'] events.append(name) - check_type(expr_info, "'data' for event '%s'" % name, + check_type(info, "'data' for event '%s'" % name, expr.get('data'), allow_dict=not boxed, allow_optional=True, allow_metas=meta) -def check_union(expr, expr_info): +def check_union(expr, info): name = expr['union'] base = expr.get('base') discriminator = expr.get('discriminator') @@ -565,18 +565,18 @@ def check_union(expr, expr_info): enum_define = None allow_metas = ['built-in', 'union', 'alternate', 'struct', 'enum'] if base is not None: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Simple union '%s' must not have a base" % name) # Else, it's a flat union. else: # The object must have a string or dictionary 'base'. - check_type(expr_info, "'base' for union '%s'" % name, + check_type(info, "'base' for union '%s'" % name, base, allow_dict=True, allow_optional=True, allow_metas=['struct']) if not base: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Flat union '%s' must have a base" % name) base_members = find_base_members(base) @@ -584,11 +584,11 @@ def check_union(expr, expr_info): # The value of member 'discriminator' must name a non-optional # member of the base struct. - check_name(expr_info, "Discriminator of flat union '%s'" % name, + check_name(info, "Discriminator of flat union '%s'" % name, discriminator) discriminator_type = base_members.get(discriminator) if not discriminator_type: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Discriminator '%s' is not a member of base " "struct '%s'" % (discriminator, base)) @@ -596,26 +596,26 @@ def check_union(expr, expr_info): allow_metas = ['struct'] # Do not allow string discriminator if not enum_define: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Discriminator '%s' must be of enumeration " "type" % discriminator) # Check every branch; don't allow an empty union if len(members) == 0: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Union '%s' cannot have empty 'data'" % name) for (key, value) in members.items(): - check_name(expr_info, "Member of union '%s'" % name, key) + check_name(info, "Member of union '%s'" % name, key) # Each value must name a known type - check_type(expr_info, "Member '%s' of union '%s'" % (key, name), + check_type(info, "Member '%s' of union '%s'" % (key, name), value, allow_array=not base, allow_metas=allow_metas) # If the discriminator names an enum type, then all members # of 'data' must also be members of the enum type. if enum_define: if key not in enum_define['enum_values']: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Discriminator value '%s' is not found in " "enum '%s'" % (key, enum_define["enum_name"])) @@ -624,64 +624,64 @@ def check_union(expr, expr_info): if enum_define: for value in enum_define['enum_values']: if value not in members.keys(): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Union '%s' data missing '%s' branch" % (name, value)) -def check_alternate(expr, expr_info): +def check_alternate(expr, info): name = expr['alternate'] members = expr['data'] types_seen = {} # Check every branch; require at least two branches if len(members) < 2: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Alternate '%s' should have at least two branches " "in 'data'" % name) for (key, value) in members.items(): - check_name(expr_info, "Member of alternate '%s'" % name, key) + check_name(info, "Member of alternate '%s'" % name, key) # Ensure alternates have no type conflicts. - check_type(expr_info, "Member '%s' of alternate '%s'" % (key, name), + check_type(info, "Member '%s' of alternate '%s'" % (key, name), value, allow_metas=['built-in', 'union', 'struct', 'enum']) qtype = find_alternate_member_qtype(value) if not qtype: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Alternate '%s' member '%s' cannot use " "type '%s'" % (name, key, value)) if qtype in types_seen: - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Alternate '%s' member '%s' can't " "be distinguished from member '%s'" % (name, key, types_seen[qtype])) types_seen[qtype] = key -def check_enum(expr, expr_info): +def check_enum(expr, info): name = expr['enum'] members = expr.get('data') prefix = expr.get('prefix') if not isinstance(members, list): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Enum '%s' requires an array for 'data'" % name) if prefix is not None and not isinstance(prefix, str): - raise QAPIExprError(expr_info, + raise QAPILineError(info, "Enum '%s' requires a string for 'prefix'" % name) for member in members: - check_name(expr_info, "Member of enum '%s'" % name, member, + check_name(info, "Member of enum '%s'" % name, member, enum_member=True) -def check_struct(expr, expr_info): +def check_struct(expr, info): name = expr['struct'] members = expr['data'] - check_type(expr_info, "'data' for struct '%s'" % name, members, + check_type(info, "'data' for struct '%s'" % name, members, allow_dict=True, allow_optional=True) - check_type(expr_info, "'base' for struct '%s'" % name, expr.get('base'), + check_type(info, "'base' for struct '%s'" % name, expr.get('base'), allow_metas=['struct']) @@ -690,25 +690,25 @@ def check_keys(expr_elem, meta, required, optional=[]): info = expr_elem['info'] name = expr[meta] if not isinstance(name, str): - raise QAPIExprError(info, + raise QAPILineError(info, "'%s' key must have a string value" % meta) required = required + [meta] for (key, value) in expr.items(): if key not in required and key not in optional: - raise QAPIExprError(info, + raise QAPILineError(info, "Unknown key '%s' in %s '%s'" % (key, meta, name)) if (key == 'gen' or key == 'success-response') and value is not False: - raise QAPIExprError(info, + raise QAPILineError(info, "'%s' of %s '%s' should only use false value" % (key, meta, name)) if key == 'boxed' and value is not True: - raise QAPIExprError(info, + raise QAPILineError(info, "'%s' of %s '%s' should only use true value" % (key, meta, name)) for key in required: if key not in expr: - raise QAPIExprError(info, + raise QAPILineError(info, "Key '%s' is missing from %s '%s'" % (key, meta, name)) @@ -743,7 +743,7 @@ def check_exprs(exprs): check_keys(expr_elem, 'event', [], ['data', 'boxed']) add_name(expr['event'], info, 'event') else: - raise QAPIExprError(expr_elem['info'], + raise QAPILineError(expr_elem['info'], "Expression is missing metatype") # Try again for hidden UnionKind enum @@ -978,7 +978,7 @@ class QAPISchemaObjectType(QAPISchemaType): def check(self, schema): if self.members is False: # check for cycles - raise QAPIExprError(self.info, + raise QAPILineError(self.info, "Object %s contains itself" % self.name) if self.members: return @@ -1051,10 +1051,10 @@ class QAPISchemaMember(object): def check_clash(self, info, seen): cname = c_name(self.name) if cname.lower() != cname and self.owner not in case_whitelist: - raise QAPIExprError(info, + raise QAPILineError(info, "%s should not use uppercase" % self.describe()) if cname in seen: - raise QAPIExprError(info, + raise QAPILineError(info, "%s collides with %s" % (self.describe(), seen[cname].describe())) seen[cname] = self @@ -1201,13 +1201,13 @@ class QAPISchemaCommand(QAPISchemaEntity): self.arg_type.check(schema) if self.boxed: if self.arg_type.is_empty(): - raise QAPIExprError(self.info, + raise QAPILineError(self.info, "Cannot use 'boxed' with empty type") else: assert not isinstance(self.arg_type, QAPISchemaAlternateType) assert not self.arg_type.variants elif self.boxed: - raise QAPIExprError(self.info, + raise QAPILineError(self.info, "Use of 'boxed' requires 'data'") if self._ret_type_name: self.ret_type = schema.lookup_type(self._ret_type_name) @@ -1235,13 +1235,13 @@ class QAPISchemaEvent(QAPISchemaEntity): self.arg_type.check(schema) if self.boxed: if self.arg_type.is_empty(): - raise QAPIExprError(self.info, + raise QAPILineError(self.info, "Cannot use 'boxed' with empty type") else: assert not isinstance(self.arg_type, QAPISchemaAlternateType) assert not self.arg_type.variants elif self.boxed: - raise QAPIExprError(self.info, + raise QAPILineError(self.info, "Use of 'boxed' requires 'data'") def visit(self, visitor): @@ -1258,7 +1258,7 @@ class QAPISchema(object): self._predefining = False self._def_exprs() self.check() - except (QAPISchemaError, QAPIExprError) as err: + except (QAPISchemaError, QAPILineError) as err: print >>sys.stderr, err exit(1) -- 2.10.0