Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-simpleeval for 
openSUSE:Factory checked in at 2026-03-24 18:48:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-simpleeval (Old)
 and      /work/SRC/openSUSE:Factory/.python-simpleeval.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-simpleeval"

Tue Mar 24 18:48:57 2026 rev:12 rq:1342124 version:1.0.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-simpleeval/python-simpleeval.changes      
2026-03-16 14:21:17.659166407 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-simpleeval.new.8177/python-simpleeval.changes
    2026-03-24 18:49:51.832919287 +0100
@@ -1,0 +2,10 @@
+Mon Mar 23 22:55:22 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.0.7:
+  * Performance fixes for problems introduced by security fixes
+    in 1.0.5 / 1.0.6
+- update to 1.0.6:
+  * unable to pass unhashable items as kwargs introduced by
+    security fixes in 1.0.5 this morning.
+
+-------------------------------------------------------------------

Old:
----
  simpleeval-1.0.5.tar.gz

New:
----
  simpleeval-1.0.7.tar.gz

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

Other differences:
------------------
++++++ python-simpleeval.spec ++++++
--- /var/tmp/diff_new_pack.LHolQB/_old  2026-03-24 18:49:52.324939588 +0100
+++ /var/tmp/diff_new_pack.LHolQB/_new  2026-03-24 18:49:52.324939588 +0100
@@ -20,7 +20,7 @@
 %define modname simpleeval
 %{?sle15_python_module_pythons}
 Name:           python-%{modname}
-Version:        1.0.5
+Version:        1.0.7
 Release:        0
 Summary:        A simple, safe single expression evaluator library
 License:        MIT

++++++ simpleeval-1.0.5.tar.gz -> simpleeval-1.0.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/simpleeval-1.0.5/.v2/lib/python3.13/site-packages/docutils/parsers/rst/include/README.rst
 
new/simpleeval-1.0.7/.v2/lib/python3.13/site-packages/docutils/parsers/rst/include/README.rst
--- 
old/simpleeval-1.0.5/.v2/lib/python3.13/site-packages/docutils/parsers/rst/include/README.rst
       2020-02-02 01:00:00.000000000 +0100
+++ 
new/simpleeval-1.0.7/.v2/lib/python3.13/site-packages/docutils/parsers/rst/include/README.rst
       1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-============================================
- ``docutils/parsers/rst/include`` Directory
-============================================
-
-This directory contains standard data files intended for inclusion in
-reStructuredText documents.  To access these files, use the "include"
-directive with the special syntax for standard "include" data files,
-angle brackets around the file name::
-
-    .. include:: <isonum.txt>
-
-See the documentation for the `"include" directive`__ and
-`reStructuredText Standard Definition Files`__ for
-details.
-
-__ https://docutils.sourceforge.io/docs/ref/rst/directives.html#include
-__ https://docutils.sourceforge.io/docs/ref/rst/definitions.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/simpleeval-1.0.5/.v2/lib/python3.13/site-packages/docutils/writers/s5_html/themes/README.rst
 
new/simpleeval-1.0.7/.v2/lib/python3.13/site-packages/docutils/writers/s5_html/themes/README.rst
--- 
old/simpleeval-1.0.5/.v2/lib/python3.13/site-packages/docutils/writers/s5_html/themes/README.rst
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/simpleeval-1.0.7/.v2/lib/python3.13/site-packages/docutils/writers/s5_html/themes/README.rst
    1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-Except where otherwise noted, all files in this
-directory have been released into the Public Domain.
-
-These files are based on files from S5 1.1, released into the Public
-Domain by Eric Meyer.  For further details, please see
-http://www.meyerweb.com/eric/tools/s5/credits.html.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/simpleeval-1.0.5/.v2/lib/python3.13/site-packages/pip/_vendor/README.rst 
new/simpleeval-1.0.7/.v2/lib/python3.13/site-packages/pip/_vendor/README.rst
--- 
old/simpleeval-1.0.5/.v2/lib/python3.13/site-packages/pip/_vendor/README.rst    
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/simpleeval-1.0.7/.v2/lib/python3.13/site-packages/pip/_vendor/README.rst    
    1970-01-01 01:00:00.000000000 +0100
@@ -1,180 +0,0 @@
-================
-Vendoring Policy
-================
-
-* Vendored libraries **MUST** not be modified except as required to
-  successfully vendor them.
-* Vendored libraries **MUST** be released copies of libraries available on
-  PyPI.
-* Vendored libraries **MUST** be available under a license that allows
-  them to be integrated into ``pip``, which is released under the MIT license.
-* Vendored libraries **MUST** be accompanied with LICENSE files.
-* The versions of libraries vendored in pip **MUST** be reflected in
-  ``pip/_vendor/vendor.txt``.
-* Vendored libraries **MUST** function without any build steps such as ``2to3``
-  or compilation of C code, practically this limits to single source 2.x/3.x 
and
-  pure Python.
-* Any modifications made to libraries **MUST** be noted in
-  ``pip/_vendor/README.rst`` and their corresponding patches **MUST** be
-  included ``tools/vendoring/patches``.
-* Vendored libraries should have corresponding ``vendored()`` entries in
-  ``pip/_vendor/__init__.py``.
-
-Rationale
-=========
-
-Historically pip has not had any dependencies except for ``setuptools`` itself,
-choosing instead to implement any functionality it needed to prevent needing
-a dependency. However, starting with pip 1.5, we began to replace code that was
-implemented inside of pip with reusable libraries from PyPI. This brought the
-typical benefits of reusing libraries instead of reinventing the wheel like
-higher quality and more battle tested code, centralization of bug fixes
-(particularly security sensitive ones), and better/more features for less work.
-
-However, there are several issues with having dependencies in the traditional
-way (via ``install_requires``) for pip. These issues are:
-
-**Fragility**
-   When pip depends on another library to function then if for whatever reason
-   that library either isn't installed or an incompatible version is installed
-   then pip ceases to function. This is of course true for all Python
-   applications, however for every application *except* for pip the way you fix
-   it is by re-running pip. Obviously, when pip can't run, you can't use pip to
-   fix pip, so you're left having to manually resolve dependencies and
-   installing them by hand.
-
-**Making other libraries uninstallable**
-   One of pip's current dependencies is the ``requests`` library, for which pip
-   requires a fairly recent version to run.  If pip depended on ``requests`` in
-   the traditional manner, then we'd either have to maintain compatibility with
-   every ``requests`` version that has ever existed (and ever will), OR allow
-   pip to render certain versions of ``requests`` uninstallable. (The second
-   issue, although technically true for any Python application, is magnified by
-   pip's ubiquity; pip is installed by default in Python, in ``pyvenv``, and in
-   ``virtualenv``.)
-
-**Security**
-   This might seem puzzling at first glance, since vendoring has a tendency to
-   complicate updating dependencies for security updates, and that holds true
-   for pip. However, given the *other* reasons for avoiding dependencies, the
-   alternative is for pip to reinvent the wheel itself.  This is what pip did
-   historically. It forced pip to re-implement its own HTTPS verification
-   routines as a workaround for the Python standard library's lack of SSL
-   validation, which resulted in similar bugs in the validation routine in
-   ``requests`` and ``urllib3``, except that they had to be discovered and
-   fixed independently. Even though we're vendoring, reusing libraries keeps
-   pip more secure by relying on the great work of our dependencies, *and*
-   allowing for faster, easier security fixes by simply pulling in newer
-   versions of dependencies.
-
-**Bootstrapping**
-   Currently most popular methods of installing pip rely on pip's
-   self-contained nature to install pip itself. These tools work by bundling a
-   copy of pip, adding it to ``sys.path``, and then executing that copy of pip.
-   This is done instead of implementing a "mini installer" (to reduce
-   duplication); pip already knows how to install a Python package, and is far
-   more battle-tested than any "mini installer" could ever possibly be.
-
-Many downstream redistributors have policies against this kind of bundling, and
-instead opt to patch the software they distribute to debundle it and make it
-rely on the global versions of the software that they already have packaged
-(which may have its own patches applied to it). We (the pip team) would prefer
-it if pip was *not* debundled in this manner due to the above reasons and
-instead we would prefer it if pip would be left intact as it is now.
-
-In the longer term, if someone has a *portable* solution to the above problems,
-other than the bundling method we currently use, that doesn't add additional
-problems that are unreasonable then we would be happy to consider, and possibly
-switch to said method. This solution must function correctly across all of the
-situation that we expect pip to be used and not mandate some external mechanism
-such as OS packages.
-
-
-Modifications
-=============
-
-* ``setuptools`` is completely stripped to only keep ``pkg_resources``.
-* ``pkg_resources`` has been modified to import its dependencies from
-  ``pip._vendor``, and to use the vendored copy of ``platformdirs``
-  rather than ``appdirs``.
-* ``packaging`` has been modified to import its dependencies from
-  ``pip._vendor``.
-* ``CacheControl`` has been modified to import its dependencies from
-  ``pip._vendor``.
-* ``requests`` has been modified to import its other dependencies from
-  ``pip._vendor`` and to *not* load ``simplejson`` (all platforms) and
-  ``pyopenssl`` (Windows).
-* ``platformdirs`` has been modified to import its submodules from 
``pip._vendor.platformdirs``.
-
-Automatic Vendoring
-===================
-
-Vendoring is automated via the `vendoring 
<https://pypi.org/project/vendoring/>`_ tool from the content of
-``pip/_vendor/vendor.txt`` and the different patches in
-``tools/vendoring/patches``.
-Launch it via ``vendoring sync . -v`` (requires ``vendoring>=0.2.2``).
-Tool configuration is done via ``pyproject.toml``.
-
-To update the vendored library versions, we have a session defined in ``nox``.
-The command to upgrade everything is::
-
-    nox -s vendoring -- --upgrade-all --skip urllib3 --skip setuptools
-
-At the time of writing (April 2025) we do not upgrade ``urllib3`` because the
-next version is a major upgrade and will be handled as an independent PR. We 
also
-do not upgrade ``setuptools``, because we only rely on ``pkg_resources``, and
-tracking every ``setuptools`` change is unnecessary for our needs.
-
-
-Managing Local Patches
-======================
-
-The ``vendoring`` tool automatically applies our local patches, but updating,
-the patches sometimes no longer apply cleanly. In that case, the update will
-fail. To resolve this, take the following steps:
-
-1. Revert any incomplete changes in the revendoring branch, to ensure you have
-   a clean starting point.
-2. Run the revendoring of the library with a problem again: ``nox -s vendoring
-   -- --upgrade <library_name>``.
-3. This will fail again, but you will have the original source in your working
-   directory. Review the existing patch against the source, and modify the 
patch
-   to reflect the new version of the source. If you ``git add`` the changes the
-   vendoring made, you can modify the source to reflect the patch file and then
-   generate a new patch with ``git diff``.
-4. Now, revert everything *except* the patch file changes. Leave the modified
-   patch file unstaged but saved in the working tree.
-5. Re-run the vendoring. This time, it should pick up the changed patch file
-   and apply it cleanly. The patch file changes will be committed along with 
the
-   revendoring, so the new commit should be ready to test and publish as a PR.
-
-
-Debundling
-==========
-
-As mentioned in the rationale, we, the pip team, would prefer it if pip was not
-debundled (other than optionally ``pip/_vendor/requests/cacert.pem``) and that
-pip was left intact. However, if you insist on doing so, we have a
-semi-supported method (that we don't test in our CI) and requires a bit of
-extra work on your end in order to solve the problems described above.
-
-1. Delete everything in ``pip/_vendor/`` **except** for
-   ``pip/_vendor/__init__.py`` and ``pip/_vendor/vendor.txt``.
-2. Generate wheels for each of pip's dependencies (and any of their
-   dependencies) using your patched copies of these libraries. These must be
-   placed somewhere on the filesystem that pip can access (``pip/_vendor`` is
-   the default assumption).
-3. Modify ``pip/_vendor/__init__.py`` so that the ``DEBUNDLED`` variable is
-   ``True``.
-4. Upon installation, the ``INSTALLER`` file in pip's own ``dist-info``
-   directory should be set to something other than ``pip``, so that pip
-   can detect that it wasn't installed using itself.
-5. *(optional)* If you've placed the wheels in a location other than
-   ``pip/_vendor/``, then modify ``pip/_vendor/__init__.py`` so that the
-   ``WHEEL_DIR`` variable points to the location you've placed them.
-6. *(optional)* Update the ``pip_self_version_check`` logic to use the
-   appropriate logic for determining the latest available version of pip and
-   prompt the user with the correct upgrade message.
-
-Note that partial debundling is **NOT** supported. You need to prepare wheels
-for all dependencies for successful debundling.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/simpleeval-1.0.5/.v314/lib/python3.14/site-packages/simpleeval-1.0.3.dist-info/licenses/LICENCE
 
new/simpleeval-1.0.7/.v314/lib/python3.14/site-packages/simpleeval-1.0.3.dist-info/licenses/LICENCE
--- 
old/simpleeval-1.0.5/.v314/lib/python3.14/site-packages/simpleeval-1.0.3.dist-info/licenses/LICENCE
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/simpleeval-1.0.7/.v314/lib/python3.14/site-packages/simpleeval-1.0.3.dist-info/licenses/LICENCE
 1970-01-01 01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-simpleeval - Copyright (c) 2013-2024 Daniel Fairhead
-
-(MIT Licence)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/simpleeval-1.0.5/.v314/lib/python3.14/site-packages/simpleeval.py 
new/simpleeval-1.0.7/.v314/lib/python3.14/site-packages/simpleeval.py
--- old/simpleeval-1.0.5/.v314/lib/python3.14/site-packages/simpleeval.py       
2020-02-02 01:00:00.000000000 +0100
+++ new/simpleeval-1.0.7/.v314/lib/python3.14/site-packages/simpleeval.py       
1970-01-01 01:00:00.000000000 +0100
@@ -1,768 +0,0 @@
-"""
-SimpleEval - (C) 2013-2024 Daniel Fairhead
--------------------------------------
-
-An short, easy to use, safe and reasonably extensible expression evaluator.
-Designed for things like in a website where you want to allow the user to
-generate a string, or a number from some other input, without allowing full
-eval() or other unsafe or needlessly complex linguistics.
-
--------------------------------------
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
--------------------------------------
-
-Initial idea copied from J.F. Sebastian on Stack Overflow
-( http://stackoverflow.com/a/9558001/1973500 ) with
-modifications and many improvements.
-
--------------------------------------
-Contributors:
-- corro (Robin Baumgartner) (py3k)
-- dratchkov (David R) (nested dicts)
-- marky1991 (Mark Young) (slicing)
-- T045T (Nils Berg) (!=, py3kstr, obj.
-- perkinslr (Logan Perkins) (.__globals__ or .func_ breakouts)
-- impala2 (Kirill Stepanov) (massive _eval refactor)
-- gk (ugik) (Other iterables than str can DOS too, and can be made)
-- daveisfera (Dave Johansen) 'not' Boolean op, Pycharm, pep8, various other 
fixes
-- xaled (Khalid Grandi) method chaining correctly, double-eval bugfix.
-- EdwardBetts (Edward Betts) spelling correction.
-- charlax (Charles-Axel Dein charlax) Makefile and cleanups
-- mommothazaz123 (Andrew Zhu) f"string" support, Python 3.8 support
-- lubieowoce (Uryga) various potential vulnerabilities
-- JCavallo (Jean Cavallo) names dict shouldn't be modified
-- Birne94 (Daniel Birnstiel) for fixing leaking generators, star expressions
-- patricksurry (Patrick Surry) or should return last value, even if falsy.
-- shughes-uk (Samantha Hughes) python w/o 'site' should not fail to import.
-- KOLANICH packaging / deployment / setup help & << + >> & other bit ops
-- graingert (Thomas Grainger) packaging / deployment / setup help
-- bozokopic (Bozo Kopic) Memory leak fix
-- daxamin (Dax Amin) Better error for attempting to eval empty string
-- smurfix (Matthias Urlichs) Allow clearing functions / operators / etc 
completely
-- koenigsley (Mikhail Yeremeyev) documentation typos correction.
-- kurtmckee (Kurt McKee) Infrastructure updates
-- edgarrmondragon (Edgar Ramírez-Mondragón) Address Python 3.12+ deprecation 
warnings
-- cedk (Cédric Krier) <[email protected]> Allow running tests with Werror
-- decorator-factory <[email protected]> More security fixes
-- lkruitwagen (Lucas Kruitwagen) Adding support for dict comprehensions
-
--------------------------------------
-Basic Usage:
-
->>> s = SimpleEval()
->>> s.eval("20 + 30")
-50
-
-You can add your own functions easily too:
-
-if file.txt contents is "11"
-
->>> def get_file():
-...     with open("file.txt", 'r') as f:
-...         return f.read()
-
->>> s.functions["get_file"] = get_file
->>> s.eval("int(get_file()) + 31")
-42
-
-For more information, see the full package documentation on pypi, or the github
-repo.
-
------------
-
-If you don't need to re-use the evaluator (with it's names, functions, etc),
-then you can use the simple_eval() function:
-
->>> simple_eval("21 + 19")
-40
-
-You can pass names, operators and functions to the simple_eval function as
-well:
-
->>> simple_eval("40 + two", names={"two": 2})
-42
-
-"""
-
-import ast
-import operator as op
-import sys
-import warnings
-from random import random
-
-########################################
-# Module wide 'globals'
-
-MAX_STRING_LENGTH = 100000
-MAX_COMPREHENSION_LENGTH = 10000
-MAX_POWER = 4000000  # highest exponent
-MAX_SHIFT = 10000  # highest << or >> (lshift / rshift)
-MAX_SHIFT_BASE = int(sys.float_info.max)  # highest on left side of << or >>
-DISALLOW_PREFIXES = ["_", "func_"]
-DISALLOW_METHODS = [
-    "format",
-    "format_map",
-    "mro",
-    "tb_frame",
-    "gi_frame",
-    "ag_frame",
-    "cr_frame",
-    "exec",
-]
-
-# Disallow functions:
-# This, strictly speaking, is not necessary.  These /should/ never be 
accessible anyway,
-# if DISALLOW_PREFIXES and DISALLOW_METHODS are all right.  This is here to 
try and help
-# people not be stupid.  Allowing these functions opens up all sorts of holes 
- if any of
-# their functionality is required, then please wrap them up in a safe 
container.  And think
-# very hard about it first.  And don't say I didn't warn you.
-# builtins is a dict in python >3.6 but a module before
-DISALLOW_FUNCTIONS = {type, isinstance, eval, getattr, setattr, repr, compile, 
open, exec}
-if hasattr(__builtins__, "help") or (
-    hasattr(__builtins__, "__contains__") and "help" in __builtins__  # type: 
ignore
-):
-    # PyInstaller environment doesn't include this module.
-    DISALLOW_FUNCTIONS.add(help)
-
-
-########################################
-# Exceptions:
-
-
-class InvalidExpression(Exception):
-    """Generic Exception"""
-
-    pass
-
-
-class FunctionNotDefined(InvalidExpression):
-    """sorry! That function isn't defined!"""
-
-    def __init__(self, func_name, expression):
-        self.message = "Function '{0}' not defined," " for expression 
'{1}'.".format(
-            func_name, expression
-        )
-        setattr(self, "func_name", func_name)  # bypass 2to3 confusion.
-        self.expression = expression
-
-        super(InvalidExpression, self).__init__(self.message)
-
-
-class NameNotDefined(InvalidExpression):
-    """a name isn't defined."""
-
-    def __init__(self, name, expression):
-        self.name = name
-        self.message = "'{0}' is not defined for expression 
'{1}'".format(name, expression)
-        self.expression = expression
-
-        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
-
-        super(InvalidExpression, self).__init__(self.message)
-
-
-class OperatorNotDefined(InvalidExpression):
-    """operator does not exist"""
-
-    def __init__(self, attr, expression):
-        self.message = "Operator '{0}' does not exist in expression 
'{1}'".format(attr, expression)
-        self.attr = attr
-        self.expression = expression
-
-        super(InvalidExpression, self).__init__(self.message)
-
-
-class FeatureNotAvailable(InvalidExpression):
-    """What you're trying to do is not allowed."""
-
-    pass
-
-
-class NumberTooHigh(InvalidExpression):
-    """Sorry! That number is too high. I don't want to spend the
-    next 10 years evaluating this expression!"""
-
-    pass
-
-
-class IterableTooLong(InvalidExpression):
-    """That iterable is **way** too long, baby."""
-
-    pass
-
-
-class AssignmentAttempted(UserWarning):
-    """Assignment not allowed in SimpleEval"""
-
-    pass
-
-
-class MultipleExpressions(UserWarning):
-    """Only the first expression parsed will be used"""
-
-    pass
-
-
-########################################
-# Default simple functions to include:
-
-
-def random_int(top):
-    """return a random int below <top>"""
-
-    return int(random() * top)
-
-
-def safe_power(a, b):  # pylint: disable=invalid-name
-    """a limited exponent/to-the-power-of function, for safety reasons"""
-
-    if abs(a) > MAX_POWER or abs(b) > MAX_POWER:
-        raise NumberTooHigh("Sorry! I don't want to evaluate {0} ** 
{1}".format(a, b))
-    return a**b
-
-
-def safe_mult(a, b):  # pylint: disable=invalid-name
-    """limit the number of times an iterable can be repeated..."""
-
-    if hasattr(a, "__len__") and b * len(a) > MAX_STRING_LENGTH:
-        raise IterableTooLong("Sorry, I will not evaluate something that 
long.")
-    if hasattr(b, "__len__") and a * len(b) > MAX_STRING_LENGTH:
-        raise IterableTooLong("Sorry, I will not evaluate something that 
long.")
-
-    return a * b
-
-
-def safe_add(a, b):  # pylint: disable=invalid-name
-    """iterable length limit again"""
-
-    if hasattr(a, "__len__") and hasattr(b, "__len__"):
-        if len(a) + len(b) > MAX_STRING_LENGTH:
-            raise IterableTooLong(
-                "Sorry, adding those two together would" " make something too 
long."
-            )
-    return a + b
-
-
-def safe_rshift(a, b):  # pylint: disable=invalid-name
-    """rshift, but with input limits"""
-    if abs(b) > MAX_SHIFT or abs(a) > MAX_SHIFT_BASE:
-        raise NumberTooHigh("Sorry! I don't want to evaluate {0} >> 
{1}".format(a, b))
-    return a >> b
-
-
-def safe_lshift(a, b):  # pylint: disable=invalid-name
-    """lshift, but with input limits"""
-    if abs(b) > MAX_SHIFT or abs(a) > MAX_SHIFT_BASE:
-        raise NumberTooHigh("Sorry! I don't want to evaluate {0} << 
{1}".format(a, b))
-    return a << b
-
-
-########################################
-# Defaults for the evaluator:
-
-DEFAULT_OPERATORS = {
-    ast.Add: safe_add,
-    ast.Sub: op.sub,
-    ast.Mult: safe_mult,
-    ast.Div: op.truediv,
-    ast.FloorDiv: op.floordiv,
-    ast.RShift: safe_rshift,
-    ast.LShift: safe_lshift,
-    ast.Pow: safe_power,
-    ast.Mod: op.mod,
-    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.Not: op.not_,
-    ast.USub: op.neg,
-    ast.UAdd: op.pos,
-    ast.BitXor: op.xor,
-    ast.BitOr: op.or_,
-    ast.BitAnd: op.and_,
-    ast.Invert: op.invert,
-    ast.In: lambda x, y: op.contains(y, x),
-    ast.NotIn: lambda x, y: not op.contains(y, x),
-    ast.Is: lambda x, y: x is y,
-    ast.IsNot: lambda x, y: x is not y,
-}
-
-DEFAULT_FUNCTIONS = {
-    "rand": random,
-    "randint": random_int,
-    "int": int,
-    "float": float,
-    "str": str,
-}
-
-DEFAULT_NAMES = {"True": True, "False": False, "None": None}
-
-ATTR_INDEX_FALLBACK = True
-
-
-########################################
-# And the actual evaluator:
-
-
-class SimpleEval(object):  # pylint: disable=too-few-public-methods
-    """A very simple expression parser.
-    >>> s = SimpleEval()
-    >>> s.eval("20 + 30 - ( 10 * 5)")
-    0
-    """
-
-    expr = ""
-
-    def __init__(self, operators=None, functions=None, names=None):
-        """
-        Create the evaluator instance.  Set up valid operators (+,-, etc)
-        functions (add, random, get_val, whatever) and names."""
-
-        if operators is None:
-            operators = DEFAULT_OPERATORS.copy()
-        if functions is None:
-            functions = DEFAULT_FUNCTIONS.copy()
-        if names is None:
-            names = DEFAULT_NAMES.copy()
-
-        self.operators = operators
-        self.functions = functions
-        self.names = names
-
-        self.nodes = {
-            ast.Expr: self._eval_expr,
-            ast.Assign: self._eval_assign,
-            ast.AugAssign: self._eval_aug_assign,
-            ast.Import: self._eval_import,
-            ast.Name: self._eval_name,
-            ast.UnaryOp: self._eval_unaryop,
-            ast.BinOp: self._eval_binop,
-            ast.BoolOp: self._eval_boolop,
-            ast.Compare: self._eval_compare,
-            ast.IfExp: self._eval_ifexp,
-            ast.Call: self._eval_call,
-            ast.keyword: self._eval_keyword,
-            ast.Subscript: self._eval_subscript,
-            ast.Attribute: self._eval_attribute,
-            ast.Index: self._eval_index,
-            ast.Slice: self._eval_slice,
-            ast.JoinedStr: self._eval_joinedstr,
-            ast.FormattedValue: self._eval_formattedvalue,
-            ast.Constant: self._eval_constant,
-        }
-
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore")
-            # py3.12 deprecated ast.Num, ast.Str, ast.NameConstant
-            # https://docs.python.org/3.12/whatsnew/3.12.html#deprecated
-            if Num := getattr(ast, "Num", None):
-                self.nodes[Num] = self._eval_num
-
-            if Str := getattr(ast, "Str", None):
-                self.nodes[Str] = self._eval_str
-
-            if NameConstant := getattr(ast, "NameConstant", None):
-                self.nodes[NameConstant] = self._eval_constant
-
-        # Defaults:
-
-        self.ATTR_INDEX_FALLBACK = ATTR_INDEX_FALLBACK
-
-        # Check for forbidden functions:
-
-        for f in self.functions.values():
-            if f in DISALLOW_FUNCTIONS:
-                raise FeatureNotAvailable("This function {} is a really bad 
idea.".format(f))
-
-    def __del__(self):
-        self.nodes = None
-
-    @staticmethod
-    def parse(expr):
-        """parse an expression into a node tree"""
-
-        parsed = ast.parse(expr.strip())
-
-        if not parsed.body:
-            raise InvalidExpression("Sorry, cannot evaluate empty string")
-        if len(parsed.body) > 1:
-            warnings.warn(
-                "'{}' contains multiple expressions. Only the first will be 
used.".format(expr),
-                MultipleExpressions,
-            )
-        return parsed.body[0]
-
-    def eval(self, expr, previously_parsed=None):
-        """evaluate an expression, using the operators, functions and
-        names previously set up."""
-
-        # set a copy of the expression aside, so we can give nice errors...
-        self.expr = expr
-
-        return self._eval(previously_parsed or self.parse(expr))
-
-    def _eval(self, node):
-        """The internal evaluator used on each node in the parsed tree."""
-
-        try:
-            handler = self.nodes[type(node)]
-        except KeyError:
-            raise FeatureNotAvailable(
-                "Sorry, {0} is not available in this " 
"evaluator".format(type(node).__name__)
-            )
-
-        return handler(node)
-
-    def _eval_expr(self, node):
-        return self._eval(node.value)
-
-    def _eval_assign(self, node):
-        warnings.warn(
-            "Assignment ({}) attempted, but this is 
ignored".format(self.expr), AssignmentAttempted
-        )
-        return self._eval(node.value)
-
-    def _eval_aug_assign(self, node):
-        warnings.warn(
-            "Assignment ({}) attempted, but this is 
ignored".format(self.expr), AssignmentAttempted
-        )
-        return self._eval(node.value)
-
-    @staticmethod
-    def _eval_import(node):
-        raise FeatureNotAvailable("Sorry, 'import' is not allowed.")
-
-    @staticmethod
-    def _eval_num(node):
-        return node.n
-
-    @staticmethod
-    def _eval_str(node):
-        if len(node.s) > MAX_STRING_LENGTH:
-            raise IterableTooLong(
-                "String Literal in statement is too long! ({0}, when {1} is 
max)".format(
-                    len(node.s), MAX_STRING_LENGTH
-                )
-            )
-        return node.s
-
-    @staticmethod
-    def _eval_constant(node):
-        if hasattr(node.value, "__len__") and len(node.value) > 
MAX_STRING_LENGTH:
-            raise IterableTooLong(
-                "Literal in statement is too long! ({0}, when {1} is 
max)".format(
-                    len(node.value), MAX_STRING_LENGTH
-                )
-            )
-        return node.value
-
-    def _eval_unaryop(self, node):
-        try:
-            operator = self.operators[type(node.op)]
-        except KeyError:
-            raise OperatorNotDefined(node.op, self.expr)
-        return operator(self._eval(node.operand))
-
-    def _eval_binop(self, node):
-        try:
-            operator = self.operators[type(node.op)]
-        except KeyError:
-            raise OperatorNotDefined(node.op, self.expr)
-        return operator(self._eval(node.left), self._eval(node.right))
-
-    def _eval_boolop(self, node):
-        to_return = False
-        if isinstance(node.op, ast.And):
-            for value in node.values:
-                to_return = self._eval(value)
-                if not to_return:
-                    break
-        elif isinstance(node.op, ast.Or):
-            for value in node.values:
-                to_return = self._eval(value)
-                if to_return:
-                    break
-        return to_return
-
-    def _eval_compare(self, node):
-        right = self._eval(node.left)
-        to_return = True
-        for operation, comp in zip(node.ops, node.comparators):
-            if not to_return:
-                break
-            left = right
-            right = self._eval(comp)
-            to_return = self.operators[type(operation)](left, right)
-        return to_return
-
-    def _eval_ifexp(self, node):
-        return self._eval(node.body) if self._eval(node.test) else 
self._eval(node.orelse)
-
-    def _eval_call(self, node):
-        if isinstance(node.func, ast.Attribute):
-            func = self._eval(node.func)
-        else:
-            try:
-                func = self.functions[node.func.id]
-            except KeyError:
-                raise FunctionNotDefined(node.func.id, self.expr)
-            except AttributeError:
-                raise FeatureNotAvailable("Lambda Functions not implemented")
-
-            if func in DISALLOW_FUNCTIONS:
-                raise FeatureNotAvailable("This function is forbidden")
-
-        return func(
-            *(self._eval(a) for a in node.args), **dict(self._eval(k) for k in 
node.keywords)
-        )
-
-    def _eval_keyword(self, node):
-        return node.arg, self._eval(node.value)
-
-    def _eval_name(self, node):
-        try:
-            # This happens at least for slicing
-            # This is a safe thing to do because it is impossible
-            # that there is a true expression assigning to none
-            # (the compiler rejects it, so you can't even
-            # pass that to ast.parse)
-            return self.names[node.id]
-
-        except (TypeError, KeyError):
-            pass
-
-        if callable(self.names):
-            try:
-                return self.names(node)
-            except NameNotDefined:
-                pass
-        elif not hasattr(self.names, "__getitem__"):
-            raise InvalidExpression(
-                'Trying to use name (variable) "{0}"'
-                ' when no "names" defined for'
-                " evaluator".format(node.id)
-            )
-
-        if node.id in self.functions:
-            return self.functions[node.id]
-
-        raise NameNotDefined(node.id, self.expr)
-
-    def _eval_subscript(self, node):
-        container = self._eval(node.value)
-        key = self._eval(node.slice)
-        # Currently if there's a KeyError, that gets raised straight up.
-        # TODO: Should that be wrapped in an InvalidExpression?
-        return container[key]
-
-    def _eval_attribute(self, node):
-        for prefix in DISALLOW_PREFIXES:
-            if node.attr.startswith(prefix):
-                raise FeatureNotAvailable(
-                    "Sorry, access to __attributes "
-                    " or func_ attributes is not available. "
-                    "({0})".format(node.attr)
-                )
-        if node.attr in DISALLOW_METHODS:
-            raise FeatureNotAvailable(
-                "Sorry, this method is not available. " 
"({0})".format(node.attr)
-            )
-        # eval node
-        node_evaluated = self._eval(node.value)
-
-        # Maybe the base object is an actual object, not just a dict
-        try:
-            return getattr(node_evaluated, node.attr)
-        except (AttributeError, TypeError):
-            pass
-
-        # TODO: is this a good idea?  Try and look for [x] if .x doesn't work?
-        if self.ATTR_INDEX_FALLBACK:
-            try:
-                return node_evaluated[node.attr]
-            except (KeyError, TypeError):
-                pass
-
-        # If it is neither, raise an exception
-        raise AttributeDoesNotExist(node.attr, self.expr)
-
-    def _eval_index(self, node):
-        return self._eval(node.value)
-
-    def _eval_slice(self, node):
-        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)
-
-    def _eval_joinedstr(self, node):
-        length = 0
-        evaluated_values = []
-        for n in node.values:
-            val = str(self._eval(n))
-            if len(val) + length > MAX_STRING_LENGTH:
-                raise IterableTooLong("Sorry, I will not evaluate something 
this long.")
-            evaluated_values.append(val)
-        return "".join(evaluated_values)
-
-    def _eval_formattedvalue(self, node):
-        if node.format_spec:
-            fmt = "{:" + self._eval(node.format_spec) + "}"
-            return fmt.format(self._eval(node.value))
-        return self._eval(node.value)
-
-
-class EvalWithCompoundTypes(SimpleEval):
-    """
-    SimpleEval with additional Compound Types, and their respective
-    function editions. (list, tuple, dict, set).
-    """
-
-    _max_count = 0
-
-    def __init__(self, operators=None, functions=None, names=None):
-        super(EvalWithCompoundTypes, self).__init__(operators, functions, 
names)
-
-        self.functions.update(list=list, tuple=tuple, dict=dict, set=set)
-
-        self.nodes.update(
-            {
-                ast.Dict: self._eval_dict,
-                ast.Tuple: self._eval_tuple,
-                ast.List: self._eval_list,
-                ast.Set: self._eval_set,
-                ast.ListComp: self._eval_comprehension,
-                ast.GeneratorExp: self._eval_comprehension,
-                ast.DictComp: self._eval_comprehension,
-            }
-        )
-
-    def eval(self, expr, previously_parsed=None):
-        # reset _max_count for each eval run
-        self._max_count = 0
-        return super(EvalWithCompoundTypes, self).eval(expr, previously_parsed)
-
-    def _eval_dict(self, node):
-        result = {}
-
-        for key, value in zip(node.keys, node.values):
-            if key is None:
-                # "{**x}" gets parsed as a key-value pair of (None, Name(x))
-                result.update(self._eval(value))
-            else:
-                result[self._eval(key)] = self._eval(value)
-
-        return result
-
-    def _eval_list(self, node):
-        result = []
-
-        for item in node.elts:
-            if isinstance(item, ast.Starred):
-                result.extend(self._eval(item.value))
-            else:
-                result.append(self._eval(item))
-
-        return result
-
-    def _eval_tuple(self, node):
-        return tuple(self._eval(x) for x in node.elts)
-
-    def _eval_set(self, node):
-        return set(self._eval(x) for x in node.elts)
-
-    def _eval_comprehension(self, node):
-        if isinstance(node, ast.DictComp):
-            to_return = {}
-        else:
-            to_return = []
-
-        extra_names = {}
-
-        previous_name_evaller = self.nodes[ast.Name]
-
-        def eval_names_extra(node):
-            """
-            Here we hide our extra scope for within this comprehension
-            """
-            if node.id in extra_names:
-                return extra_names[node.id]
-            return previous_name_evaller(node)
-
-        self.nodes.update({ast.Name: eval_names_extra})
-
-        def recurse_targets(target, value):
-            """
-                Recursively (enter, (into, (nested, name), unpacking)) = \
-                             and, (assign, (values, to), each
-            """
-            if isinstance(target, ast.Name):
-                extra_names[target.id] = value
-            else:
-                for t, v in zip(target.elts, value):
-                    recurse_targets(t, v)
-
-        def do_generator(gi=0):
-            g = node.generators[gi]
-            for i in self._eval(g.iter):
-                self._max_count += 1
-
-                if self._max_count > MAX_COMPREHENSION_LENGTH:
-                    raise IterableTooLong("Comprehension generates too many 
elements")
-                recurse_targets(g.target, i)
-                if all(self._eval(iff) for iff in g.ifs):
-                    if len(node.generators) > gi + 1:
-                        do_generator(gi + 1)
-                    else:
-                        if isinstance(to_return, dict):
-                            to_return[self._eval(node.key)] = 
self._eval(node.value)
-                        elif isinstance(to_return, list):
-                            to_return.append(self._eval(node.elt))
-
-        try:
-            do_generator()
-        finally:
-            self.nodes.update({ast.Name: previous_name_evaller})
-
-        return to_return
-
-
-def simple_eval(expr, operators=None, functions=None, names=None):
-    """Simply evaluate an expression"""
-    s = SimpleEval(operators=operators, functions=functions, names=names)
-    return s.eval(expr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simpleeval-1.0.5/PKG-INFO 
new/simpleeval-1.0.7/PKG-INFO
--- old/simpleeval-1.0.5/PKG-INFO       2020-02-02 01:00:00.000000000 +0100
+++ new/simpleeval-1.0.7/PKG-INFO       2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.3
 Name: simpleeval
-Version: 1.0.5
+Version: 1.0.7
 Summary: A simple, safe single expression evaluator library.
 Project-URL: Source code, https://github.com/danthedeckie/simpleeval
 Author-email: Daniel Fairhead <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simpleeval-1.0.5/pyproject.toml 
new/simpleeval-1.0.7/pyproject.toml
--- old/simpleeval-1.0.5/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
+++ new/simpleeval-1.0.7/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 [project]
 name = "simpleeval"
-version = "1.0.5"
+version = "1.0.7"
 requires-python = ">=3.9"
 readme = "README.rst"
 description = "A simple, safe single expression evaluator library."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simpleeval-1.0.5/simpleeval.py 
new/simpleeval-1.0.7/simpleeval.py
--- old/simpleeval-1.0.5/simpleeval.py  2020-02-02 01:00:00.000000000 +0100
+++ new/simpleeval-1.0.7/simpleeval.py  2020-02-02 01:00:00.000000000 +0100
@@ -59,7 +59,8 @@
 - smurfix (Matthias Urlichs) Allow clearing functions / operators / etc 
completely
 - koenigsley (Mikhail Yeremeyev) documentation typos correction.
 - kurtmckee (Kurt McKee) Infrastructure updates
-- edgarrmondragon (Edgar Ramírez-Mondragón) Address Python 3.12+ deprecation 
warnings
+- edgarrmondragon (Edgar Ramírez-Mondragón) Address Python 3.12+ deprecation 
warnings,
+  performance fixes
 - cedk (Cédric Krier) <[email protected]> Allow running tests with Werror
 - decorator-factory <[email protected]> More security fixes
 - lkruitwagen (Lucas Kruitwagen) Adding support for dict comprehensions
@@ -110,7 +111,7 @@
 import types
 import warnings
 from random import random
-from typing import Type, Dict, Set, Union, Hashable
+from typing import Type, Dict, Set, Union
 
 ########################################
 # Module wide 'globals'
@@ -132,6 +133,14 @@
     "exec",
 ]
 
+########################################
+# Tiny helpers:
+
+# Primitive types that are always safe: can't be modules, can't be in 
DISALLOW_FUNCTIONS,
+# and don't need recursive container checks. Used as a fast path in 
_check_disallowed_items.
+_PRIMITIVE_TYPES = frozenset({int, float, str, bool, type(None), bytes, 
complex})
+
+
 # Disallow functions:
 # This, strictly speaking, is not necessary.  These /should/ never be 
accessible anyway,
 # if DISALLOW_PREFIXES and DISALLOW_METHODS are all right.  This is here to 
try and help
@@ -617,14 +626,16 @@
         Raises FeatureNotAvailable if forbidden content found.
         ModuleWrapper instances are allowed (explicit opt-in to module access).
         """
+        # Fast path: primitive scalars are always safe (most common case)
+        if type(item) in _PRIMITIVE_TYPES:
+            return
+
         # Allow ModuleWrapper (explicit opt-in to module access)
         if isinstance(item, ModuleWrapper):
             return
 
         if isinstance(item, types.ModuleType):
             raise FeatureNotAvailable("Sorry, modules are not allowed")
-        if isinstance(item, Hashable) and item in DISALLOW_FUNCTIONS:
-            raise FeatureNotAvailable("This function is forbidden")
 
         if isinstance(item, (list, tuple)):
             for element in item:
@@ -632,6 +643,8 @@
         elif isinstance(item, dict):
             for value in item.values():
                 self._check_disallowed_items(value)
+        elif callable(item) and item in DISALLOW_FUNCTIONS:
+            raise FeatureNotAvailable("This function is forbidden")
 
     @staticmethod
     def parse(expr):
@@ -864,7 +877,7 @@
         if item is not _ATTR_NOT_FOUND:
             if isinstance(item, types.ModuleType):
                 raise FeatureNotAvailable("Sorry, modules are not allowed in 
attribute access")
-            if isinstance(item, Hashable) and item in DISALLOW_FUNCTIONS:
+            if callable(item) and item in DISALLOW_FUNCTIONS:
                 raise FeatureNotAvailable("This function is forbidden")
             return item
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/simpleeval-1.0.5/test_simpleeval.py 
new/simpleeval-1.0.7/test_simpleeval.py
--- old/simpleeval-1.0.5/test_simpleeval.py     2020-02-02 01:00:00.000000000 
+0100
+++ new/simpleeval-1.0.7/test_simpleeval.py     2020-02-02 01:00:00.000000000 
+0100
@@ -349,6 +349,15 @@
         self.t("foo(mult=2, to_return=4)", 8)
         self.t("foo(2, 10)", 20)
 
+    def test_function_with_list_args(self):
+        # Regression test, makes sure we can pass lists (non-hashable) items as
+        # kwargs to functions.
+
+        def func(*args, **kwargs):
+            return 42
+
+        simple_eval("test(boo=x)", functions={"test": func}, names={"x": [1, 
2]})
+
 
 class TestOperators(DRYTest):
     """Test adding in new operators, removing them, make sure it works."""
@@ -661,7 +670,7 @@
         """Functions returning disallowed functions should be blocked"""
 
         def get_evil():
-            return exec
+            return exec  # pragma: no cover
 
         s = SimpleEval(names={}, functions={"get_evil": get_evil})
 
@@ -750,9 +759,9 @@
         """Functions returning disallowed methods should be blocked"""
 
         def get_exec_module():
-            import os
+            import os  # pragma: no cover
 
-            return os
+            return os  # pragma: no cover
 
         s = SimpleEval(names={}, functions={"get_os": get_exec_module})
 
@@ -775,7 +784,7 @@
         class Container:
             @staticmethod
             def get_exec():
-                return exec
+                return exec  # pragma: no cover
 
         s = SimpleEval(names={"c": Container()})
 
@@ -849,7 +858,6 @@
         def name_handler(node):
             if node.id == "evil":
                 return exec
-            raise simpleeval.NameNotDefined(node.id, "")
 
         s = SimpleEval(names=name_handler)
 
@@ -863,7 +871,6 @@
         def name_handler(node):
             if node.id == "m":
                 return os
-            raise simpleeval.NameNotDefined(node.id, "")
 
         s = SimpleEval(names=name_handler)
 
@@ -875,7 +882,7 @@
         blocked - they can be executed by the custom function"""
 
         def evil_caller(func):
-            return func("print('pwned')")
+            return func("print('pwned')")  # pragma: no cover
 
         s = SimpleEval(names={"evil": exec}, functions={"evil_caller": 
evil_caller})
 
@@ -888,19 +895,19 @@
         import os
 
         def os_caller(mod):
-            return mod.system("id")
+            return mod.system("id")  # pragma: no cover
 
         s = SimpleEval(names={"m": os}, functions={"os_caller": os_caller})
 
         with self.assertRaises(FeatureNotAvailable):
-            s.eval("os_caller(m)")
+            s.eval("os_caller(m)")  # pragma: no cover
 
     def test_forbidden_function_in_list_passed_to_custom_function(self):
         """Forbidden functions in containers passed to custom functions
         should be blocked"""
 
         def extract_and_call(items):
-            return items[0]("print('pwned')")
+            return items[0]("print('pwned')")  # pragma: no cover
 
         s = SimpleEval(names={"funcs": [exec, eval]}, functions={"extract": 
extract_and_call})
 
@@ -913,7 +920,7 @@
         import os
 
         def extract_and_use(items):
-            return items[0].system("id")
+            return items[0].system("id")  # pragma: no cover
 
         s = SimpleEval(names={"mods": [os.path, os]}, functions={"extract": 
extract_and_use})
 
@@ -925,7 +932,7 @@
         be blocked"""
 
         def extract_and_call(d):
-            return d["bad"]("print('pwned')")
+            return d["bad"]("print('pwned')")  # pragma: no cover
 
         s = SimpleEval(
             names={"funcs": {"bad": exec, "good": print}}, 
functions={"extract": extract_and_call}
@@ -939,7 +946,7 @@
         import os
 
         def extract_and_use(d):
-            return d["m"].system("id")
+            return d["m"].system("id")  # pragma: no cover
 
         s = SimpleEval(
             names={"mods": {"m": os, "p": os.path}}, functions={"extract": 
extract_and_use}

Reply via email to