Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.0.0 - Time for a new updated release, and call this iteration stable. #144

Merged
merged 28 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
376f303
Support Python 3.9+
kurtmckee Jun 19, 2024
47fdf5e
Remove old Python compatibility conditionals and references
kurtmckee Aug 5, 2024
23874c0
Merge pull request #142 from kurtmckee/drop-python-2.7
danthedeckie Oct 4, 2024
b915ec8
Faster formatting & linting via ruff & update mypy
danthedeckie Oct 4, 2024
a7c9fb7
Minor linting tweaks that ruff wants...
danthedeckie Oct 4, 2024
866004e
Merge pull request #145 from danthedeckie/dev-updates
danthedeckie Oct 4, 2024
d23ad09
Fix deprecation warnings
danthedeckie Oct 4, 2024
b86d36f
Merge pull request #146 from danthedeckie/fix-deprecation-warnings
danthedeckie Oct 4, 2024
32c047b
Run tests with warnings as error
cedk Jun 8, 2024
061acec
Attribution cedk
danthedeckie Oct 4, 2024
6deac2f
And catch warnings from the deprecated AST nodes.
danthedeckie Oct 4, 2024
c14afc0
lint
danthedeckie Oct 4, 2024
9c90b10
Merge pull request #147 from danthedeckie/catch-warnings
danthedeckie Oct 4, 2024
9542343
Attempt to fix codecov stats
danthedeckie Oct 4, 2024
570476b
Bump version info
danthedeckie Oct 4, 2024
7d89e0e
Merge pull request #148 from danthedeckie/infra-fixes
danthedeckie Oct 4, 2024
1ff1bda
Fix escape via generators etc.
danthedeckie Oct 4, 2024
ccb584e
Merge pull request #149 from danthedeckie/more-restrictions
danthedeckie Oct 4, 2024
4835603
add support for dictcomp
Lkruitwagen Sep 10, 2023
c9dcca1
delint and add contib to README
Lkruitwagen Sep 10, 2023
166e90f
Merge pull request #150 from danthedeckie/dictcomp-support
danthedeckie Oct 4, 2024
983f4e0
Don't misuse KeyError for the custom `names` function.
danthedeckie Feb 8, 2023
ee16fd3
README fixes
danthedeckie Oct 4, 2024
014f2e8
Merge pull request #126 from danthedeckie/better-names-exceptions
danthedeckie Oct 4, 2024
5c38a5c
Bump copyright year.
danthedeckie Oct 4, 2024
07f3363
Hacky make codecov see new lines are tested.
danthedeckie Oct 4, 2024
eced404
README bump badges
danthedeckie Oct 5, 2024
0fe45bb
Fix licence & classifier info for pypi
danthedeckie Oct 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Codecov
name: CI
on: [push]
jobs:
lint:
Expand All @@ -18,7 +18,14 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python: ['2.7', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12-dev', 'pypy-3.8']
python:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- 'pypy-3.9'
- 'pypy-3.10'
env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.python }}
Expand All @@ -29,13 +36,16 @@ jobs:
uses: actions/setup-python@master
with:
python-version: ${{ matrix.python }}
allow-prereleases: true

- name: Generate Report
run: |
pip install coverage
coverage run -m test_simpleeval
coverage xml
- name: Upload to codecov
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v4.0.1
with:
files: coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
11 changes: 5 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
test:
python test_simpleeval.py
python -Werror test_simpleeval.py

autotest:
find . -name \*.py -not -path .\/.v\* | entr make test
Expand All @@ -22,11 +22,10 @@ coverage:
coverage run test_simpleeval.py

lint:
black --check --diff simpleeval.py test_simpleeval.py
isort --check-only --diff simpleeval.py test_simpleeval.py
pylint simpleeval.py test_simpleeval.py
ruff check simpleeval.py test_simpleeval.py
ruff format --check simpleeval.py test_simpleeval.py
mypy simpleeval.py test_simpleeval.py

format:
black simpleeval.py test_simpleeval.py
isort simpleeval.py test_simpleeval.py
ruff check --fix-only simpleeval.py test_simpleeval.py
ruff format simpleeval.py test_simpleeval.py
54 changes: 39 additions & 15 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ The ``^`` operator is often mistaken for a exponent operator, not the bitwise
operation that it is in python, so if you want ``3 ^ 2`` to equal ``9``, you can
replace the operator like this:

.. code-block:: python
.. code-block:: pycon

>>> import ast
>>> from simpleeval import safe_power
Expand Down Expand Up @@ -200,15 +200,15 @@ If Expressions

You can use python style ``if x then y else z`` type expressions:

.. code-block:: python
.. code-block:: pycon

>>> simple_eval("'equal' if x == y else 'not equal'",
names={"x": 1, "y": 2})
'not equal'

which, of course, can be nested:

.. code-block:: python
.. code-block:: pycon

>>> simple_eval("'a' if 1 == 2 else 'b' if 2 == 3 else 'c'")
'c'
Expand All @@ -219,15 +219,15 @@ Functions

You can define functions which you'd like the expresssions to have access to:

.. code-block:: python
.. code-block:: pycon

>>> simple_eval("double(21)", functions={"double": lambda x:x*2})
42

You can define "real" functions to pass in rather than lambdas, of course too,
and even re-name them so that expressions can be shorter

.. code-block:: python
.. code-block:: pycon

>>> def double(x):
return x * 2
Expand All @@ -246,13 +246,13 @@ are provided in the ``DEFAULT_FUNCTIONS`` dict:
+----------------+--------------------------------------------------+
| ``float(x)`` | Convert ``x`` to a ``float``. |
+----------------+--------------------------------------------------+
| ``str(x)`` | Convert ``x`` to a ``str`` (``unicode`` in py2) |
| ``str(x)`` | Convert ``x`` to a ``str`` |
+----------------+--------------------------------------------------+

If you want to provide a list of functions, but want to keep these as well,
then you can do a normal python ``.copy()`` & ``.update``:

.. code-block:: python
.. code-block:: pycon

>>> my_functions = simpleeval.DEFAULT_FUNCTIONS.copy()
>>> my_functions.update(
Expand All @@ -267,15 +267,15 @@ Names
Sometimes it's useful to have variables available, which in python terminology
are called 'names'.

.. code-block:: python
.. code-block:: pycon

>>> simple_eval("a + b", names={"a": 11, "b": 100})
111

You can also hand the handling of names over to a function, if you prefer:


.. code-block:: python
.. code-block:: pycon

>>> def name_handler(node):
return ord(node.id[0].lower(a))-96
Expand All @@ -284,9 +284,34 @@ You can also hand the handling of names over to a function, if you prefer:
3

That was a bit of a silly example, but you could use this for pulling values
from a database or file, say, or doing some kind of caching system.
from a database or file, looking up spreadsheet cells, say, or doing some kind of caching system.

In general, when it attempts to find a variable by name, if it cannot find one,
then it will look in the ``functions`` for a function of that name. If you want your name handler
function to return an "I can't find that name!", then it should raise a ``simpleeval.NameNotDefined``
exception. Eg:

The two default names that are provided are ``True`` and ``False``. So if you want to provide your own names, but want ``True`` and ``False`` to keep working, either provide them yourself, or ``.copy()`` and ``.update`` the ``DEFAULT_NAMES``. (See functions example above).
.. code-block:: pycon

>>> def name_handler(node):
... if node.id[0] == 'a':
... return 21
... raise NameNotDefined(node.id[0], "Not found")
...
... simple_eval('a + a', names=name_handler, functions={"b": 100})

42

>>> simple_eval('a + b', names=name_handler, functions={'b': 100})
121

(Note: in that example, putting a number directly into the ``functions`` dict was done just to
show the fall-back to functions. Normally only put actual callables in there.)


The two default names that are provided are ``True`` and ``False``. So if you want to provide
your own names, but want ``True`` and ``False`` to keep working, either provide them yourself,
or ``.copy()`` and ``.update`` the ``DEFAULT_NAMES``. (See functions example above).

Creating an Evaluator Class
---------------------------
Expand All @@ -296,7 +321,7 @@ evaluations, 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):

.. code-block:: python
.. code-block:: pycon

>>> s = SimpleEval()

Expand Down Expand Up @@ -375,7 +400,7 @@ comprehensions.
Since the primary intention of this library is short expressions - an extra 'sweetener' is
enabled by default. You can access a dict (or similar's) keys using the .attr syntax:

.. code-block:: python
.. code-block:: pycon

>>> simple_eval("foo.bar", names={"foo": {"bar": 42}})
42
Expand Down Expand Up @@ -405,8 +430,7 @@ and then use ``EvalNoMethods`` instead of the ``SimpleEval`` class.
Other...
--------

The library supports python 3 - but should be mostly compatible (and tested before 0.9.11)
with python 2.7 as well.
The library supports Python 3.9 and higher.

Object attributes that start with ``_`` or ``func_`` are disallowed by default.
If you really need that (BE CAREFUL!), then modify the module global
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ build-backend = "setuptools.build_meta"
line-length = 99
target-version = ['py310']

[tool.ruff]
line-length = 99

[tool.isort]
combine_as_imports = true
float_to_top = true
Expand Down
6 changes: 2 additions & 4 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
black==23.1.0
isort==5.10.1
pylint==2.12.2
mypy==0.931
ruff==0.6.9
mypy==1.11.2
8 changes: 3 additions & 5 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = simpleeval
version = 0.9.13
version = 1.0.0
author = Daniel Fairhead
author_email = [email protected]
description = A simple, safe single expression evaluator library.
Expand All @@ -9,17 +9,15 @@ url = https://github.com/danthedeckie/simpleeval
long_description = file: README.rst
long_description_content_type = text/x-rst
classifiers =
Development Status :: 4 - Beta
Development Status :: Development Status :: 5 - Production/Stable
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Topic :: Software Development :: Libraries :: Python Modules
Programming Language :: Python

[options]
py_modules = simpleeval

[bdist_wheel]
universal=1
python_requires = >=3.9

[pycodestyle]
max_line_length = 99
Loading