summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-06 16:06:37 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-06 17:20:51 +0900
commit1b4307f1baaf36e44a95154861e99d822c2f7e43 (patch)
treeed52e56179e1e05198bb119e3a421b9b3bb5c914
parent09e520166547eef03cbb3ca996f9ae42edc671ec (diff)
downloadbuildstream-1b4307f1baaf36e44a95154861e99d822c2f7e43.tar.gz
_yaml.py: Added assert_symbol_name() helper function.
This function asserts that a loaded symbol name is a valid one, and raises an appropriate and consistent LoadError if an invalid symbol name is encountered.
-rw-r--r--buildstream/_yaml.py45
1 files changed, 45 insertions, 0 deletions
diff --git a/buildstream/_yaml.py b/buildstream/_yaml.py
index 2f8a2921d..85410caf2 100644
--- a/buildstream/_yaml.py
+++ b/buildstream/_yaml.py
@@ -20,6 +20,7 @@
import sys
import collections
+import string
from copy import deepcopy
from contextlib import ExitStack
@@ -1015,3 +1016,47 @@ def list_final_assertions(values):
node_final_assertions(value)
elif isinstance(value, list):
list_final_assertions(value)
+
+
+# assert_symbol_name()
+#
+# A helper function to check if a loaded string is a valid symbol
+# name and to raise a consistent LoadError if not. For strings which
+# are required to be symbols.
+#
+# Args:
+# provenance (Provenance): The provenance of the loaded symbol
+# symbol_name (str): The loaded symbol name
+# purpose (str): The purpose of the string, for an error message
+# allow_dashes (bool): Whether dashes are allowed for this symbol
+#
+# Raises:
+# LoadError: If the symbol_name is invalid
+#
+# Note that dashes are generally preferred for variable names and
+# usage in YAML, but things such as option names which will be
+# evaluated with jinja2 cannot use dashes.
+#
+def assert_symbol_name(provenance, symbol_name, purpose, *, allow_dashes=True):
+ valid_chars = string.digits + string.ascii_letters + '_'
+ if allow_dashes:
+ valid_chars += '-'
+
+ valid = True
+ if not symbol_name:
+ valid = False
+ elif any(x not in valid_chars for x in symbol_name):
+ valid = False
+ elif symbol_name[0] in string.digits:
+ valid = False
+
+ if not valid:
+ detail = "Symbol names must contain only alphanumeric characters, " + \
+ "may not start with a digit, and may contain underscores"
+ if allow_dashes:
+ detail += " or dashes"
+
+ raise LoadError(LoadErrorReason.INVALID_SYMBOL_NAME,
+ "{}: Invalid symbol name for {}: '{}'"
+ .format(provenance, purpose, symbol_name),
+ detail=detail)