2024-01-03
Safe Eval In Jinja

1
2
3
4
5
6
7
8
9
10
11
12
from jinja2 import Environment
from jinja2 import StrictUndefined
from jinja2.nativetypes import NativeEnvironment
def simple_eval(expr: str, globals_dict: dict = None):
globals_dict = globals_dict or {}
env = Environment(variable_start_string='${', variable_end_string='}', undefined=StrictUndefined)
template = env.from_string(expr).render(**dict(zip(globals_dict.keys(), globals_dict.keys())))
native_env = NativeEnvironment(undefined=StrictUndefined)
return native_env.from_string('{{' + template + '}}').render(**globals_dict)
if __name__ == '__main__':
print(simple_eval('${a}+1', {'a': 1}) == 2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class NeverUndefined(jinja2.StrictUndefined):
def __init__(self, *args, **kwargs):
# ARGS: ("parameter 'myvar2' was not provided",)
# KWARGS: {'name': 'myvar2'}
if len(args) == 1:
info = args[0]
elif "name" in kwargs.keys():
info = f"Undefined variable '{kwargs['name']}"
else:
infoList = ["Not allowing any undefined variable."]
infoList.append(f"ARGS: {args}")
infoList.append(f"KWARGS: {kwargs}")
info = "\n".join(infoList)
raise Exception(info)

Read More

2023-06-16
Incremental Testing, Build Tools, Cacheing, Logging

how to log error emitted from better-exceptions?


logging tutorial at betterstack & official

other logging libraries: loguru structlog (able to show locals/globals around error)


better-exceptions


to ensure the consistency of tests, you need to collect input/output pairs (and compare with expected/actual output), if it is deterministic.


monkeytype, pytype (by google), runtype (Dispatch)


better assertion


enum class in python


use cache in pytest

use redis lru_cache, put decorators to json serializable functions

use build tools, forcing program to read and write files in the process

type checking using mypy

code static analysis

code formatter like black


tools:

pydoit with “up to date” signals for non-file objectives

scons

ruby rake

Read More