simpleeval 1.0.2__tar.gz → 1.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simpleeval-1.0.2 → simpleeval-1.0.3}/PKG-INFO +3 -3
- {simpleeval-1.0.2 → simpleeval-1.0.3}/README.rst +2 -2
- {simpleeval-1.0.2 → simpleeval-1.0.3}/pyproject.toml +1 -1
- {simpleeval-1.0.2 → simpleeval-1.0.3}/simpleeval.py +8 -8
- {simpleeval-1.0.2 → simpleeval-1.0.3}/test_simpleeval.py +5 -5
- {simpleeval-1.0.2 → simpleeval-1.0.3}/.gitignore +0 -0
- {simpleeval-1.0.2 → simpleeval-1.0.3}/LICENCE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: simpleeval
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: A simple, safe single expression evaluator library.
|
|
5
5
|
Project-URL: Source code, https://github.com/danthedeckie/simpleeval
|
|
6
6
|
Author-email: Daniel Fairhead <danthedeckie@gmail.com>
|
|
@@ -239,7 +239,7 @@ which, of course, can be nested:
|
|
|
239
239
|
Functions
|
|
240
240
|
---------
|
|
241
241
|
|
|
242
|
-
You can define functions which you'd like the
|
|
242
|
+
You can define functions which you'd like the expressions to have access to:
|
|
243
243
|
|
|
244
244
|
.. code-block:: pycon
|
|
245
245
|
|
|
@@ -356,7 +356,7 @@ cases):
|
|
|
356
356
|
# and so on...
|
|
357
357
|
|
|
358
358
|
One useful feature of using the ``SimpleEval`` object is that you can parse an expression
|
|
359
|
-
once, and then evaluate it
|
|
359
|
+
once, and then evaluate it multiple times using different ``names``:
|
|
360
360
|
|
|
361
361
|
.. code-block:: python
|
|
362
362
|
|
|
@@ -222,7 +222,7 @@ which, of course, can be nested:
|
|
|
222
222
|
Functions
|
|
223
223
|
---------
|
|
224
224
|
|
|
225
|
-
You can define functions which you'd like the
|
|
225
|
+
You can define functions which you'd like the expressions to have access to:
|
|
226
226
|
|
|
227
227
|
.. code-block:: pycon
|
|
228
228
|
|
|
@@ -339,7 +339,7 @@ cases):
|
|
|
339
339
|
# and so on...
|
|
340
340
|
|
|
341
341
|
One useful feature of using the ``SimpleEval`` object is that you can parse an expression
|
|
342
|
-
once, and then evaluate it
|
|
342
|
+
once, and then evaluate it multiple times using different ``names``:
|
|
343
343
|
|
|
344
344
|
.. code-block:: python
|
|
345
345
|
|
|
@@ -129,7 +129,7 @@ DISALLOW_METHODS = [
|
|
|
129
129
|
]
|
|
130
130
|
|
|
131
131
|
# Disallow functions:
|
|
132
|
-
# This, strictly speaking, is not necessary. These /should/ never be
|
|
132
|
+
# This, strictly speaking, is not necessary. These /should/ never be accessible anyway,
|
|
133
133
|
# if DISALLOW_PREFIXES and DISALLOW_METHODS are all right. This is here to try and help
|
|
134
134
|
# people not be stupid. Allowing these functions opens up all sorts of holes - if any of
|
|
135
135
|
# their functionality is required, then please wrap them up in a safe container. And think
|
|
@@ -254,9 +254,9 @@ def safe_mult(a, b): # pylint: disable=invalid-name
|
|
|
254
254
|
"""limit the number of times an iterable can be repeated..."""
|
|
255
255
|
|
|
256
256
|
if hasattr(a, "__len__") and b * len(a) > MAX_STRING_LENGTH:
|
|
257
|
-
raise IterableTooLong("Sorry, I will not
|
|
257
|
+
raise IterableTooLong("Sorry, I will not evaluate something that long.")
|
|
258
258
|
if hasattr(b, "__len__") and a * len(b) > MAX_STRING_LENGTH:
|
|
259
|
-
raise IterableTooLong("Sorry, I will not
|
|
259
|
+
raise IterableTooLong("Sorry, I will not evaluate something that long.")
|
|
260
260
|
|
|
261
261
|
return a * b
|
|
262
262
|
|
|
@@ -386,13 +386,13 @@ class SimpleEval(object): # pylint: disable=too-few-public-methods
|
|
|
386
386
|
warnings.simplefilter("ignore")
|
|
387
387
|
# py3.12 deprecated ast.Num, ast.Str, ast.NameConstant
|
|
388
388
|
# https://docs.python.org/3.12/whatsnew/3.12.html#deprecated
|
|
389
|
-
if Num := getattr(ast, "Num"):
|
|
389
|
+
if Num := getattr(ast, "Num", None):
|
|
390
390
|
self.nodes[Num] = self._eval_num
|
|
391
391
|
|
|
392
|
-
if Str := getattr(ast, "Str"):
|
|
392
|
+
if Str := getattr(ast, "Str", None):
|
|
393
393
|
self.nodes[Str] = self._eval_str
|
|
394
394
|
|
|
395
|
-
if NameConstant := getattr(ast, "NameConstant"):
|
|
395
|
+
if NameConstant := getattr(ast, "NameConstant", None):
|
|
396
396
|
self.nodes[NameConstant] = self._eval_constant
|
|
397
397
|
|
|
398
398
|
# Defaults:
|
|
@@ -424,7 +424,7 @@ class SimpleEval(object): # pylint: disable=too-few-public-methods
|
|
|
424
424
|
return parsed.body[0]
|
|
425
425
|
|
|
426
426
|
def eval(self, expr, previously_parsed=None):
|
|
427
|
-
"""evaluate an
|
|
427
|
+
"""evaluate an expression, using the operators, functions and
|
|
428
428
|
names previously set up."""
|
|
429
429
|
|
|
430
430
|
# set a copy of the expression aside, so we can give nice errors...
|
|
@@ -763,6 +763,6 @@ class EvalWithCompoundTypes(SimpleEval):
|
|
|
763
763
|
|
|
764
764
|
|
|
765
765
|
def simple_eval(expr, operators=None, functions=None, names=None):
|
|
766
|
-
"""Simply evaluate an
|
|
766
|
+
"""Simply evaluate an expression"""
|
|
767
767
|
s = SimpleEval(operators=operators, functions=functions, names=names)
|
|
768
768
|
return s.eval(expr)
|
|
@@ -39,9 +39,9 @@ class DRYTest(unittest.TestCase):
|
|
|
39
39
|
"""initialize a SimpleEval"""
|
|
40
40
|
self.s = SimpleEval()
|
|
41
41
|
|
|
42
|
-
def t(self, expr,
|
|
42
|
+
def t(self, expr, should_be): # pylint: disable=invalid-name
|
|
43
43
|
"""test an evaluation of an expression against an expected answer"""
|
|
44
|
-
return self.assertEqual(self.s.eval(expr),
|
|
44
|
+
return self.assertEqual(self.s.eval(expr), should_be)
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class TestBasic(DRYTest):
|
|
@@ -207,7 +207,7 @@ class TestBasic(DRYTest):
|
|
|
207
207
|
class TestEvaluator(DRYTest):
|
|
208
208
|
"""Tests for how the SimpleEval class does things"""
|
|
209
209
|
|
|
210
|
-
def
|
|
210
|
+
def test_only_evaluate_first_statement(self):
|
|
211
211
|
# it only evaluates the first statement:
|
|
212
212
|
with warnings.catch_warnings(record=True) as ws:
|
|
213
213
|
warnings.simplefilter("always")
|
|
@@ -1027,7 +1027,7 @@ class TestWhitespace(DRYTest):
|
|
|
1027
1027
|
def test_trailing(self):
|
|
1028
1028
|
self.t("200 + 200 ", 400)
|
|
1029
1029
|
|
|
1030
|
-
def
|
|
1030
|
+
def test_preceding_whitespace(self):
|
|
1031
1031
|
self.t(" 200 + 200", 400)
|
|
1032
1032
|
|
|
1033
1033
|
def test_preceding_tab_whitespace(self):
|
|
@@ -1284,7 +1284,7 @@ class TestDisallowedFunctions(DRYTest):
|
|
|
1284
1284
|
def bar(self):
|
|
1285
1285
|
yield "Hello, world!"
|
|
1286
1286
|
|
|
1287
|
-
# Test the
|
|
1287
|
+
# Test the generator does work - also adds the `yield` to codecov...
|
|
1288
1288
|
assert list(Foo().bar()) == ["Hello, world!"]
|
|
1289
1289
|
|
|
1290
1290
|
evil = "foo.bar().gi_frame.f_globals['__builtins__'].exec('raise RuntimeError(\"Oh no\")')"
|
|
File without changes
|
|
File without changes
|