From 8d38900daf083d5ad59409fac3a0bd83d6b876fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Cardao?= Date: Thu, 21 Mar 2024 12:23:40 +0100 Subject: [PATCH 1/2] Type e3.anod.sandbox.scripts module --- src/e3/anod/sandbox/scripts.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/e3/anod/sandbox/scripts.py b/src/e3/anod/sandbox/scripts.py index 5036b95f..4e355046 100644 --- a/src/e3/anod/sandbox/scripts.py +++ b/src/e3/anod/sandbox/scripts.py @@ -3,8 +3,15 @@ from e3.anod.error import AnodError from e3.main import Main +from typing import TYPE_CHECKING -def anod_cmdline(subparsers, action_name: str, action_help: str) -> None: # type: ignore +if TYPE_CHECKING: + from argparse import _SubParsersAction + + +def anod_cmdline( + subparsers: _SubParsersAction, action_name: str, action_help: str +) -> None: parser = subparsers.add_parser(action_name, help=action_help) parser.set_defaults(action_name=action_name) parser.add_argument("spec", metavar="SPEC", help="The specification file name") @@ -29,7 +36,7 @@ def anod() -> None: assert sys.modules["__main__"].__file__ is not None sandbox_dir = os.path.abspath( - os.path.join(os.path.dirname(sys.modules["__main__"].__file__), os.pardir) + os.path.join(os.path.dirname(sys.modules["__main__"].__file__), os.pardir) # type: ignore ) sandbox = e3.anod.sandbox.SandBox(root_dir=sandbox_dir) From 0a80bf0eb6ed69a745f0cabe5567ff948e96678d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Cardao?= Date: Thu, 21 Mar 2024 11:55:52 +0100 Subject: [PATCH 2/2] Enable Anod class to use methods instead of properties --- src/e3/anod/spec.py | 20 ++++++++++++++++++++ tests/tests_e3/anod/spec_test.py | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/src/e3/anod/spec.py b/src/e3/anod/spec.py index a9e2f1a0..41f7c005 100644 --- a/src/e3/anod/spec.py +++ b/src/e3/anod/spec.py @@ -203,6 +203,26 @@ class MyProduct(Anod): ExternalSourceBuilder = e3.anod.package.ExternalSourceBuilder ThirdPartySourceBuilder = e3.anod.package.ThirdPartySourceBuilder + def __new__(cls, *args: Any, **kwargs: Any) -> Any: + """Replace `method` by property when decorator is missing.""" + should_be_property = ( + "enable_name_generator", + "readme_info", + "base_name", + "build_space_name", + "has_package", + "package", + "component", + "source_pkg_build", + ) + + for prop in should_be_property: + class_property = getattr(cls, prop) + if callable(class_property): + setattr(cls, prop, property(fget=class_property)) + + return super().__new__(cls) + def __init__( self, qualifier: str, diff --git a/tests/tests_e3/anod/spec_test.py b/tests/tests_e3/anod/spec_test.py index b4772b0b..eacbd273 100644 --- a/tests/tests_e3/anod/spec_test.py +++ b/tests/tests_e3/anod/spec_test.py @@ -147,3 +147,12 @@ class GeneratorDisabled(Anod): assert spec_enable.args == {"q1": True} assert spec_disable.args == {"q1": ""} + + +def test_missing_property(): + class NoProperty(Anod): + def source_pkg_build(self) -> list: + return [] + + noproperty = NoProperty(qualifier="", kind="source") + assert noproperty.source_pkg_build == []