Hello community,

here is the log from the commit of package python-asteval for openSUSE:Factory 
checked in at 2019-03-06 15:52:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-asteval (Old)
 and      /work/SRC/openSUSE:Factory/.python-asteval.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-asteval"

Wed Mar  6 15:52:29 2019 rev:3 rq:682133 version:0.9.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-asteval/python-asteval.changes    
2018-08-31 10:45:19.567266102 +0200
+++ /work/SRC/openSUSE:Factory/.python-asteval.new.28833/python-asteval.changes 
2019-03-06 15:52:38.628420863 +0100
@@ -1,0 +2,7 @@
+Wed Mar  6 12:17:43 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update 0.9.13:
+  * Various spelling fixes
+  * Error reporting tweaks
+
+-------------------------------------------------------------------

Old:
----
  asteval-0.9.12.tar.gz

New:
----
  asteval-0.9.13.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-asteval.spec ++++++
--- /var/tmp/diff_new_pack.0PJ7VE/_old  2019-03-06 15:52:40.100420568 +0100
+++ /var/tmp/diff_new_pack.0PJ7VE/_new  2019-03-06 15:52:40.100420568 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-asteval
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,31 +12,30 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-asteval
-Version:        0.9.12
+Version:        0.9.13
 Release:        0
 Summary:        Safe, minimalistic evaluator of python expression using ast 
module
 License:        MIT
 Group:          Development/Languages/Python
-Url:            http://github.com/newville/asteval
+URL:            http://github.com/newville/asteval
 Source:         
https://files.pythonhosted.org/packages/source/a/asteval/asteval-%{version}.tar.gz
 BuildRequires:  %{python_module setuptools}
-# SECTION test requirements
-BuildRequires:  %{python_module numpy >= 1.6}
-BuildRequires:  %{python_module pytest}
-BuildRequires:  %{python_module six}
-# /SECTION
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Requires:       python-numpy >= 1.6
 Requires:       python-six
 BuildArch:      noarch
-
+# SECTION test requirements
+BuildRequires:  %{python_module numpy >= 1.6}
+BuildRequires:  %{python_module pytest}
+BuildRequires:  %{python_module six}
+# /SECTION
 %python_subpackages
 
 %description
@@ -62,9 +61,7 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-pushd tests
-%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} 
py.test-%{$python_bin_suffix}
-popd
+%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} 
py.test-%{$python_bin_suffix} -v
 
 %files %{python_files}
 %doc README.rst

++++++ asteval-0.9.12.tar.gz -> asteval-0.9.13.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/PKG-INFO new/asteval-0.9.13/PKG-INFO
--- old/asteval-0.9.12/PKG-INFO 2018-03-08 23:09:06.000000000 +0100
+++ new/asteval-0.9.13/PKG-INFO 2018-09-29 15:15:38.000000000 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 1.1
 Name: asteval
-Version: 0.9.12
+Version: 0.9.13
 Summary: Safe, minimalistic evaluator of python expression using ast module
 Home-page: http://github.com/newville/asteval
 Author: Matthew Newville
 Author-email: [email protected]
 License: MIT
-Description-Content-Type: UNKNOWN
 Description: ASTEVAL provides a numpy-aware, safe(ish) 'eval' function
         
         Emphasis is on mathematical expressions, and so numpy ufuncs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/asteval/__init__.py 
new/asteval-0.9.13/asteval/__init__.py
--- old/asteval-0.9.12/asteval/__init__.py      2018-03-08 23:07:09.000000000 
+0100
+++ new/asteval-0.9.13/asteval/__init__.py      2018-09-29 15:08:22.000000000 
+0200
@@ -9,8 +9,8 @@
    Expressions can be compiled into ast node for later evaluation,
    using the values in the symbol table current at evaluation time.
 
-   version: 0.9.12
-   last update: 2018-March-8
+   version: 0.9.13
+   last update: 2018-Sept-29
    License:  MIT
    Author:  Matthew Newville <[email protected]>
             Center for Advanced Radiation Sources,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/asteval/_version.py 
new/asteval-0.9.13/asteval/_version.py
--- old/asteval-0.9.12/asteval/_version.py      2018-03-08 23:09:06.000000000 
+0100
+++ new/asteval-0.9.13/asteval/_version.py      2018-09-29 15:15:38.000000000 
+0200
@@ -8,11 +8,11 @@
 
 version_json = '''
 {
- "date": "2018-03-08T14:46:40-0600",
+ "date": "2018-09-29T08:08:37-0500",
  "dirty": false,
  "error": null,
- "full-revisionid": "c865690ee5a3f4e7f409fa758eecd23bdbc3ead9",
- "version": "0.9.12"
+ "full-revisionid": "e388a003415cdebc910c3ac10bc5a395d10d9424",
+ "version": "0.9.13"
 }
 '''  # END VERSION_JSON
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/asteval/asteval.py 
new/asteval-0.9.13/asteval/asteval.py
--- old/asteval-0.9.12/asteval/asteval.py       2018-03-08 23:07:09.000000000 
+0100
+++ new/asteval-0.9.13/asteval/asteval.py       2018-09-29 15:06:59.000000000 
+0200
@@ -107,13 +107,17 @@
     no_print : bool
         whether to support `print`.
     max_time : float
-        deprecated.  max run time in seconds (see Note 2) [30.0]
+        deprecated, unreliable. max_time will be dropped soon. (default 86400)
+    readonly_symbols : iterable or `None`
+        symbols that the user can not assign to
+    builtins_readonly : bool
+        whether to blacklist all symbols that are in the initial symtable
 
     Notes
     -----
     1. setting `minimal=True` is equivalent to setting all
        `no_***` options to `True`.
-    2. max_time is not reliable and support may be dropped soon.
+    2. max_time is not reliable and no longer supported -- the keyword will be 
dropped soon.
     """
 
     def __init__(self, symtable=None, usersyms=None, writer=None,
@@ -121,7 +125,8 @@
                  no_if=False, no_for=False, no_while=False, no_try=False,
                  no_functiondef=False, no_ifexp=False, no_listcomp=False,
                  no_augassign=False, no_assert=False, no_delete=False,
-                 no_raise=False, no_print=False, max_time=30):
+                 no_raise=False, no_print=False, max_time=86400,
+                 readonly_symbols=None, builtins_readonly=False):
 
         self.writer = writer or stdout
         self.err_writer = err_writer or stderr
@@ -180,6 +185,14 @@
             self.node_handlers['tryexcept'] = self.node_handlers['try']
             self.node_handlers['tryfinally'] = self.node_handlers['try']
 
+        if readonly_symbols is None:
+            self.readonly_symbols = set()
+        else:
+            self.readonly_symbols = set(readonly_symbols)
+
+        if builtins_readonly:
+            self.readonly_symbols |= set(self.symtable)
+
         self.no_deepcopy = [key for key, val in symtable.items()
                             if (callable(val)
                                 or 'numpy.lib.index_tricks' in repr(val)
@@ -237,9 +250,9 @@
         self._interrupt = ast.Break()
         self.error.append(err)
         if self.error_msg is None:
-            self.error_msg = "%s in expr='%s'" % (msg, self.expr)
+            self.error_msg = "at expr='%s'" % (self.expr)
         elif len(msg) > 0:
-            self.error_msg = "%s\n %s" % (self.error_msg, msg)
+            self.error_msg = msg
         if exc is None:
             try:
                 exc = self.error[0].exc
@@ -450,7 +463,7 @@
 
         """
         if node.__class__ == ast.Name:
-            if not valid_symbol_name(node.id):
+            if not valid_symbol_name(node.id) or node.id in 
self.readonly_symbols:
                 errmsg = "invalid symbol name (reserved word?) %s" % node.id
                 self.raise_exception(node, exc=NameError, msg=errmsg)
             self.symtable[node.id] = val
@@ -553,7 +566,7 @@
                 children.append(tnode.attr)
                 tnode = tnode.value
 
-            if tnode.__class__ == ast.Name:
+            if tnode.__class__ == ast.Name and tnode.id not in 
self.readonly_symbols:
                 children.append(tnode.id)
                 children.reverse()
                 self.symtable.pop('.'.join(children))
@@ -704,6 +717,7 @@
                         for tline in hnd.body:
                             self.run(tline)
                         break
+                break
         if no_errors and hasattr(node, 'orelse'):
             for tnode in node.orelse:
                 self.run(tnode)
@@ -756,8 +770,10 @@
 
         try:
             return func(*args, **keywords)
-        except:
-            self.raise_exception(node, msg="Error running %s" % (func))
+        except Exception as ex:
+            self.raise_exception(
+                node, msg="Error running function call '%s' with args %s and "
+                "kwargs %s: %s" % (func.__name__, args, keywords, ex))
 
     def on_arg(self, node):    # ('test', 'msg')
         """Arg for function definitions."""
@@ -770,6 +786,10 @@
             raise Warning("decorated procedures not supported!")
         kwargs = []
 
+        if not valid_symbol_name(node.name) or node.name in 
self.readonly_symbols:
+            errmsg = "invalid function name (reserved word?) %s" % node.name
+            self.raise_exception(node, exc=NameError, msg=errmsg)
+
         offset = len(node.args.args) - len(node.args.defaults)
         for idef, defnode in enumerate(node.args.defaults):
             defval = self.run(defnode)
@@ -817,6 +837,7 @@
         """TODO: docstring in public method."""
         self.__ininit__ = True
         self.name = name
+        self.__name__ = self.name
         self.__asteval__ = interp
         self.raise_exc = self.__asteval__.raise_exception
         self.__doc__ = doc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/asteval.egg-info/PKG-INFO 
new/asteval-0.9.13/asteval.egg-info/PKG-INFO
--- old/asteval-0.9.12/asteval.egg-info/PKG-INFO        2018-03-08 
23:09:06.000000000 +0100
+++ new/asteval-0.9.13/asteval.egg-info/PKG-INFO        2018-09-29 
15:15:38.000000000 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 1.1
 Name: asteval
-Version: 0.9.12
+Version: 0.9.13
 Summary: Safe, minimalistic evaluator of python expression using ast module
 Home-page: http://github.com/newville/asteval
 Author: Matthew Newville
 Author-email: [email protected]
 License: MIT
-Description-Content-Type: UNKNOWN
 Description: ASTEVAL provides a numpy-aware, safe(ish) 'eval' function
         
         Emphasis is on mathematical expressions, and so numpy ufuncs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/asteval.egg-info/SOURCES.txt 
new/asteval-0.9.13/asteval.egg-info/SOURCES.txt
--- old/asteval-0.9.12/asteval.egg-info/SOURCES.txt     2018-03-08 
23:09:06.000000000 +0100
+++ new/asteval-0.9.13/asteval.egg-info/SOURCES.txt     2018-09-29 
15:15:38.000000000 +0200
@@ -23,4 +23,6 @@
 doc/motivation.rst
 doc/_static/empty
 doc/_templates/indexsidebar.html
+tests/A.py
+tests/m.py
 tests/test_asteval.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/doc/motivation.rst 
new/asteval-0.9.13/doc/motivation.rst
--- old/asteval-0.9.12/doc/motivation.rst       2018-03-08 23:07:09.000000000 
+0100
+++ new/asteval-0.9.13/doc/motivation.rst       2018-09-29 15:06:59.000000000 
+0200
@@ -106,6 +106,16 @@
 without knowing the values of `x`, `y`, and `z`.   In short, runtime cannot
 be determined lexically.
 
+Unfortunately, there is not a good way to check for a long-running
+calculation within a single Python process.  For example, the double
+exponential example above will be stuck deep inside C-code evaluated by the
+Python interpreter itself, and will not return or allow other threads to
+run until that calculation is done.  That is, from within a single process,
+there is not a foolproof way to tell `asteval` when a calculation has taken
+too long.  The most reliable way to limit run time is to have a second
+process watching the execution time of the asteval process and interrupt
+or kill it.
+
 For a limited range of problems, you can try to avoid asteval taking too
 long.  For example, you may try to limit the *recursion limit* when
 executing expressions, with a code like this::
@@ -124,17 +134,15 @@
     with limited_recursion(100):
         Interpreter().eval(...)
 
-You can also pass in a `max_time` (in seconds) when you create an asteval
-Interpreter, wich will try to limit the amount of time an expression will
-take.  This is actually of limited utility, since the calculation must
-return to the asteval interpreter for the runtime to be checked at all.  Many
-long-running calculations will be stuck deep inside C-code evaluated by the
-Python interpreter itself, and not return or allow other threads to run
-until that calculation is done. That is, from within a single process,
-there really is not a foolproof way to tell asteval to have a maximum
-runtime.  The most reliable way to put a firm limit on runtime is to have a
-second process watching the execution time of the asteval process and
-interrupt or kill it.
+As an addition security concern, the default list of supported functions
+does include Python's `open()` which will allow disk access to the
+untrusted user.  If `numpy` is supported, its `load()` and `loadtxt()`
+functions will also be supported.  This doesn't really elevate permissions,
+but it does allow the user of the `asteval` interpreter to read files with
+the privileges of the calling program.  In some cases, this may not be
+desireable, and you may want to remove some of these functions from the
+symbol table, re-implement them, or ensure that your program cannot access
+information on disk that should be kept private.
 
 In summary, while asteval attempts to be safe and is definitely safer than
 using :py:func:`eval`, there are many ways that asteval could be considered
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/tests/A.py 
new/asteval-0.9.13/tests/A.py
--- old/asteval-0.9.12/tests/A.py       1970-01-01 01:00:00.000000000 +0100
+++ new/asteval-0.9.13/tests/A.py       2018-09-21 02:52:44.000000000 +0200
@@ -0,0 +1,18 @@
+import sys
+from asteval import Interpreter
+aeval = Interpreter()
+
+script = """
+def tmp(x):
+    return tmp(x+1)
+##
+"""
+
+aeval(script)
+
+for rec_limit in (50, 100, 200, 500, 1000, 2000, 5000, 10000):
+    sys.setrecursionlimit(rec_limit)
+    aeval('tmp(33)')
+    msg = aeval.error_msg
+    if msg is not None:
+        print("rec limit=%d, length of error messge=%d" % (rec_limit,  
len(msg)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/tests/m.py 
new/asteval-0.9.13/tests/m.py
--- old/asteval-0.9.12/tests/m.py       1970-01-01 01:00:00.000000000 +0100
+++ new/asteval-0.9.13/tests/m.py       2018-09-21 02:33:45.000000000 +0200
@@ -0,0 +1,8 @@
+from asteval import Interpreter
+
+aeval = Interpreter()
+
+text = """
+def foo():
+    return foo()
+"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asteval-0.9.12/tests/test_asteval.py 
new/asteval-0.9.13/tests/test_asteval.py
--- old/asteval-0.9.12/tests/test_asteval.py    2018-03-08 23:07:09.000000000 
+0100
+++ new/asteval-0.9.13/tests/test_asteval.py    2018-09-29 15:06:59.000000000 
+0200
@@ -16,6 +16,8 @@
 PY3 = version_info[0] == 3
 PY33Plus = PY3 and version_info[1] >= 3
 PY35Plus = PY3 and version_info[1] >= 5
+PY35     = PY3 and version_info[1] == 5
+PY36Plus = PY3 and version_info[1] >= 6
 
 if PY3:
     # noinspection PyUnresolvedReferences
@@ -616,6 +618,16 @@
             """))
         self.isvalue('x', -1)
 
+        self.interp(textwrap.dedent("""
+            x = 15
+            try:
+                raise Exception()
+                x = 20
+            except:
+                pass
+            """))
+        self.isvalue('x', 15)
+
     def test_tryelsefinally(self):
 
         self.interp(textwrap.dedent("""
@@ -816,14 +828,20 @@
         self.interp('open("foo3", "rb", 2<<18)')
         self.check_error('RuntimeError')
 
-    def test_dos(self):
+    def test_recursionlimit(self):
+        self.interp("""def foo(): return foo()\nfoo()""")
+        if PY35Plus:
+            self.check_error('RecursionError')
+        else:
+            self.check_error('RuntimeError')
+
+    def test_runtime(self):
         self.interp.max_time = 3
         self.interp("""for x in range(2<<21): pass""")
         self.check_error('RuntimeError', 'time limit')
         self.interp("""while True: pass""")
         self.check_error('RuntimeError', 'time limit')
-        self.interp("""def foo(): return foo()\nfoo()""")
-        self.check_error('RecursionError' if PY35Plus else 'RuntimeError')
+
 
     def test_kaboom(self):
         """ test Ned Batchelder's 'Eval really is dangerous' - Kaboom test 
(and related tests)"""
@@ -905,6 +923,60 @@
         assert_allclose(x2, 0.866025, rtol=0.001)
         assert_allclose(x3, 1.00,     rtol=0.001)
 
+    def test_readonly_symbols(self):
+
+        def foo():
+            return 31
+
+
+        usersyms = {
+            "a": 10,
+            "b": 11,
+            "c": 12,
+            "d": 13,
+            "foo": foo,
+            "bar": foo,
+            "x": 5,
+            "y": 7
+        }
+
+        aeval = Interpreter(usersyms=usersyms, readonly_symbols={"a", "b", 
"c", "d", "foo", "bar"})
+
+        aeval("a = 20")
+        aeval("def b(): return 100")
+        aeval("c += 1")
+        aeval("del d")
+        aeval("def foo(): return 55")
+        aeval("bar = None")
+        aeval("x = 21")
+        aeval("y += a")
+
+        assert(aeval("a") == 10)
+        assert(aeval("b") == 11)
+        assert(aeval("c") == 12)
+        assert(aeval("d") == 13)
+        assert(aeval("foo()") == 31)
+        assert(aeval("bar()") == 31)
+        assert(aeval("x") == 21)
+        assert(aeval("y") == 17)
+
+
+        assert(aeval("abs(8)") == 8)
+        assert(aeval("abs(-8)") == 8)
+        aeval("def abs(x): return x*2")
+        assert(aeval("abs(8)") == 16)
+        assert(aeval("abs(-8)") == -16)
+
+        aeval2 = Interpreter(builtins_readonly=True)
+
+        assert(aeval2("abs(8)") == 8)
+        assert(aeval2("abs(-8)") == 8)
+        aeval2("def abs(x): return x*2")
+        assert(aeval2("abs(8)") == 8)
+        assert(aeval2("abs(-8)") == 8)
+
+
+
 
 
 class TestCase2(unittest.TestCase):


Reply via email to