Coverage for gws-app/gws/plugin/model_value/expression/__init__.py: 0%
31 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
1"""Expression value.
3Computes the value by evaluating a Python expression. The expression is
4compiled at configuration time; a syntax error is a configuration error.
6The following variables are available in the expression:
8- ``app``: the Application object,
9- ``user``: the current user,
10- ``project``: the current project,
11- ``feature``: the feature the value is computed for,
12- ``mc``: the ``gws.ModelContext`` object,
13- ``date``: the ``gws.lib.datetimex`` module.
15Additional modules can be made available with the ``imports`` option, a list
16of module names, e.g. ``["math", "os"]``. Each module is available under its
17name. If a module cannot be imported or the evaluation fails, the error is
18logged and the value is None.
20Example::
22 fields+ {
23 name "area_ha"
24 type "float"
25 values+ {
26 type "expression"
27 expression "round(feature.get('area_m2', 0) / 10000, 2)"
28 }
29 }
30"""
32from typing import Optional
33import gws
34import gws.base.model.value
35import gws.lib.datetimex
38@gws.ext.config.modelValue('expression')
39class Config(gws.base.model.value.Config):
40 """Value computed by a Python expression."""
42 expression: str
43 """Python expression to evaluate."""
45 imports: Optional[list[str]]
46 """Additional Python modules available to the expression."""
49@gws.ext.object.modelValue('expression')
50class Object(gws.base.model.value.Object):
51 """Expression value object."""
53 expression: str
54 """Python expression to evaluate."""
55 imports: list[str]
56 """Names of modules imported for the expression."""
58 def configure(self):
59 self.expression = (self.cfg('expression') or '').strip()
60 self.imports = self.cfg('imports') or []
61 try:
62 compile(self.expression, 'expression', 'eval')
63 except Exception as exc:
64 raise gws.ConfigurationError(f'invalid expression: {exc!r}') from exc
66 def compute(self, field, feature, mc):
67 context = {
68 'app': self.root.app,
69 'user': mc.user,
70 'project': mc.project,
71 'feature': feature,
72 'mc': mc,
73 'date': gws.lib.datetimex,
74 }
75 for mod in self.imports:
76 try:
77 context[mod] = __import__(mod)
78 except ImportError as exc:
79 gws.log.error(f'failed to import module {mod!r}: {exc!r}')
80 return
82 try:
83 return eval(self.expression, context)
84 except Exception as exc:
85 gws.log.error(f'failed to compute expression: {exc!r}')