John Snow <js...@redhat.com> writes: > Code style tools really dislike the use of global keywords, because it > generally involves re-binding the name at runtime which can have strange > effects depending on when and how that global name is referenced in > other modules. > > Make a little indent level manager instead. > > Signed-off-by: John Snow <js...@redhat.com> > Reviewed-by: Eduardo Habkost <ehabk...@redhat.com> > Reviewed-by: Cleber Rosa <cr...@redhat.com>
Intentation is a job for QAPIGen (and its subtypes). But if this patch is easier to achieve this series' goal, I don't mind. > --- > scripts/qapi/common.py | 49 ++++++++++++++++++++++++++++-------------- > scripts/qapi/visit.py | 7 +++--- > 2 files changed, 36 insertions(+), 20 deletions(-) > > diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py > index cee63eb95c7..b35318b72cf 100644 > --- a/scripts/qapi/common.py > +++ b/scripts/qapi/common.py > @@ -93,33 +93,50 @@ def c_name(name, protect=True): > pointer_suffix = ' *' + eatspace > > > -def genindent(count): > - ret = '' > - for _ in range(count): > - ret += ' ' > - return ret > +class Indentation: > + """ > + Indentation level management. > > + :param initial: Initial number of spaces, default 0. > + """ > + def __init__(self, initial: int = 0) -> None: > + self._level = initial > > -indent_level = 0 > + def __int__(self) -> int: > + return self._level > > + def __repr__(self) -> str: > + return "{}({:d})".format(type(self).__name__, self._level) > > -def push_indent(indent_amount=4): > - global indent_level > - indent_level += indent_amount > + def __str__(self) -> str: > + """Return the current indentation as a string of spaces.""" > + return ' ' * self._level > > + def __bool__(self) -> bool: > + """True when there is a non-zero indentation.""" > + return bool(self._level) > > -def pop_indent(indent_amount=4): > - global indent_level > - indent_level -= indent_amount > + def increase(self, amount: int = 4) -> None: > + """Increase the indentation level by ``amount``, default 4.""" > + self._level += amount > + > + def decrease(self, amount: int = 4) -> None: > + """Decrease the indentation level by ``amount``, default 4.""" > + if self._level < amount: > + raise ArithmeticError( > + f"Can't remove {amount:d} spaces from {self!r}") Raise a fancy error when there's an actual need for it. You're not coding a framework thousands of people you never heard of will put to uses you cannot imagine. > + self._level -= amount > + > + > +indent = Indentation() > > > # Generate @code with @kwds interpolated. > -# Obey indent_level, and strip eatspace. > +# Obey indent, and strip eatspace. > def cgen(code, **kwds): > raw = code % kwds > - if indent_level: > - indent = genindent(indent_level) > - raw = re.sub(r'^(?!(#|$))', indent, raw, flags=re.MULTILINE) > + if indent: > + raw = re.sub(r'^(?!(#|$))', str(indent), raw, flags=re.MULTILINE) > return re.sub(re.escape(eatspace) + r' *', '', raw) > > > diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py > index 808410d6f1b..14f30c228b7 100644 > --- a/scripts/qapi/visit.py > +++ b/scripts/qapi/visit.py > @@ -18,9 +18,8 @@ > c_name, > gen_endif, > gen_if, > + indent, > mcgen, > - pop_indent, > - push_indent, > ) > from .gen import QAPISchemaModularCVisitor, ifcontext > from .schema import QAPISchemaObjectType > @@ -69,7 +68,7 @@ def gen_visit_object_members(name, base, members, variants): > if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { > ''', > name=memb.name, c_name=c_name(memb.name)) > - push_indent() > + indent.increase() > ret += mcgen(''' > if (!visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, errp)) { > return false; > @@ -78,7 +77,7 @@ def gen_visit_object_members(name, base, members, variants): > c_type=memb.type.c_name(), name=memb.name, > c_name=c_name(memb.name)) > if memb.optional: > - pop_indent() > + indent.decrease() > ret += mcgen(''' > } > ''')