Skip to content

Commit

Permalink
ENH: implement variables substitution in configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
dnicolodi committed Sep 6, 2023
1 parent 6c720bb commit a51d22b
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions mesonpy/_substitutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-FileCopyrightText: 2023 The meson-python developers
#
# SPDX-License-Identifier: MIT

from __future__ import annotations

import ast
import functools
import operator

from typing import Any, Dict


class Interpreter:

_operators = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
}

def __init__(self, variables: Dict[str, Any]):
self._variables = variables

def eval(self, string: str) -> Any:
expr = ast.parse(string, mode='eval')
return self._eval(expr)

__getitem__ = eval

@functools.singledispatchmethod
def _eval(self, node: ast.Node) -> Any:
print(node, type(node))
raise ValueError

@_eval.register
def _expression(self, node: ast.Expression) -> Any:
return self._eval(node.body)

@_eval.register
def _binop(self, node: ast.BinOp) -> Any:
func = self._operators.get(type(node.op))
if func is None:
raise ValueError(node.op)
return func(self._eval(node.left), self._eval(node.right))

@_eval.register
def _constant(self, node: ast.Constant) -> Any:
return node.value

@_eval.register
def _variable(self, node: ast.Name) -> Any:
value = self._variables.get(node.id)
if value is None:
raise ValueError
return value


def interpolate(string, **variables):
return string % Interpreter(variables)

0 comments on commit a51d22b

Please sign in to comment.