diff mbox series

[v2,10/11] qapi/introspect.py: improve readability of _tree_to_qlit

Message ID 20201026194251.11075-11-jsnow@redhat.com
State Accepted
Commit c0e8d9f3c199357d89f362c54e1edced82c3c084
Headers show
Series [v2,01/11,DO-NOT-MERGE] docs: replace single backtick (`) with double-backtick (``) | expand

Commit Message

John Snow Oct. 26, 2020, 7:42 p.m. UTC
Subjective, but I find getting rid of the comprehensions helps. Also,
divide the sections into scalar and non-scalar sections, and remove
old-style string formatting.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 scripts/qapi/introspect.py | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

Comments

Cleber Rosa Nov. 7, 2020, 5:54 a.m. UTC | #1
On Mon, Oct 26, 2020 at 03:42:50PM -0400, John Snow wrote:
> Subjective, but I find getting rid of the comprehensions helps. Also,

> divide the sections into scalar and non-scalar sections, and remove

> old-style string formatting.

>


It's certainly a matter of picking your favorite poison... but for the
most part I think this is an improvement...

> Signed-off-by: John Snow <jsnow@redhat.com>

> ---

>  scripts/qapi/introspect.py | 37 +++++++++++++++++++++----------------

>  1 file changed, 21 insertions(+), 16 deletions(-)

> 

> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py

> index a261e402d69..d4f28485ba5 100644

> --- a/scripts/qapi/introspect.py

> +++ b/scripts/qapi/introspect.py

> @@ -100,7 +100,7 @@ def indent(level: int) -> str:

>  

>          ret = ''

>          if obj.comment:

> -            ret += indent(level) + '/* %s */\n' % obj.comment

> +            ret += indent(level) + f"/* {obj.comment} */\n"

>          if obj.ifcond:

>              ret += gen_if(obj.ifcond)

>          ret += _tree_to_qlit(obj.value, level, suppress_first_indent)

> @@ -111,31 +111,36 @@ def indent(level: int) -> str:

>      ret = ''

>      if not suppress_first_indent:

>          ret += indent(level)

> +

> +    # Scalars:

>      if obj is None:

>          ret += 'QLIT_QNULL'

>      elif isinstance(obj, str):

> -        ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'

> +        ret += f"QLIT_QSTR({to_c_string(obj)})"

> +    elif isinstance(obj, bool):

> +        ret += "QLIT_QBOOL({:s})".format(str(obj).lower())

> +

> +    # Non-scalars:

>      elif isinstance(obj, list):

> -        elts = [_tree_to_qlit(elt, level + 1).strip('\n')

> -                for elt in obj]

> -        elts.append(indent(level + 1) + "{}")

>          ret += 'QLIT_QLIST(((QLitObject[]) {\n'

> -        ret += '\n'.join(elts) + '\n'

> +        for value in obj:

> +            ret += _tree_to_qlit(value, level + 1).strip('\n') + '\n'

> +        ret += indent(level + 1) + '{}\n'

>          ret += indent(level) + '}))'

>      elif isinstance(obj, dict):

> -        elts = []

> -        for key, value in sorted(obj.items()):

> -            elts.append(indent(level + 1) + '{ %s, %s }' %

> -                        (to_c_string(key),

> -                         _tree_to_qlit(value, level + 1, True)))

> -        elts.append(indent(level + 1) + '{}')

>          ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'

> -        ret += ',\n'.join(elts) + '\n'

> +        for key, value in sorted(obj.items()):

> +            ret += indent(level + 1) + "{{ {:s}, {:s} }},\n".format(

> +                to_c_string(key),

> +                _tree_to_qlit(value, level + 1, suppress_first_indent=True)

> +            )

> +        ret += indent(level + 1) + '{}\n'

>          ret += indent(level) + '}))'

> -    elif isinstance(obj, bool):

> -        ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')

>      else:

> -        assert False                # not implemented

> +        raise NotImplementedError(


This is an improvement, but doesn't fall into the *readability* bucket.
IMO it's worth splitting it out.

- Cleber.
Markus Armbruster Nov. 16, 2020, 10:17 a.m. UTC | #2
John Snow <jsnow@redhat.com> writes:

> Subjective, but I find getting rid of the comprehensions helps. Also,

> divide the sections into scalar and non-scalar sections, and remove

> old-style string formatting.

>

> Signed-off-by: John Snow <jsnow@redhat.com>

> ---

>  scripts/qapi/introspect.py | 37 +++++++++++++++++++++----------------

>  1 file changed, 21 insertions(+), 16 deletions(-)

>

> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py

> index a261e402d69..d4f28485ba5 100644

> --- a/scripts/qapi/introspect.py

> +++ b/scripts/qapi/introspect.py

> @@ -100,7 +100,7 @@ def indent(level: int) -> str:

>  

>          ret = ''

>          if obj.comment:

> -            ret += indent(level) + '/* %s */\n' % obj.comment

> +            ret += indent(level) + f"/* {obj.comment} */\n"

>          if obj.ifcond:

>              ret += gen_if(obj.ifcond)

>          ret += _tree_to_qlit(obj.value, level, suppress_first_indent)

> @@ -111,31 +111,36 @@ def indent(level: int) -> str:

>      ret = ''

>      if not suppress_first_indent:

>          ret += indent(level)

> +

> +    # Scalars:

>      if obj is None:

>          ret += 'QLIT_QNULL'

>      elif isinstance(obj, str):

> -        ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'

> +        ret += f"QLIT_QSTR({to_c_string(obj)})"

> +    elif isinstance(obj, bool):

> +        ret += "QLIT_QBOOL({:s})".format(str(obj).lower())


Changed from

           ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')

Doesn't look like an improvement to me.

> +

> +    # Non-scalars:

>      elif isinstance(obj, list):

> -        elts = [_tree_to_qlit(elt, level + 1).strip('\n')

> -                for elt in obj]

> -        elts.append(indent(level + 1) + "{}")

>          ret += 'QLIT_QLIST(((QLitObject[]) {\n'

> -        ret += '\n'.join(elts) + '\n'

> +        for value in obj:

> +            ret += _tree_to_qlit(value, level + 1).strip('\n') + '\n'

> +        ret += indent(level + 1) + '{}\n'

>          ret += indent(level) + '}))'

>      elif isinstance(obj, dict):

> -        elts = []

> -        for key, value in sorted(obj.items()):

> -            elts.append(indent(level + 1) + '{ %s, %s }' %

> -                        (to_c_string(key),

> -                         _tree_to_qlit(value, level + 1, True)))

> -        elts.append(indent(level + 1) + '{}')

>          ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'

> -        ret += ',\n'.join(elts) + '\n'

> +        for key, value in sorted(obj.items()):

> +            ret += indent(level + 1) + "{{ {:s}, {:s} }},\n".format(

> +                to_c_string(key),

> +                _tree_to_qlit(value, level + 1, suppress_first_indent=True)

> +            )

> +        ret += indent(level + 1) + '{}\n'

>          ret += indent(level) + '}))'

> -    elif isinstance(obj, bool):

> -        ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')

>      else:

> -        assert False                # not implemented

> +        raise NotImplementedError(

> +            f"type '{type(obj).__name__}' not implemented"

> +        )


Not covered by the commit message's mandate.

Why bother?

> +

>      if level > 0:

>          ret += ','

>      return ret
John Snow Dec. 15, 2020, 3:25 p.m. UTC | #3
On 11/16/20 5:17 AM, Markus Armbruster wrote:
> John Snow <jsnow@redhat.com> writes:

> 

>> Subjective, but I find getting rid of the comprehensions helps. Also,

>> divide the sections into scalar and non-scalar sections, and remove

>> old-style string formatting.

>>

>> Signed-off-by: John Snow <jsnow@redhat.com>

>> ---

>>   scripts/qapi/introspect.py | 37 +++++++++++++++++++++----------------

>>   1 file changed, 21 insertions(+), 16 deletions(-)

>>

>> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py

>> index a261e402d69..d4f28485ba5 100644

>> --- a/scripts/qapi/introspect.py

>> +++ b/scripts/qapi/introspect.py

>> @@ -100,7 +100,7 @@ def indent(level: int) -> str:

>>   

>>           ret = ''

>>           if obj.comment:

>> -            ret += indent(level) + '/* %s */\n' % obj.comment

>> +            ret += indent(level) + f"/* {obj.comment} */\n"

>>           if obj.ifcond:

>>               ret += gen_if(obj.ifcond)

>>           ret += _tree_to_qlit(obj.value, level, suppress_first_indent)

>> @@ -111,31 +111,36 @@ def indent(level: int) -> str:

>>       ret = ''

>>       if not suppress_first_indent:

>>           ret += indent(level)

>> +

>> +    # Scalars:

>>       if obj is None:

>>           ret += 'QLIT_QNULL'

>>       elif isinstance(obj, str):

>> -        ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'

>> +        ret += f"QLIT_QSTR({to_c_string(obj)})"

>> +    elif isinstance(obj, bool):

>> +        ret += "QLIT_QBOOL({:s})".format(str(obj).lower())

> 

> Changed from

> 

>             ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')

> 

> Doesn't look like an improvement to me.

> 


Momentary lapse of judgment and/or just got lost in a sea of 150 
patches, please pick your preferred excuse.

(I've made this one use an f-string, too.)

>> +

>> +    # Non-scalars:

>>       elif isinstance(obj, list):

>> -        elts = [_tree_to_qlit(elt, level + 1).strip('\n')

>> -                for elt in obj]

>> -        elts.append(indent(level + 1) + "{}")

>>           ret += 'QLIT_QLIST(((QLitObject[]) {\n'

>> -        ret += '\n'.join(elts) + '\n'

>> +        for value in obj:

>> +            ret += _tree_to_qlit(value, level + 1).strip('\n') + '\n'

>> +        ret += indent(level + 1) + '{}\n'

>>           ret += indent(level) + '}))'

>>       elif isinstance(obj, dict):

>> -        elts = []

>> -        for key, value in sorted(obj.items()):

>> -            elts.append(indent(level + 1) + '{ %s, %s }' %

>> -                        (to_c_string(key),

>> -                         _tree_to_qlit(value, level + 1, True)))

>> -        elts.append(indent(level + 1) + '{}')

>>           ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'

>> -        ret += ',\n'.join(elts) + '\n'

>> +        for key, value in sorted(obj.items()):

>> +            ret += indent(level + 1) + "{{ {:s}, {:s} }},\n".format(

>> +                to_c_string(key),

>> +                _tree_to_qlit(value, level + 1, suppress_first_indent=True)

>> +            )

>> +        ret += indent(level + 1) + '{}\n'

>>           ret += indent(level) + '}))'

>> -    elif isinstance(obj, bool):

>> -        ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')

>>       else:

>> -        assert False                # not implemented

>> +        raise NotImplementedError(

>> +            f"type '{type(obj).__name__}' not implemented"

>> +        )

> 

> Not covered by the commit message's mandate.

> 

> Why bother?

> 


Somewhat as a debugging mechanism while I was toying with various 
refactors. I like my error messages to be informative, I guess.

>> +

>>       if level > 0:

>>           ret += ','

>>       return ret
diff mbox series

Patch

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index a261e402d69..d4f28485ba5 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -100,7 +100,7 @@  def indent(level: int) -> str:
 
         ret = ''
         if obj.comment:
-            ret += indent(level) + '/* %s */\n' % obj.comment
+            ret += indent(level) + f"/* {obj.comment} */\n"
         if obj.ifcond:
             ret += gen_if(obj.ifcond)
         ret += _tree_to_qlit(obj.value, level, suppress_first_indent)
@@ -111,31 +111,36 @@  def indent(level: int) -> str:
     ret = ''
     if not suppress_first_indent:
         ret += indent(level)
+
+    # Scalars:
     if obj is None:
         ret += 'QLIT_QNULL'
     elif isinstance(obj, str):
-        ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
+        ret += f"QLIT_QSTR({to_c_string(obj)})"
+    elif isinstance(obj, bool):
+        ret += "QLIT_QBOOL({:s})".format(str(obj).lower())
+
+    # Non-scalars:
     elif isinstance(obj, list):
-        elts = [_tree_to_qlit(elt, level + 1).strip('\n')
-                for elt in obj]
-        elts.append(indent(level + 1) + "{}")
         ret += 'QLIT_QLIST(((QLitObject[]) {\n'
-        ret += '\n'.join(elts) + '\n'
+        for value in obj:
+            ret += _tree_to_qlit(value, level + 1).strip('\n') + '\n'
+        ret += indent(level + 1) + '{}\n'
         ret += indent(level) + '}))'
     elif isinstance(obj, dict):
-        elts = []
-        for key, value in sorted(obj.items()):
-            elts.append(indent(level + 1) + '{ %s, %s }' %
-                        (to_c_string(key),
-                         _tree_to_qlit(value, level + 1, True)))
-        elts.append(indent(level + 1) + '{}')
         ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'
-        ret += ',\n'.join(elts) + '\n'
+        for key, value in sorted(obj.items()):
+            ret += indent(level + 1) + "{{ {:s}, {:s} }},\n".format(
+                to_c_string(key),
+                _tree_to_qlit(value, level + 1, suppress_first_indent=True)
+            )
+        ret += indent(level + 1) + '{}\n'
         ret += indent(level) + '}))'
-    elif isinstance(obj, bool):
-        ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')
     else:
-        assert False                # not implemented
+        raise NotImplementedError(
+            f"type '{type(obj).__name__}' not implemented"
+        )
+
     if level > 0:
         ret += ','
     return ret