Check symbol names
[linpy.git] / linpy / linexprs.py
index 82d75d0..834c3b4 100644 (file)
@@ -348,7 +348,10 @@ class LinExpr:
         # add implicit multiplication operators, e.g. '5x' -> '5*x'
         string = LinExpr._RE_NUM_VAR.sub(r'\1*\2', string)
         tree = ast.parse(string, 'eval')
-        return cls._fromast(tree)
+        expr = cls._fromast(tree)
+        if not isinstance(expr, cls):
+            raise SyntaxError('invalid syntax')
+        return expr
 
     def __repr__(self):
         string = ''
@@ -453,8 +456,13 @@ class Symbol(LinExpr):
         """
         if not isinstance(name, str):
             raise TypeError('name must be a string')
+        node = ast.parse(name)
+        try:
+            name = node.body[0].value.id
+        except (AttributeError, SyntaxError):
+            raise SyntaxError('invalid syntax')
         self = object().__new__(cls)
-        self._name = name.strip()
+        self._name = name
         self._coefficients = {self: Fraction(1)}
         self._constant = Fraction(0)
         self._symbols = (self,)
@@ -493,16 +501,6 @@ class Symbol(LinExpr):
         """
         return Dummy(self.name)
 
-    @classmethod
-    def _fromast(cls, node):
-        if isinstance(node, ast.Module) and len(node.body) == 1:
-            return cls._fromast(node.body[0])
-        elif isinstance(node, ast.Expr):
-            return cls._fromast(node.value)
-        elif isinstance(node, ast.Name):
-            return Symbol(node.id)
-        raise SyntaxError('invalid syntax')
-
     def __repr__(self):
         return self.name