[tryton-debian-vcs] simpleeval branch debian updated. debian/0.8.2-2-8-gafa2b0d

Mathias Behrle tryton-debian-vcs at alioth.debian.org
Mon Nov 9 10:39:58 UTC 2015


The following commit has been merged in the debian branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/simpleeval.git;a=commitdiff;h=debian/0.8.2-2-8-gafa2b0d

commit afa2b0db919f96093642bff3336ff99dacdc37b8
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Mon Nov 9 11:14:01 2015 +0100

    Releasing debian version 0.8.7-1.
    
    Signed-off-by: Mathias Behrle <mathiasb at m9s.biz>

diff --git a/debian/changelog b/debian/changelog
index d21cccc..20a57c1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+simpleeval (0.8.7-1) unstable; urgency=medium
+
+  * Merging upstream version 0.8.7.
+  * Updating d/copyright.
+
+ -- Mathias Behrle <mathiasb at m9s.biz>  Mon, 09 Nov 2015 11:13:30 +0100
+
 simpleeval (0.8.5-1) unstable; urgency=medium
 
   * Disabling failing test for python3.2.
commit 8cca74994ca6a22ab95ac72ba8a9f631cff91032
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Mon Nov 9 11:11:25 2015 +0100

    Updating d/copyright.

diff --git a/debian/copyright b/debian/copyright
index 7928ea2..7cc4af3 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,7 +1,7 @@
 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 
 Files: *
-Copyright: 2013-2014 Daniel Fairhead
+Copyright: 2013-2015 Daniel Fairhead
 License: MIT
 
 Files: debian/*
commit d99a2015acf7a0724954e699e2a5556d74e1409d
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Mon Nov 9 11:08:01 2015 +0100

    Merging upstream version 0.8.7.

diff --git a/PKG-INFO b/PKG-INFO
index b3a0e24..d505fd3 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: simpleeval
-Version: 0.8.5
+Version: 0.8.7
 Summary: A simple, safe single expression evaluator library.
 Home-page: https://github.com/danthedeckie/simpleeval
 Author: Daniel Fairhead
 Author-email: danthedeckie at gmail.com
 License: UNKNOWN
-Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.8.5
+Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.8.7
 Description: simpleeval (Simple Eval)
         ========================
         
@@ -193,7 +193,7 @@ Description: simpleeval (Simple Eval)
         ---------------------------
         
         Rather than creating a new evaluator each time, if you are doing a lot of evaluations,
-        you can create a SimpleEval object, and pass it expressions each time (which should be a bit quicker, and certainly more convienient for some use cases): ::
+        you can create a SimpleEval object, and pass it expressions each time (which should be a bit quicker, and certainly more convenient for some use cases): ::
         
             s = SimpleEval()
             s.eval("1 + 1")
diff --git a/README.rst b/README.rst
index 0bfb650..266f0b6 100644
--- a/README.rst
+++ b/README.rst
@@ -184,7 +184,7 @@ Creating an Evaluator Class
 ---------------------------
 
 Rather than creating a new evaluator each time, if you are doing a lot of evaluations,
-you can create a SimpleEval object, and pass it expressions each time (which should be a bit quicker, and certainly more convienient for some use cases): ::
+you can create a SimpleEval object, and pass it expressions each time (which should be a bit quicker, and certainly more convenient for some use cases): ::
 
     s = SimpleEval()
     s.eval("1 + 1")
diff --git a/setup.py b/setup.py
index 2d49312..0e71ef7 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,5 @@
 from setuptools import setup
-__version__ = '0.8.5'
+__version__ = '0.8.7'
 
 setup(
     name = 'simpleeval',
diff --git a/simpleeval.egg-info/PKG-INFO b/simpleeval.egg-info/PKG-INFO
index b3a0e24..d505fd3 100644
--- a/simpleeval.egg-info/PKG-INFO
+++ b/simpleeval.egg-info/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: simpleeval
-Version: 0.8.5
+Version: 0.8.7
 Summary: A simple, safe single expression evaluator library.
 Home-page: https://github.com/danthedeckie/simpleeval
 Author: Daniel Fairhead
 Author-email: danthedeckie at gmail.com
 License: UNKNOWN
-Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.8.5
+Download-URL: https://github.com/danthedeckie/simpleeval/tarball/0.8.7
 Description: simpleeval (Simple Eval)
         ========================
         
@@ -193,7 +193,7 @@ Description: simpleeval (Simple Eval)
         ---------------------------
         
         Rather than creating a new evaluator each time, if you are doing a lot of evaluations,
-        you can create a SimpleEval object, and pass it expressions each time (which should be a bit quicker, and certainly more convienient for some use cases): ::
+        you can create a SimpleEval object, and pass it expressions each time (which should be a bit quicker, and certainly more convenient for some use cases): ::
         
             s = SimpleEval()
             s.eval("1 + 1")
diff --git a/simpleeval.py b/simpleeval.py
index 7f29d2e..81e4193 100644
--- a/simpleeval.py
+++ b/simpleeval.py
@@ -1,5 +1,5 @@
 '''
-SimpleEval - (C) 2013/2014 Daniel Fairhead
+SimpleEval - (C) 2013/2015 Daniel Fairhead
 -------------------------------------
 
 An short, easy to use, safe and reasonably extensible expression evaluator.
@@ -35,7 +35,10 @@ modifications and many improvments.
 
 -------------------------------------
 Contributors:
-corro (Robin Baumgartner) (py3k)
+- corro (Robin Baumgartner) (py3k)
+- dratchkov (David R) (nested dicts)
+- marky1991 (Mark Young) (slicing)
+- T045T (Nils Berg) (!=, py3kstr, obj.attributes)
 
 -------------------------------------
 Usage:
@@ -76,6 +79,7 @@ well:
 '''
 
 import ast
+import sys
 import operator as op
 from random import random
 
@@ -84,6 +88,7 @@ from random import random
 
 MAX_STRING_LENGTH = 100000
 MAX_POWER = 4000000 # highest exponent
+PYTHON3 = sys.version_info[0] == 3
 
 ########################################
 # Exceptions:
@@ -114,6 +119,14 @@ class NameNotDefined(InvalidExpression):
         # pylint: disable=bad-super-call
         super(InvalidExpression, self).__init__(self.message)
 
+class AttributeDoesNotExist(InvalidExpression):
+    '''attribute does not exist'''
+    def __init__(self, attr, expression):
+        self.message = "Attribute '{0}' does not exist in expression '{1}'".format(
+            attr, expression)
+        self.attr = attr
+        self.expression = expression
+ 
 class FeatureNotAvailable(InvalidExpression):
     ''' What you're trying to do is not allowed. '''
     pass
@@ -165,12 +178,12 @@ def safe_add(a, b): # pylint: disable=invalid-name
 
 DEFAULT_OPERATORS = {ast.Add: safe_add, ast.Sub: op.sub, ast.Mult: safe_mult,
                      ast.Div: op.truediv, ast.Pow: safe_power, ast.Mod: op.mod,
-                     ast.Eq: op.eq, ast.Gt: op.gt, ast.Lt: op.lt,
+                     ast.Eq: op.eq, ast.NotEq: op.ne, ast.Gt: op.gt, ast.Lt: op.lt,
                      ast.GtE: op.ge, ast.LtE: op.le, ast.USub: op.neg,
                      ast.UAdd: op.pos}
 
 DEFAULT_FUNCTIONS = {"rand": random, "randint": random_int,
-                     "int": int, "float": float, "str": unicode}
+                     "int": int, "float": float, "str": str if PYTHON3 else unicode}
 
 DEFAULT_NAMES = {"True": True, "False": False}
 
@@ -262,7 +275,13 @@ class SimpleEval(object): # pylint: disable=too-few-public-methods
 
         elif isinstance(node, ast.Name): # a, b, c...
             try:
-                if isinstance(self.names, dict):
+                #This happens at least for slicing
+                #This is a safe thing to do because it is impossible
+                #that there is a true exression assigning to none
+                #(the compiler rejects it, so you can't even pass that to ast.parse)
+                if node.id == "None":
+                    return None
+                elif isinstance(self.names, dict):
                     return self.names[node.id]
                 elif callable(self.names):
                     return self.names(node)
@@ -275,8 +294,34 @@ class SimpleEval(object): # pylint: disable=too-few-public-methods
                 raise NameNotDefined(node.id, self.expr)
 
         elif isinstance(node, ast.Subscript): # b[1]
-            return self._eval(node.value)[self._eval(node.slice.value)]
+            return self._eval(node.value)[self._eval(node.slice)]
+
+        elif isinstance(node, ast.Attribute): # a.b.c
+            try:
+                return self._eval(node.value)[node.attr]
+            except (KeyError, TypeError):
+                pass
 
+            # Maybe the base object is an actual object, not just a dict
+            try:
+                return getattr(self._eval(node.value), node.attr)
+            except (AttributeError, TypeError):
+                pass
+
+            # If it is neither, raise an exception
+            raise AttributeDoesNotExist(node.attr, self.expr)
+
+        elif isinstance(node, ast.Index):
+            return self._eval(node.value)
+        elif isinstance(node, ast.Slice):
+            lower = upper = step = None
+            if node.lower is not None:
+                lower = self._eval(node.lower)
+            if node.upper is not None:
+                upper = self._eval(node.upper)
+            if node.step is not None:
+                step = self._eval(node.step)
+            return slice(lower, upper, step)
         else:
             raise FeatureNotAvailable("Sorry, {0} is not available in this "
                                       "evaluator".format(type(node).__name__ ))
diff --git a/test_simpleeval.py b/test_simpleeval.py
index 6fdf849..ec1689a 100644
--- a/test_simpleeval.py
+++ b/test_simpleeval.py
@@ -7,9 +7,9 @@
 '''
 # pylint: disable=too-many-public-methods, missing-docstring
 
-import unittest
+import unittest, operator, ast
 import simpleeval
-from simpleeval import SimpleEval, NameNotDefined, InvalidExpression, simple_eval
+from simpleeval import SimpleEval, NameNotDefined, InvalidExpression, AttributeDoesNotExist, simple_eval
 
 class DRYTest(unittest.TestCase):
     ''' Stuff we need to do every test, let's do here instead..
@@ -43,6 +43,7 @@ class TestBasic(DRYTest):
         self.t('1 - 1 or 21', True)
         self.t('1 - 1 and 11', False)
         self.t('110 == 100 + 10 and True', True)
+        self.t('110 != 100 + 10 and True', False)
 
     def test_maths_with_floats(self):
         self.t("11.02 - 9.1", 1.92)
@@ -84,7 +85,24 @@ class TestBasic(DRYTest):
 
         self.t('int("20") + int(0.22*100)', 42)
         self.t('float("42")', 42.0)
-        self.t('"Test Stuff!" + str(11)', u"Test Stuff!11")
+        self.t('"Test Stuff!" + str(11)', "Test Stuff!11")
+
+    def test_slicing(self):
+        self.s.operators[ast.Slice] = operator.getslice if hasattr(operator, "getslice") else operator.getitem
+        self.t("'hello'[1]", "e")
+        self.t("'hello'[:]", "hello")
+        self.t("'hello'[:3]", "hel")
+        self.t("'hello'[3:]", "lo")
+        self.t("'hello'[::2]", "hlo")
+        self.t("'hello'[::-1]", "olleh")
+        self.t("'hello'[3::]", "lo")
+        self.t("'hello'[:3:]", "hel")
+        self.t("'hello'[1:3]", "el")
+        self.t("'hello'[1:3:]", "el")
+        self.t("'hello'[1::2]", "el")
+        self.t("'hello'[:1:2]", "h")
+        self.t("'hello'[1:3:1]", "el")
+        self.t("'hello'[1:3:2]", "e")
 
 class TestFunctions(DRYTest):
     ''' Functions for expressions to play with '''
@@ -106,7 +124,7 @@ class TestFunctions(DRYTest):
 
         # simple load:
 
-        self.s.functions = {u"read": load_file}
+        self.s.functions = {"read": load_file}
         self.t("read('file.txt')", "42")
 
         # and we should have *replaced* the default functions. Let's check:
@@ -226,6 +244,11 @@ class TestNames(DRYTest):
         with self.assertRaises(InvalidExpression):
             self.t('s', 21)
 
+        self.s.names = {'a' : {'b': {'c': 42}}}
+
+        with self.assertRaises(AttributeDoesNotExist):
+            self.t('a.b.d**2', 42)
+
 
     def test_dict(self):
         ''' using a normal dict for names lookup '''
@@ -277,6 +300,39 @@ class TestNames(DRYTest):
 
         self.assertEqual(self.s.names['c']['c']['c'], 11)
 
+        # nested dict
+
+        self.s.names = {'a' : {'b': {'c': 42}}}
+
+        self.t("a.b.c*2", 84)
+
+        self.t("a.b.c = 11", 11)
+
+        self.assertEqual(self.s.names['a']['b']['c'], 42)
+
+        self.t("a.d = 11", 11)
+
+        with self.assertRaises(KeyError):
+            self.assertEqual(self.s.names['a']['d'], 11)
+
+    def test_object(self):
+        ''' using an object for name lookp '''
+        class TestObject(object):
+            pass
+        o = TestObject()
+        o.a = 23
+        o.b = 42
+        o.c = TestObject()
+        o.c.d = 9001
+
+        self.s.names = {'o' : o}
+
+        self.t('o', o)
+        self.t('o.a', 23)
+        self.t('o.b + o.c.d', 9043)
+        with self.assertRaises(AttributeDoesNotExist):
+            self.t('o.d', None)
+
     def test_func(self):
         ''' using a function for 'names lookup' '''
 
@@ -319,3 +375,6 @@ class Test_simple_eval(unittest.TestCase):
     def test_default_functions(self):
         self.assertEqual(simple_eval('rand() < 1.0 and rand() > -0.01'), True)
         self.assertEqual(simple_eval('randint(200) < 200 and rand() > 0'), True)
+
+if __name__ == '__main__':
+    unittest.main()
-- 
simpleeval



More information about the tryton-debian-vcs mailing list