From 24b7682f6b36c74eb3e9baaa74d4eabf77143cff Mon Sep 17 00:00:00 2001 From: Rafal Skolasinski <r.j.skolasinski@gmail.com> Date: Sun, 3 Dec 2017 12:13:09 +0100 Subject: [PATCH] continuum: check if symbol names are valid identifiers A regression in Sympy causes symbols that are invalid identifiers to be created, e.g. '-B_x'. While we cannot fix Sympy's behaviour, we can at least shield our users from its quirks. Closes #179. --- kwant/continuum/discretizer.py | 10 ++++++++++ kwant/continuum/tests/test_discretizer.py | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/kwant/continuum/discretizer.py b/kwant/continuum/discretizer.py index cac78399..119a4c11 100644 --- a/kwant/continuum/discretizer.py +++ b/kwant/continuum/discretizer.py @@ -6,6 +6,7 @@ # the file AUTHORS.rst at the top-level directory of this distribution and at # http://kwant-project.org/authors. +from keyword import iskeyword from collections import defaultdict import itertools @@ -598,6 +599,15 @@ def _builder_value(expr, coords, grid_spacing, onsite, # as arguments to the value function arg_names = set.union({s.name for s in const_symbols}, {str(k.func) for k in map_func_calls}) + + # check if all argument names are valid python identifiers + for name in arg_names: + if not (name.isidentifier() and not iskeyword(name)): + raise ValueError("Invalid name in used symbols: {}\n" + "Names of symbols used in Hamiltonian " + "must be valid Python identifiers and " + "may not be keywords".format(name)) + arg_names = ', '.join(sorted(arg_names)) if (not arg_names) and (coords is None): diff --git a/kwant/continuum/tests/test_discretizer.py b/kwant/continuum/tests/test_discretizer.py index 98a5cec8..47efbe3a 100644 --- a/kwant/continuum/tests/test_discretizer.py +++ b/kwant/continuum/tests/test_discretizer.py @@ -509,3 +509,16 @@ def test_numeric_functions_with_parameter(): rhs = f_num assert np.allclose(lhs, rhs) + + +@pytest.mark.parametrize('name', [ + '1', + '1a', + '-a', + '+a', + 'while', + 'for' +]) +def test_check_symbol_names(name): + with pytest.raises(ValueError): + discretize(sympy.Symbol(name), 'x') -- GitLab