Skip to content

Commit 39fd0f3

Browse files
committed
Rework interface_generator to use trim_blocks and lstrip_blocks
This makes the template strings easier to understand as each filter or include can be indented without affecting the newlines. Also add a note to documentation that style is not guranteed by the code generator. Only syntax will be checked. Add unit test to check that syntax is correct.
1 parent 9f1d48d commit 39fd0f3

File tree

3 files changed

+201
-96
lines changed

3 files changed

+201
-96
lines changed

docs/code_generator.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ to be installed.
1313
.. warning:: Do NOT send the generator result to ``exec()`` function.
1414
Interface code MUST be inspected before running.
1515

16+
The generated interfaces code will be syntactically correct but NOT stylistically.
17+
It is recommended running a code formatter on the generated code. (for example ``black``)
18+
1619
Generating from XML files
1720
-------------------------
1821

src/sdbus/interface_generator.py

Lines changed: 127 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -555,38 +555,41 @@ def has_members(self) -> bool:
555555
'org.freedesktop.DBus.ObjectManager',
556556
}
557557

558+
558559
INTERFACE_TEMPLATES: Dict[str, str] = {
559-
"generic_no_members": r"... # Interface has no members",
560+
"generic_no_members": """\
561+
... # Interface has no members
562+
""",
560563
"generic_method_flags": (
561-
r"""
562-
{%- if method.dbus_input_signature %}
564+
"""\
565+
{% if method.dbus_input_signature %}
563566
input_signature="{{ method.dbus_input_signature }}",
564-
{%- endif %}
565-
566-
{%- if method.dbus_result_signature %}
567+
{% endif %}
568+
{% if method.dbus_result_signature %}
567569
result_signature="{{ method.dbus_result_signature }}",
568-
{%- endif %}
569-
570-
{%- if method.flags_str %}
570+
{% endif %}
571+
{% if method.flags_str %}
571572
flags={{ method.flags_str }},
572-
{%- endif %}
573+
{% endif %}
573574
"""
574575
),
575576
"generic_property_flags": (
576-
r"""
577-
{%- if a_property.dbus_signature %}
577+
"""\
578+
{% if a_property.dbus_signature %}
578579
property_signature="{{ a_property.dbus_signature }}",
579-
{%- endif %}
580-
581-
{%- if a_property.flags_str %}
580+
{% endif %}
581+
{% if a_property.flags_str %}
582582
flags={{ a_property.flags_str }},
583-
{%- endif %}
583+
{% endif %}
584584
"""
585585
),
586-
"generic_header": r"""from __future__ import annotations
586+
"generic_header": """\
587+
from __future__ import annotations
587588
588-
from typing import Any, Dict, List, Tuple""",
589-
"async_imports_header": r"""from sdbus import (
589+
from typing import Any, Dict, List, Tuple
590+
591+
""",
592+
"async_imports_header": """from sdbus import (
590593
DbusDeprecatedFlag,
591594
DbusInterfaceCommonAsync,
592595
DbusNoReplyFlag,
@@ -598,84 +601,96 @@ def has_members(self) -> bool:
598601
dbus_method_async,
599602
dbus_property_async,
600603
dbus_signal_async,
601-
)""",
604+
)
605+
606+
""",
602607
"async_main": (
603-
r"""{% if include_import_header -%}
604-
{% include 'generic_header' %}
608+
"""\
609+
{% if include_import_header %}
610+
{% include 'generic_header' %}
611+
612+
{% include 'async_imports_header' %}
613+
{% endif %}
605614
606-
{% include 'async_imports_header' %}
607-
{%- endif %}
608615
{% for interface in interfaces %}
609616
610-
{% include 'async_interface' %}
611-
{%- endfor %}
617+
{% include 'async_interface' %}
618+
{% endfor %}
612619
"""
613620
),
614621
"async_interface": (
615-
r"""class {{ interface.python_name }}(
622+
"""\
623+
class {{ interface.python_name }}(
616624
DbusInterfaceCommonAsync,
617625
interface_name="{{ interface.interface_name }}",
618626
):
619-
{%- filter indent -%}
620-
{%- if interface.has_members -%}
621-
{% for method in interface.methods -%}
622-
{% include 'async_method' %}
623-
{% endfor -%}
624-
{% for a_property in interface.properties -%}
625-
{% include 'async_property' %}
626-
{% endfor -%}
627-
{% for signal in interface.signals -%}
628-
{% include 'async_signal' %}
629-
{% endfor -%}
630-
{%- else %}
631-
{% include 'generic_no_members' %}
632-
{% endif -%}
633-
{%- endfilter -%}
627+
{% filter indent(first=True) %}
628+
{% if interface.has_members %}
629+
{% for method in interface.methods %}
630+
{% include 'async_method' %}
631+
632+
{% endfor %}
633+
{% for a_property in interface.properties %}
634+
{% include 'async_property' %}
635+
636+
{% endfor %}
637+
{% for signal in interface.signals %}
638+
{% include 'async_signal' %}
639+
640+
{% endfor %}
641+
{% else %}
642+
{% include 'generic_no_members' %}
643+
644+
{% endif %}
645+
{% endfilter %}
634646
"""
635647
),
636648
"async_method": (
637-
r"""
649+
"""\
638650
@dbus_method_async(
639-
{%- filter indent -%}
640-
{%- include 'generic_method_flags' -%}
641-
{%- endfilter %}
651+
{% filter indent(first=True) %}
652+
{% include 'generic_method_flags' %}
653+
{% endfilter %}
642654
)
643655
async def {{ method.python_name }}(
644656
self,
645-
646-
{%- for arg_name, arg_type in method.args_names_and_typing %}
657+
{% for arg_name, arg_type in method.args_names_and_typing %}
647658
{{ arg_name }}: {{ arg_type }},
648-
{%- endfor %}
659+
{% endfor %}
649660
) -> {{ method.result_typing }}:
650661
raise NotImplementedError
662+
651663
"""
652664
),
653665
"async_property": (
654-
r"""
666+
"""\
655667
@dbus_property_async(
656-
{%- filter indent -%}
657-
{%- include 'generic_property_flags' -%}
658-
{%- endfilter %}
668+
{% filter indent(first=True) %}
669+
{% include 'generic_property_flags' %}
670+
{% endfilter %}
659671
)
660672
def {{ a_property.python_name }}(self) -> {{ a_property.typing }}:
661-
raise NotImplementedError"""
673+
raise NotImplementedError
674+
675+
"""
662676
),
663677
"async_signal": (
664-
r"""
678+
"""\
665679
@dbus_signal_async(
666-
667-
{%- if signal.dbus_signature %}
680+
{% if signal.dbus_signature %}
668681
signal_signature="{{ signal.dbus_signature }}",
669-
{%- endif %}
670-
671-
{%- if signal.flags_str %}
682+
{% endif %}
683+
{% if signal.flags_str %}
672684
flags={{ signal.flags_str }},
673-
{%- endif %}
685+
{% endif %}
674686
)
675687
def {{ signal.python_name }}(self) -> {{ signal.typing }}:
676-
raise NotImplementedError"""
688+
raise NotImplementedError
689+
690+
"""
677691
),
678-
"blocking_imports_header": r"""from sdbus import (
692+
"blocking_imports_header": """\
693+
from sdbus import (
679694
DbusDeprecatedFlag,
680695
DbusInterfaceCommon,
681696
DbusNoReplyFlag,
@@ -686,64 +701,75 @@ def {{ signal.python_name }}(self) -> {{ signal.typing }}:
686701
DbusUnprivilegedFlag,
687702
dbus_method,
688703
dbus_property,
689-
)""",
704+
)
705+
706+
""",
690707
"blocking_main": (
691-
r"""{% if include_import_header -%}
692-
{% include 'generic_header' %}
708+
"""\
709+
{% if include_import_header %}
710+
{% include 'generic_header' %}
711+
712+
{% include 'blocking_imports_header' %}
713+
{% endif %}
693714
694-
{% include 'blocking_imports_header' %}
695-
{%- endif %}
696715
{% for interface in interfaces %}
697716
698-
{% include 'blocking_interface' %}
699-
{%- endfor %}
717+
{% include 'blocking_interface' %}
718+
{% endfor %}
719+
700720
"""
701721
),
702722
"blocking_interface": (
703-
r"""class {{ interface.python_name }}(
723+
"""\
724+
class {{ interface.python_name }}(
704725
DbusInterfaceCommon,
705726
interface_name="{{ interface.interface_name }}",
706727
):
707-
{%- filter indent -%}
708-
{%- if interface.has_members -%}
709-
{% for method in interface.methods -%}
710-
{% include 'blocking_method' %}
711-
{% endfor -%}
712-
{% for a_property in interface.properties -%}
713-
{% include 'blocking_property' %}
714-
{% endfor -%}
715-
{%- else %}
716-
{% include 'generic_no_members' %}
717-
{% endif -%}
718-
{%- endfilter -%}
728+
{% filter indent(first=True) %}
729+
{% if interface.has_members %}
730+
{% for method in interface.methods %}
731+
{% include 'blocking_method' %}
732+
733+
{% endfor %}
734+
{% for a_property in interface.properties %}
735+
{% include 'blocking_property' %}
736+
737+
{% endfor %}
738+
{% else %}
739+
{% include 'generic_no_members' %}
740+
741+
{% endif %}
742+
{% endfilter %}
719743
"""
720744
),
721745
"blocking_method": (
722-
r"""
746+
"""\
723747
@dbus_method(
724-
{%- filter indent -%}
725-
{%- include 'generic_method_flags' -%}
726-
{%- endfilter %}
748+
{% filter indent(first=True) %}
749+
{% include 'generic_method_flags' %}
750+
{% endfilter %}
727751
)
728752
def {{ method.python_name }}(
729753
self,
730-
731-
{%- for arg_name, arg_type in method.args_names_and_typing %}
754+
{% for arg_name, arg_type in method.args_names_and_typing %}
732755
{{ arg_name }}: {{ arg_type }},
733-
{%- endfor %}
756+
{% endfor %}
734757
) -> {{ method.result_typing }}:
735758
raise NotImplementedError
759+
736760
"""
737761
),
738762
"blocking_property": (
739-
r"""
763+
"""\
740764
@dbus_property(
741-
{%- filter indent -%}
742-
{%- include 'generic_property_flags' -%}
743-
{%- endfilter %}
765+
{% filter indent(first=True) %}
766+
{% include 'generic_property_flags' %}
767+
{% endfilter %}
744768
)
745769
def {{ a_property.python_name }}(self) -> {{ a_property.typing }}:
746-
raise NotImplementedError"""
770+
raise NotImplementedError
771+
772+
"""
747773
),
748774
}
749775

@@ -795,7 +821,12 @@ def generate_py_file(
795821

796822
template_name = "async_main" if do_async else "blocking_main"
797823

798-
env = JinjaEnv(loader=DictLoader(INTERFACE_TEMPLATES))
824+
env = JinjaEnv(
825+
loader=DictLoader(INTERFACE_TEMPLATES),
826+
trim_blocks=True,
827+
lstrip_blocks=True,
828+
autoescape=False,
829+
)
799830
return env.get_template(template_name).render(
800831
interfaces=interfaces,
801832
include_import_header=include_import_header,

0 commit comments

Comments
 (0)