Skip to content

parameterspace.utils

extract_lambda_information(source_lines)

[summary]

Parameters:

Name Type Description Default
source_lines Iterable

[description]

required

Exceptions:

Type Description
RuntimeError

If function definition is not a valid Lambda function.

Returns:

Type Description
Tuple[list, str]

[description]

Source code in parameterspace/utils.py
def extract_lambda_information(source_lines: Iterable) -> Tuple[list, str]:
    """[summary]

    Args:
        source_lines: [description]

    Raises:
        RuntimeError: If function definition is not a valid Lambda function.

    Returns:
        [description]
    """
    condensed_code = "".join(source_lines).replace(os.linesep, "")  # join lines
    condensed_code = " ".join(
        condensed_code.split()
    )  # replace multiple spaces by a single one

    try:
        signature, body = condensed_code.split("lambda")[1].split(":")
    except IndexError as e:
        raise RuntimeError(
            "The function definition does not look like a valid Lambda function:\n"
            + "".join(source_lines)
        ) from e

    while len(body) > 1:
        lambda_def = f"lambda {signature}: {body}"
        try:
            _ = compile(lambda_def, "<unused filename>", "eval")
            break
        except SyntaxError:
            body = body[:-1]

    variables = [s.strip() for s in signature.split(",")]

    return variables, body.strip().rstrip(",")

store_init_arguments(init_method)

Stores init arguments (including keyword arguments) and auto converts numpy.ndarrays to lists for json serializability.

Parameters:

Name Type Description Default
init_method Callable

[description]

required

Returns:

Type Description
Callable

[description]

Source code in parameterspace/utils.py
def store_init_arguments(init_method: Callable) -> Callable:
    """Stores init arguments (including keyword arguments) and auto converts
    `numpy.ndarray`s to `list`s for json serializability.

    Args:
        init_method: [description]

    Returns:
        [description]
    """

    @wraps(init_method)
    def wrapper(self, *args, **kwargs):
        args = [a.tolist() if isinstance(a, np.ndarray) else a for a in args]

        for k, k_value in kwargs.items():
            if isinstance(k_value, np.ndarray):
                kwargs[k] = k_value.tolist()

        self._init_args = args
        self._init_kwargs = kwargs
        init_method(self, *args, **kwargs)

    return wrapper

verify_lambda(variables, body)

Check serialized lambda expression for malicious code.

Parameters:

Name Type Description Default
variables list

[description]

required
body str

[description]

required

Returns:

Type Description
bool

[description]

Source code in parameterspace/utils.py
def verify_lambda(variables: list, body: str) -> bool:
    """Check serialized lambda expression for malicious code.

    Args:
        variables: [description]
        body: [description]

    Returns:
        [description]
    """

    if len(body) > 200:
        return False

    if "eval(" in body:
        return False

    blacklisted_characters = "\\;"

    for c in blacklisted_characters:
        if c in body:
            return False

    white_listed_chars = ".0123456789+-*/()<=!> "
    white_listed_functions = [
        "math.sin",
        "math.cos",
        "math.exp",
        "math.log",
        "or",
        "and",
        "not",
    ]

    for vn in variables:
        body = body.replace(vn, "")

    for fn in white_listed_functions:
        body = body.replace(fn, "")

    for c in white_listed_chars:
        body = body.replace(c, "")

    # remove all single quoted strings
    matches = re.findall(r"\'(.+?)\'", body)
    for m in matches:
        body = body.replace("'" + m + "'", "")

    # remove all double quoted strings
    matches = re.findall(r"\"(.+?)\"", body)
    for m in matches:
        body = body.replace('"' + m + '"', "")

    if len(body) > 0:
        print("body:", body)
        return False

    return True