diff --git a/docs/examples/function_defaults.py b/docs/examples/function_defaults.py new file mode 100644 index 0000000..3ec2cc7 --- /dev/null +++ b/docs/examples/function_defaults.py @@ -0,0 +1,29 @@ +from conjector import Default, properties + + +@properties(filename="function_defaults.yml", root="some_func_scope") +def first_func( + required: int, + regular_default: int = 20, + specified_default: int = Default(30), + file_default: int = Default(), +): + return required, regular_default, specified_default, file_default + + +assert first_func(10, 20, 30, 40) == (10, 20, 30, 40) +assert first_func(10) == (10, 20, 33, 44) + + +@properties(filename="function_defaults.yml", root="not_existing_func_scope") +def second_func( + required: int, + regular_default: int = 20, + specified_default: int = Default(30), + file_default: int = Default(), +): + return required, regular_default, specified_default, file_default + + +assert second_func(10, 20, 30, 40) == (10, 20, 30, 40) +assert second_func(10) == (10, 20, 30, 0) diff --git a/docs/examples/function_defaults.yml b/docs/examples/function_defaults.yml new file mode 100644 index 0000000..dc2cb41 --- /dev/null +++ b/docs/examples/function_defaults.yml @@ -0,0 +1,6 @@ +some_func_scope: + required: 11 + regular_default: 22 + specified_default: 33 + file_default: 44 +not_existing_func_scope: diff --git a/docs/function_defaults.md b/docs/function_defaults.md new file mode 100644 index 0000000..87d9455 --- /dev/null +++ b/docs/function_defaults.md @@ -0,0 +1,52 @@ +# Function defaults + +Using `conjector` you can not only inject config values into class, but also into function defaults. +Let's start by taking a look at an example. The code below demonstrates how to use `conjector` +to specify function defaults with values that can be replaced by configuration values: + +`function_defaults.yml`: +```{literalinclude} examples/function_defaults.yml +``` + +`function_defaults.py`: +```{literalinclude} examples/function_defaults.py +``` + + +The `required` parameter is a required function argument, while the other parameters have default values. +The `specified_default` parameter uses the `Default` wrapper to indicate that its value can be replaced +by a value from the configuration file. The `file_default` parameter also uses the `Default` wrapper, +but with an empty value, which means it will use the default value of its type. + +The assert statements verify that the functions return the expected output for various input parameters. +If all arguments are provided, the functions use the provided values, including any that replace `Default` markers. +If any arguments are missing, the functions will use the configuration values, if available, or the default values otherwise. + +## Wrapping class methods +With `@properties` decorator under class, you can also use `Default` marker in every method: +```python +@properties +class OtherClass: + def __init__(self, a: int = Default(), b: int = Default()) -> None: + self.a = a + self.b = b + + def simple_method( + self, a: int = Default(), b: int = Default() + ) -> Tuple[int, int]: + return a, b + + @classmethod + def cls_method( + cls, a: int = Default(), b: int = Default() + ) -> Tuple[int, int]: + return a, b + + @staticmethod + def stat_method( + a: int = Default(), b: int = Default() + ) -> Tuple[int, int]: + return a, b +``` +So there is no need to wrapp every method with `properties` decorator. +But "magic methods" (except `__init__`) are unwrapped by default. diff --git a/docs/index.md b/docs/index.md index 692c4b3..46ce302 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,4 +13,5 @@ config_formats supported_types global_settings lazy_initialization +function_defaults ```