Code Monkey home page Code Monkey logo

simpleeval's Issues

Release plan

Do we have plan to make a new release?
we hit the issue: #69 and it has been fix by #72
but not perform new release for it, so i wonder to know the release plan see if it can catch our time-line thanks

LICENCE in pypi tarball

Hi,
could you please ship licence file along with tarbal as usual in opensource projects?
Thanks for considering

Including non-builtin class in names allows end user to snoop

If the user (source of untrusted code) can get access to a non-builtin function, such as a method defined on a non-builtin class, they can access the functions func_globals or __globals__ property and see everything defined in that function's module. This includes other imported modules and often leads to access to sys, and by extension, sys.modules. This could allow an attacker to find sensitive data (usernames, passwords, PII) by crawling through the list of modules. Even if the sensitive information is not defined at top level, inspection of function objects will reveal any constants or default arguments used anywhere in the running system.

At a minimum, attribute lookup for attributes beginning with _ should be denied (plus the special case in python2 to deny func_*). Ideally, attribute lookup should have a configurable max-depth, or a whitelist of allowed types and classes.

Weird behaviour when trying to evaluate a class method chaining

Hello,
First I want to thank you for this project,
I was trying to evaluate some class method calls using the method chaining syntax, but i got a weird result:
my code:

from __future__ import print_function
import simpleeval

class A(object):
    def __init__(self):
        self.a = "0"

    def add(self, b):
        self.a += "-add" + str(b)
        return self

    def sub(self, b):
        self.a += "-sub" + str(b)
        return self

    def __str__(self):
        return str(self.a)

x = A()
print(simpleeval.simple_eval("x.add(1).sub(2).sub(3)", names={"x": x}))
x = A()
print(x.add(1).sub(2).sub(3)) # expected output

the output:

0-add1-add1-sub2-add1-add1-sub2-sub3
0-add1-sub2-sub3

The first line is the output from simpleeval.

Expression Evaluation Error

Perhaps I am misunderstanding how the expression evaluator should work, but consider the following:

formula = "0 <= 10 <= 5"
simple_eval(formula)
True

While 0 <= 10 should evaluate to True, 10 <= 5 should not. Perhaps the evaluation is being short-circuited? Is this intentional?

I also tested this with Python's built in eval function:

formula = "0 <= 10 <= 5"
eval(formula)
False

Support for Python 3.8

Tests fail with the following error when running on Python 3.8:
simpleeval.FeatureNotAvailable: Sorry, Constant is not available in this evaluator

Decimal support example not working

Hi, in this issue you propose a solution for using simpleeval with Decimal type. That appears to no longer be working? I'm not quite sure why.

import decimal
import simpleeval


class DecimalEval(simpleeval.SimpleEval):
    @staticmethod
    def _eval_num(node):
        return decimal.Decimal(node.n)

decimal.getcontext().prec = 1

print(DecimalEval().eval('0.1+0.2'))
print(type(DecimalEval().eval('0.1+0.2')))

This outputs

0.30000000000000004
<class 'float'>

Can you give some insight please?

Crashes when evaluating an empty string

When giving simpleeval an empty string it raises this error:
Traceback (most recent call last):

Traceback (most recent call last):
  File "simpleeval.py", line 613, in simple_eval
    return s.eval(expr)
  File "simpleeval.py", line 334, in eval
    return self._eval(parsed.body[0].value)
IndexError: list index out of range

I propose to either throw an appropriate error or maybe return something. Wether that'd be an empty string or None is too philosophical for me but maybe there's an PIP on this? Anyways, something like this should suffice:

parsed = ast.parse(expr.strip())
if len(parsed.body) > 0:
    # and evaluate if not empty:
    return self._eval(parsed.body[0].value)
else:
    return None

Support "decimal" module

Would be possible to support the decimal module, such that e.g. simple_eval('0.1+0.2') gives 0.3 instead of 0.30000000000000004?

test_simpleeval.py not packaged

The file test_simpleeval.py is not in the package on PyPI.
It will be good to have it to test if the installation is correct.

How to use math constants

Hi, is it possible to evaluate "Pi" or "e" in an expression ?
If not, would you have any idea on how to implement this ?

Do not allow assignment operator

The following statement successfully executes.

simpleeval.simple_eval("a = 2")

And returns 2.
I suggest that assignment operator is entirely disallowed as input to simple eval.

Because "a == 2" can be easily mistyped as "a = 2" and existence of variable "a" is not even checked in evaluation of this input.

Possible to define my own operators

Hi,
I'm trying to use simpleeval to evaluate expressions as XML attributes.
Since XML syntax uses "<" and ">" I cannot do this:

  <Tag expr="3 > 1"/>

So I am trying to use something like this:

  <Tag expr="3 GT 1"/>

Can this be done?

Raise error when multi line expression is passed for evaluation

Using simple_eval method expression like True\nFalse is evaluated to True, False\nTrue to False.

It looks like only the first statement is taken from AST for evaluation.

return self._eval(ast.parse(expr.strip()).body[0].value)

I suggest that an exception must be raised in case where there are multiple statements to be sure that passed expression is evaluated correctly.

simpleeval + sqlalchemy query

Hi,

I'm trying to get the safety of simpleeval to work with sqlalchemy's core query:
Something like:

tbl = Table('mytable', meta)
names = tbl.c._data
myexpr = 'mycol > 5'
se = simpleeval.EvalWithCompoundTypes(names=names)
safe_filter = se.eval(myexpr)  # <-- I get an error
results = session.query(tbl).filter(safe_filter)

I'm getting this error on eval():

TypeError: Boolean value of this clause is not defined

For the record, this does work:

tbl = Table('mytable', meta)
names = tbl.c._data
myexpr = 'mycol > 5'
unsafe_filter = eval(myexpr, names)
results = session.query(tbl).filter(unsafe_filter)

It looks like eval() is returning: sqlalchemy.sql.elements.BinaryExpression, which breaks simpleeval...

Any hope of getting this to work? Am I doing something wrong?

Thanks!

How to change MAX_POWER limit without edit simpleeval source code

Hello,
congratulations on this fantastic library.

It has allowed me to develop a generic function with the following signature:

def calc_model (formula, ** kargs)

The native function eval (formula, kargs) was giving me an error when the formula contained functions like math.log10 (x) even after importing it.

Embedding the import just before the formula was not the solution either:

if ('math' in formula):
         formula = 'import math; '+ formula

Finally, I had the solution with simpleeval defining a specific lambda function:

log10_lambda = {"log10": lambda x: math.log10(x)}
result = simple_eval (formula, names = kargs, functions = log10_lambda)

MY QUESTION IS

How can I increase or even completely disable the MAX_POWER limit value without editing the library source code?

I have some formulas that need it

Thanks in advance.

Problem when building using simpleeval

I have a project that I wanted to build to create a release. I've tried with py2exe and PyInstaller.
However, always after the building, it throws an error that says:

   File "simpleeval.py", line 116, in <module>
NameError: name 'help' is not defined
[39588] Failed to execute script app

I was able to solve this by adding:

def help():
    pass

right above the definition of DISALLOW_FUNCTIONS, that was at the line 116.

I only did it because I've found another person with the same problem, that described this solution in this site.

It would be possible to add this in a release? Because the program works perfectly just with this little modification. But it is annoying to add this always when I want to build the project.

I don't know if there's another person that faced the same problem and has a better way to solve this. If so, I would like to know.

Functions not considered during name lookup

Here's a simple reproducer of the problem:

#!/usr/bin/env python3

from simpleeval import EvalWithCompoundTypes

s = EvalWithCompoundTypes(functions={"map": map, "str": str})
print(s.eval("list(map(str, [-1, 0, 1]))"))

The fix is to have SimpleEval._eval_name() also look in self.functions when it can't find node.is in self.names. I can submit a pull request once my pending one is closed.

Issue when running on python3.8

When you try to run the testsuite of simpleeval on python 3.8 you get following error on most tests:

[   12s] ___________________ TestShortCircuiting.test_shortcircuit_if ___________________
[   12s] 
[   12s] self = <simpleeval.SimpleEval object at 0xf66c0208>
[   12s] node = <_ast.Constant object at 0xf66c02f8>
[   12s] 
[   12s]     def _eval(self, node):
[   12s]         """ The internal evaluator used on each node in the parsed tree. """
[   12s]     
[   12s]         try:
[   12s] >           handler = self.nodes[type(node)]
[   12s] E           KeyError: <class '_ast.Constant'>
[   12s] 
[   12s] simpleeval.py:315: KeyError
[   12s] 
[   12s] During handling of the above exception, another exception occurred:
[   12s] 
[   12s] self = <test_simpleeval.TestShortCircuiting testMethod=test_shortcircuit_if>
[   12s] 
[   12s]     def test_shortcircuit_if(self):
[   12s]         x = []
[   12s]         def foo(y):
[   12s]             x.append(y)
[   12s]             return y
[   12s]         self.s.functions = {'foo': foo}
[   12s] >       self.t('foo(1) if foo(2) else foo(3)', 1)
[   12s] 
[   12s] test_simpleeval.py:1001: 
[   12s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   12s] test_simpleeval.py:31: in t
[   12s]     return self.assertEqual(self.s.eval(expr), shouldbe)
[   12s] simpleeval.py:309: in eval
[   12s]     return self._eval(ast.parse(expr.strip()).body[0].value)
[   12s] simpleeval.py:320: in _eval
[   12s]     return handler(node)
[   12s] simpleeval.py:372: in _eval_ifexp
[   12s]     return self._eval(node.body) if self._eval(node.test) \
[   12s] simpleeval.py:320: in _eval
[   12s]     return handler(node)
[   12s] simpleeval.py:386: in _eval_call
[   12s]     return func(
[   12s] simpleeval.py:387: in <genexpr>
[   12s]     *(self._eval(a) for a in node.args),
[   12s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   12s] 
[   12s] self = <simpleeval.SimpleEval object at 0xf66c0208>
[   12s] node = <_ast.Constant object at 0xf66c02f8>
[   12s] 
[   12s]     def _eval(self, node):
[   12s]         """ The internal evaluator used on each node in the parsed tree. """
[   12s]     
[   12s]         try:
[   12s]             handler = self.nodes[type(node)]
[   12s]         except KeyError:
[   12s] >           raise FeatureNotAvailable("Sorry, {0} is not available in this "
[   12s]                                       "evaluator".format(type(node).__name__))
[   12s] E           simpleeval.FeatureNotAvailable: Sorry, Constant is not available in this evaluator
[   12s] 
[   12s] simpleeval.py:317: FeatureNotAvailable
[   12s] ======================== 64 failed, 16 passed in 4.37s =========================

Failing test TestTryingToBreakOut

TestTryingToBreakOut is currently failing with

I: pybuild base:170: python2.7 setup.py test 
running test
running egg_info
creating simpleeval.egg-info
writing simpleeval.egg-info/PKG-INFO
writing top-level names to simpleeval.egg-info/top_level.txt
writing dependency_links to simpleeval.egg-info/dependency_links.txt
writing manifest file 'simpleeval.egg-info/SOURCES.txt'
reading manifest file 'simpleeval.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'simpleeval.egg-info/SOURCES.txt'
running build_ext
test_bools_and_or (test_simpleeval.TestBasic) ... ok
test_comparisons (test_simpleeval.TestBasic) ... ok
test_default_conversions (test_simpleeval.TestBasic)
conversion between types ... ok
test_if_else (test_simpleeval.TestBasic)
x if y else z ... ok
test_maths_with_floats (test_simpleeval.TestBasic) ... ok
test_maths_with_ints (test_simpleeval.TestBasic)
simple maths expressions ... ok
test_mixed_comparisons (test_simpleeval.TestBasic) ... ok
test_load_file (test_simpleeval.TestFunctions)
add in a function which loads data from an external file. ... ok
test_randoms (test_simpleeval.TestFunctions)
test the rand() and randint() functions ... ok
test_dict (test_simpleeval.TestNames)
using a normal dict for names lookup ... ok
test_from_doc (test_simpleeval.TestNames)
the 'name first letter as value' example from the docs ... ok
test_func (test_simpleeval.TestNames)
using a function for 'names lookup' ... ok
test_none (test_simpleeval.TestNames)
what to do when names isn't defined, or is 'none' ... ok
test_import (test_simpleeval.TestTryingToBreakOut)
usual suspect. import ... ok
test_long_running (test_simpleeval.TestTryingToBreakOut)
exponent operations can take a long time. ... ok
test_python_stuff (test_simpleeval.TestTryingToBreakOut)
other various pythony things. ... ok
test_string_length (test_simpleeval.TestTryingToBreakOut) ... ERROR
test_basic_run (test_simpleeval.Test_simple_eval) ... ok
test_default_functions (test_simpleeval.Test_simple_eval) ... ok

======================================================================
ERROR: test_string_length (test_simpleeval.TestTryingToBreakOut)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/buildd/simpleeval-0.8.2/test_simpleeval.py", line 199, in test_string_length
    self.t("'" + (50000 * "stuff") + "'", 0)
  File "/tmp/buildd/simpleeval-0.8.2/test_simpleeval.py", line 24, in t
    return self.assertEqual(self.s.eval(expr), shouldbe)
  File "/tmp/buildd/simpleeval-0.8.2/simpleeval.py", line 209, in eval
    return self._eval(ast.parse(expr).body[0].value)
  File "/tmp/buildd/simpleeval-0.8.2/simpleeval.py", line 223, in _eval
    node.id, len(node.s), MAX_STRING_LENGTH))
AttributeError: 'Str' object has no attribute 'id'

----------------------------------------------------------------------
Ran 19 tests in 0.009s

FAILED (errors=1)

Side effects on names

Hi,

I've noticed that the names dictionary provided to simple_eval was actually modified here:

3aa36f3

It is a difficult side-effect to detect, so I would like to know if it is the expected behavior (meaning one should always copy actual data passed to names) or a bug to fix.

Installing works, but gives ParseError warning

I just ran:

pip install simpleeval

It was successfully installed (and works locally), but there was a warning from line 55:

Can't parse docstring in build/lib/simpleeval.py line 55: ParseError: bad input: type=0, value='', context=('', (56, 0))

Modifying defaults

Hi, first of all I want to thank you for the package. It comes very handy to my project. I have forked it, so I'm open to contribute.

I have some questions, what happens if I do:

import simpleeval
import math

simpleeval.DEFAULT_FUNCTIONS["sqrt"] = math.sqrt
print simpleeval.simple_eval("sqrt(25)")

>>> 5

It works, but, is that all right? Is it the supposed way I should do it? is there any risk?

Lambda application causes crash instead of `FeatureNotAvailable`

I ran into this crash when investigating safeeval's resiliency against lambda-based attacks.

Platform:

Python 3.6.5 (default, Apr  3 2018, 21:02:01)
[GCC 4.2.1 Compatible Android Clang 5.0.300080 ] on linux

I'm using the Android app Termux, so the environment is a bit unusual, but this doesn't look like a platform-specific crash. Maybe this is caused by some change in ast on Python 3.6?

Code:

>>> import simpleeval
>>> s = simpleeval.SimpleEval()
>>> s.eval('(lambda x: x+1)(3)')

Expected result:

Traceback (most recent call last):
  ...
  simpleeval.FeatureNotAvailable: Sorry, Lambda is not available in this evaluator

Actual result (crash):

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<python path>/site-packages/simpleeval.py", line 283, in eval
    return self._eval(ast.parse(expr.strip()).body[0].value)
  File "<python path>/site-packages/simpleeval.py", line 294, in _eval
    return handler(node)
  File "<python path>/site-packages/simpleeval.py", line 353, in _eval_call
    func = self.functions[node.func.id]
AttributeError: 'Lambda' object has no attribute 'id'

s.eval('lambda x: x') correctly raises FeatureNotAvailable, only a lambda application causes this problem.

Evaluator crash on complex assignment target in list comprehension

simpleeval 0.9.10

So I just remembered that any valid assignment target can be used in a list comprehension! i.e. something like [... for foo[0] in ...] is valid syntax.

Expected behavior

>>> [x for x in ([None],) for x[0] in (15,)]
[[15]]

Actual behavior

>>> EvalWithCompoundTypes('[x for x in ([None],) for x[0] in (15,)]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "LIBPATH/simpleeval.py", line 539, in eval
    return super(EvalWithCompoundTypes, self).eval(expr)
  File "LIBPATH/simpleeval.py", line 332, in eval
    return self._eval(ast.parse(expr.strip()).body[0].value)
  File "LIBPATH/simpleeval.py", line 343, in _eval
    return handler(node)
  File "LIBPATH/simpleeval.py", line 597, in _eval_comprehension
    do_generator()
  File "LIBPATH/simpleeval.py", line 592, in do_generator
    do_generator(gi+1)
  File "LIBPATH/simpleeval.py", line 589, in do_generator
    recurse_targets(g.target, i)
  File "LIBPATH/simpleeval.py", line 579, in recurse_targets
    for t, v in zip(target.elts, value):
AttributeError: 'Subscript' object has no attribute 'elts'

Exceptions during list comprehensions leak local variables

Example code:

import ast

from simpleeval import EvalWithCompoundTypes

e = EvalWithCompoundTypes()

try:
    print(e.eval('[x if x == "2" else y for x in "123"]'))
except Exception as exc:
    print(exc)
print(e.nodes[ast.Name])
print(e.eval('x'))

Result:

'y' is not defined for expression '[x if x == "2" else y for x in "123"]'
<function EvalWithCompoundTypes._eval_comprehension.<locals>.eval_names_extra at 0x1098f91e0>
1

Expected Result:

The second print statement should print something like <bound method SimpleEval._eval_name of <simpleeval.EvalWithCompoundTypes object at 0x10bf2f860>> while the second evaluation should raise a NameNotDefined exception.

Solution:

The _eval_comprehension method changes the evaller for the ast.Name node, but does not reset it in case of an exception. This can be easily solved by wrapping the call to do_generator into a try...finally construct.

FunctionNotDefined object has no attribute 'func_name'

According to the source code, the FunctionNotDefined exception has an attribute func_name, and has had it since the initial commit. However, when using pip to install the package, the same section looks like this:

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)
        self.__name__ = func_name
        self.expression = expression

so the attribute is called __name__.

The weird thing is, that the tar on PyPI DOES seem to contain the correct code (no diff with the github version.

What's going on here?

To reproduce, I did:

docker run --rm -it python:3.7.0-stretch bash
pip install simpleeval
grep -A6 'class FunctionNotDefined' /usr/local/lib/python3.7/site-packages/simpleeval.py

Failing test with python3.2

With python3.4 no errors (s. #5), but when building for Debian wheezy, which only has python3.2 the following error occurs:

I: pybuild base:170: python3.2 setup.py test
running test
running build_py
running egg_info
creating /tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info
writing /tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info/PKG-INFO
writing top-level names to /tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info/top_level.txt
writing dependency_links to /tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info/dependency_links.txt
writing manifest file '/tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info/SOURCES.txt'
reading manifest file '/tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file '/tmp/buildd/simpleeval-0.8.2/.pybuild/pythonX.Y_3.2/build/simpleeval.egg-info/SOURCES.txt'
running build_ext
Traceback (most recent call last):
  File "setup.py", line 22, in <module>
    'Programming Language :: Python :: 3',
  File "/usr/lib/python3.2/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/lib/python3.2/distutils/dist.py", line 917, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python3.2/distutils/dist.py", line 936, in run_command
    cmd_obj.run()
  File "/usr/lib/python3/dist-packages/setuptools/command/test.py", line 137, in run
    self.with_project_on_sys_path(self.run_tests)
  File "/usr/lib/python3/dist-packages/setuptools/command/test.py", line 117, in with_project_on_sys_path
    func()
  File "/usr/lib/python3/dist-packages/setuptools/command/test.py", line 146, in run_tests
    testLoader = loader_class()
  File "/usr/lib/python3.2/unittest/main.py", line 123, in __init__
    self.parseArgs(argv)
  File "/usr/lib/python3.2/unittest/main.py", line 191, in parseArgs
    self.createTests()
  File "/usr/lib/python3.2/unittest/main.py", line 198, in createTests
    self.module)
  File "/usr/lib/python3.2/unittest/loader.py", line 137, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib/python3.2/unittest/loader.py", line 137, in <listcomp>
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib/python3.2/unittest/loader.py", line 96, in loadTestsFromName
    module = __import__('.'.join(parts_copy))
  File "/tmp/buildd/simpleeval-0.8.2/test_simpleeval.py", line 87
    self.t('"Test Stuff!" + str(11)', u"Test Stuff!11")
                                                     ^
SyntaxError: invalid syntax

Operator with arguments??

I'd like to have an operator like "?(number)". How would I go about doing this, and if I can't, is it planned and/or are there workarounds?

You might not understand why, but it's so that I can do things like FIBONACCI(2) would get the first 2 fibonacci numbers. it's like functions but as expressions.

Leading space results in IndentationError

I'm using simpleeval for evaluating template expressions, e.g.

{{ foo.bar }}

Because the engine (https://github.com/iivvoo/ate if anyone's interested ;) aims to be user (programmer) friendly it ignores leading/trailing whitespaces and passes them verbatim to simpleeval which sometimes results in an IndentationError

In [1]: from simpleeval import simple_eval
In [2]: simple_eval(" True")
  File "<unknown>", line 1
    True
    ^
IndentationError: unexpected indent

This is quite simple to work around but it makes me wonder if there's any need at all for simpleeval to be so strict about whitespace - is any form of indentation actually supported?

Default Operators are not appended when new operators added

Documentation on your simpleeval package (on github) has an explanation on how add ^ operator, but lacks an example of how operators paramater work

is through a dict with lambda, just like functions paramater work?
already tested the following and it was the only way I could make it work

s = SimpleEval()
s.operators[ast.BitOr] = op.or_

the problem with this is that Or can not be added as or
Also custom functions that are not available in ast package are trickier (could not make it work)
for example lets take operator juggler:
1 juggler 7 returns 5, since juggler takes 1 from 7, and since the result is higher that 1, takes another 1 from the result (6) ending in 5

if the example does not make much sense is because I'm forcing it to be a custom operator

This triggers the fact that when any operator is added DEFAULT OPERATORS are ignored:
if anything is added through parameter operator= a conditional on the constructor (__init__) makes it imposible to append new operators to the default operators

Is this a feature? an optimization feature? maybe I am not using the package correctly

I thought the documentation could use something like:

adding operator Or would require the following:

simple_eval("True Or False", operators={"Or": lambda x, y: x | y})

returns True

simple_eval("1 juggler 7", operators={"juggler": lambda x, y: 
                                       y - 2 *x if (y - x) > x else y - x })

returns 5

this becomes extremely handy when using complex operators for time series when comparisons are time wise (maybe sent in tuple form)

simple_eval("(t0, t1) crosses_above (s0, s1)", 
            operators={"crosses_above": lambda t, s: t[1] > s[1] if t[0] < s[0] else False})

returns True or False depending on the case
when: t[0, 1] = 2, 4 and s[0, 1] = 2.5, 3.5; crosses_above returns True
when: t[0, 1] = 2, 3 and s[0, 1] = 2.5, 3.5; crosses_above returns False

When this issue is clear to me I could open a fork and send the PR with the respective changes into the documentation

Also I am impressed at your work, wish you a wonderful day sir

Can't install...

How do I install with pip? (I've got a bad feeling I'm missing something really obvious)

Help is not included when using pyinstaller

I'm having an issue when creating a python binary using Pyinstaller. It does not include the site module , which is where help comes from. This results in a NameError when importing simpleeval. As including site seems like it would cause Pyinstaller significant issues it might be wise to check for it's existence before adding it to your excluded keywords list in simpleeval.

The relevant code is DISALLOW_FUNCTIONS = {type, isinstance, eval, getattr, setattr, help, repr, compile, open}

Here's a pyinstaller issue I was able to find that is related.

pyinstaller/pyinstaller#4448

If you feel this is a pyinstaller issue I can recreate this issue over there.

Expression does not give expected result

Consider the following:

out = True
position = 3
expr = '(out and position <=6 and -10) or (out and position > 6 and -5) or (not out and 15)'

simple_eval(expr, names={'out': True, 'position': 3} )

gives the result

True

This is wrong. Using

eval(expr)

we get the correct result:

-10

Is this a bug? Or intentional?

README doesn't render correctly on PyPI

Hi! This is what the PyPI page looks like to me (Chrome/Android):

storage emulated 0 firespeed org resizeimage 612-452-1538742958902

IME with markdown, adding a long_description_content_type='<your_format>' to your setup(...) should make the page render correctly. (I'm not sure if it's supposed to be 'rst' or 'reStructuredText' though.) You might have to update your setuptools, some older versions don't recognize that parameter.

safe_lambda

Hi! maybe this can help:

def safe_lambda(x, y):
  return lambda z: simple_eval(y, names={x:z})

list(filter(safe_lambda('x', 'x > 2'), [1, 2, 3, 4, 5, 6]))

Support implied multiply

Can support by added for the implied multiplication, for example:
"2(3+4)"

If not, how can a random equation be edited at runtime to insert the '*' ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.