Skip to content
Snippets Groups Projects
Commit 4045187d authored by David Schäfer's avatar David Schäfer
Browse files

Merge branch 'config_func' into 'develop'

Allow function arguments in config syntax

See merge request !641
parents 8668f59e 7de05513
No related branches found
No related tags found
3 merge requests!685Release 2.4,!684Release 2.4,!641Allow function arguments in config syntax
Pipeline #161258 passed with stages
in 7 minutes and 38 seconds
......@@ -10,7 +10,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
[List of commits](https://git.ufz.de/rdm-software/saqc/-/compare/v2.3.0...develop)
### Added
- Methods `logicalAnd` and `logicalOr`
- `Flags` supports slicing and column selection with `list` or a `pd.Index`.
- `Flags` supports slicing and column selection with `list` or a `pd.Index`
### Changed
- Deprecate `interpolate`, `linear` and `shift` in favor of `align`
- Rename `interplateInvalid` to `interpolate`
......@@ -18,6 +18,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
### Removed
- Parameter `limit` from `align`
### Fixed
- `func` arguments in text configurations were not parsed correctly
- fail on duplicated arguments to test methods
## [2.3.0](https://git.ufz.de/rdm-software/saqc/-/tags/v2.3.0) - 2023-01-17
......
......@@ -7,6 +7,9 @@
# -*- coding: utf-8 -*-
import ast
import importlib
import numpy as np
from saqc.core.register import FUNC_MAP
from saqc.parsing.environ import ENVIRONMENT
......@@ -127,18 +130,33 @@ class ConfigFunctionParser(ast.NodeVisitor):
key, value = node.arg, node.value
check_tree = True
imports = {}
if key == "func":
visitor = ConfigExpressionParser(value)
args = ast.arguments(
posonlyargs=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[],
args=[ast.arg(arg=a, annotation=None) for a in visitor.args],
kwarg=None,
vararg=None,
)
value = ast.Lambda(args=args, body=value)
if (isinstance(value, ast.Name) and value.id in ENVIRONMENT) or (
isinstance(value, ast.Constant) and value.value in ENVIRONMENT
):
func = ENVIRONMENT[
value.id if isinstance(value, ast.Name) else value.value
]
# handle the missing attribute for numpy.ufunc
module = getattr(func, "__module__", "numpy")
if module.startswith("saqc"):
# if it's an saqc function, we need to import the top level package first
imports["saqc"] = importlib.import_module("saqc")
imports[module] = importlib.import_module(module)
value = ast.parse(f"{module}.{func.__name__}").body[0].value
else:
visitor = ConfigExpressionParser(value)
args = ast.arguments(
posonlyargs=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[],
args=[ast.arg(arg=a, annotation=None) for a in visitor.args],
kwarg=None,
vararg=None,
)
value = ast.Lambda(args=args, body=value)
# NOTE:
# don't pass the generated functions down
# to the checks implemented in this class...
......@@ -159,8 +177,7 @@ class ConfigFunctionParser(ast.NodeVisitor):
mode="single",
)
# NOTE: only pass a copy to not clutter the ENVIRONMENT
# try:
exec(co, {**ENVIRONMENT}, self.kwargs)
exec(co, {**ENVIRONMENT, **imports}, self.kwargs)
# let's do some more validity checks
if check_tree:
......
......@@ -9,7 +9,9 @@
import numpy as np
import pytest
from saqc.core import DictOfSeries, Flags, flagging
import saqc.lib.ts_operators as ts_ops
from saqc.core import DictOfSeries, Flags, SaQC, flagging
from saqc.parsing.environ import ENVIRONMENT
from saqc.parsing.reader import fromConfig, readFile
from tests.common import initData, writeIO
......@@ -155,3 +157,21 @@ def test_supportedArguments(data):
for test in tests:
fobj = writeIO(header + "\n" + test)
fromConfig(fobj, data)
@pytest.mark.parametrize(
"func_string", [k for k, v in ENVIRONMENT.items() if callable(v)]
)
def test_funtionArguments(data, func_string):
@flagging()
def testFunction(saqc, field, func, **kwargs):
assert func is ENVIRONMENT[func_string]
return saqc
config = f"""
varname ; test
{data.columns[0]} ; testFunction(func={func_string})
{data.columns[0]} ; testFunction(func="{func_string}")
"""
fromConfig(writeIO(config), data)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment