diff --git a/README.md b/README.md index 0694664..87b1dd9 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,11 @@ from py2vega import py2vega, Variable py2vega('3 if value > 0 else 4', whitelist=['value']) # Returns "value > 0 ? 3 : 4" py2vega('3 if my_variable > 0 else 4', whitelist=['value']) # Raises a SyntaxError, `my_variable` is not whitelisted + +# Allow any member access on `value` +py2vega('3 if value.member1 > value.member2 else 4', whitelist=[Variable('value')]) # Returns "value.member1 > value.member2 ? 3 : 4" + +# Restrict member access explicitly py2vega('3 if value.member1 > value.member2 else 4', whitelist=[Variable('value', ['member1', 'member2'])]) # Returns "value.member1 > value.member2 ? 3 : 4" py2vega('3 if value.member3 > 0 else 4', whitelist=[Variable('value', ['member1', 'member2'])]) # Raises a SyntaxError, `value.member3` is not whitelisted` ``` diff --git a/py2vega/main.py b/py2vega/main.py index ae2740e..0ec64d9 100644 --- a/py2vega/main.py +++ b/py2vega/main.py @@ -12,8 +12,13 @@ class Variable(): """Helper class for defining a variable in whitelisting.""" - def __init__(self, name, members): - """Construct a Variable, given its name and available members.""" + def __init__(self, name, members=None): + """Construct a Variable, given its name and available members. + + If members is None, all direct members are allowed. This is useful for + dynamic objects such as Vega's `datum`, where available field names are + data-dependent and not known ahead of time.""" + self.name = name self.members = members @@ -76,6 +81,9 @@ def validate(nodes, origin_node): def valid_attribute_impl(node, var): """Check the attribute access validity. Returns True if the member access is valid, False otherwise.""" + if var.members is None: + return True + if node.value.id == var.name and node.attr in var.members: return True diff --git a/test/test_py2vega.py b/test/test_py2vega.py index 4935c65..bb270f0 100644 --- a/test/test_py2vega.py +++ b/test/test_py2vega.py @@ -174,6 +174,9 @@ def test_attribute(): assert py2vega('3 if value.member1 > value.member2 else 4', whitelist=[Variable('value', ['member1', 'member2'])]) == "((value.member1 > value.member2) ? 3 : 4)" + # Variable without explicit members# Variable without explicit members + assert py2vega("'red' if datum.code > 80 else 'blue'", whitelist=[Variable("datum")], ) == "((datum.code > 80) ? 'red' : 'blue')" + # Nested member access whitelisted_vars = [Variable('nested_var', [Variable('var', ['test']), 'x'])]