diff --git a/CHANGELOG.md b/CHANGELOG.md index 68352f9..815fde2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +## [1.5.3] + +### Fixed + +- `FnWithKwargs` call function fixed + ## [1.5.2] ### Added diff --git a/kaizo/utils/fn.py b/kaizo/utils/fn.py index cb3dbf9..6f13ab0 100644 --- a/kaizo/utils/fn.py +++ b/kaizo/utils/fn.py @@ -1,5 +1,5 @@ from collections.abc import Callable -from copy import copy +from functools import partial from typing import Generic, TypeVar R = TypeVar("R") @@ -7,8 +7,8 @@ class FnWithKwargs(Generic[R]): fn: Callable[..., R] - args: tuple | None - kwargs: dict[str] | None + args: tuple + kwargs: dict[str] def __init__( self, @@ -16,22 +16,20 @@ def __init__( args: tuple | None = None, kwargs: dict[str] | None = None, ) -> None: - self.fn = fn + if args is None: + args = () if kwargs is None: kwargs = {} + self.fn = fn self.args = args self.kwargs = kwargs def __call__(self, *args, **kwargs) -> R: - call_kwargs = copy(self.kwargs) - call_kwargs.update(kwargs) - - if self.args is not None: - args = self.args + fn = partial(self.fn, *self.args, **self.kwargs) - return self.fn(*args, **call_kwargs) + return fn(*args, **kwargs) def update(self, **kwargs) -> None: self.kwargs.update(kwargs) diff --git a/pyproject.toml b/pyproject.toml index 2105df5..9c8f5c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kaizo" -version = "1.5.2" +version = "1.5.3" description = "declarative YAML-based configuration parser" authors = [{ name = "Mohammad Ghazanfari", email = "mgh.5225@gmail.com" }] readme = "README.md" diff --git a/tests/test_lazy_injection.py b/tests/test_lazy_injection.py new file mode 100644 index 0000000..e79839a --- /dev/null +++ b/tests/test_lazy_injection.py @@ -0,0 +1,46 @@ +from pathlib import Path + +from kaizo import ConfigParser +from kaizo.utils import FnWithKwargs + +X = 5 +Y = 6 +Z = 7 + +main_py = f""" +def fn(x,y,z): + return (x,y,z) + +def fn2(cb): + return cb({X},{Y}) +""" + + +lazy_config = f""" +local: main.py +a: + module: local + source: fn + lazy: true + args: + z: {Z} +b: + module: local + source: fn2 + args: + cb: .{{a}} +""" + + +def test_lazy_injection(tmp_path: Path) -> None: + module = tmp_path / "main.py" + module.write_text(main_py) + + cfg_file = tmp_path / "cfg.yml" + cfg_file.write_text(lazy_config) + + parser = ConfigParser(cfg_file, kwargs={"injected": X}) + out = parser.parse() + + assert isinstance(out["a"], FnWithKwargs) + assert out["b"] == (X, Y, Z)