pydata/numexpr

ValueError exception for scientific notation with digits after .

t20100 opened this issue · 2 comments

t20100 commented

With numexpr v2.8.6, the following code:

import numexpr
numexpr.NumExpr("4.0e-9*x")

raises an exception ValueError: Expression 4.0e-9*x has forbidden control characters.

Complete exception:
File ~/venvs/py310/lib/python3.10/site-packages/numexpr/necompiler.py:639, in NumExpr(ex, signature, sanitize, **kwargs)
    637 _frame_depth = 1
    638 context = getContext(kwargs, _frame_depth=_frame_depth)
--> 639 threeAddrProgram, inputsig, tempsig, constants, input_names = precompile(ex, signature, context, sanitize=sanitize)
    640 program = compileThreeAddrForm(threeAddrProgram)
    641 return interpreter.NumExpr(inputsig.encode('ascii'),
    642                            tempsig.encode('ascii'),
    643                            program, constants, input_names)

File ~/venvs/py310/lib/python3.10/site-packages/numexpr/necompiler.py:576, in precompile(ex, signature, context, sanitize)
    573 input_order = [name for (name, type_) in signature]
    575 if isinstance(ex, str):
--> 576     ex = stringToExpression(ex, types, context, sanitize)
    578 # the AST is like the expression, but the node objects don't have
    579 # any odd interpretations
    581 ast = expressionToAST(ex)

File ~/venvs/py310/lib/python3.10/site-packages/numexpr/necompiler.py:281, in stringToExpression(s, types, context, sanitize)
    279     no_whitespace = re.sub(r'\s+', '', s)
    280     if _blacklist_re.search(no_whitespace) is not None:
--> 281         raise ValueError(f'Expression {s} has forbidden control characters.')
    283 old_ctx = expressions._context.get_current_context()
    284 try:

ValueError: Expression 4.0e-9*x has forbidden control characters.

This is working with v2.8.5.

Also, numexpr.NumExpr("4.e-9*x") or numexpr.NumExpr("4.0*x") works fine with v2.8.6.

t20100 commented

Changing this regular expression:

_attr_pat = r'\.\b(?!(real|imag|[eE]?[+-]?\d+)\b)'

to:

_attr_pat = r'\.\b(?!(real|imag|\d*[eE]?[+-]?\d+)\b)'

makes it accept trailing zeros.

In fact, it was caught by @rebecca-palmer earlier (#442 (comment)).

They proposed a similar correction to the regexp that didn't make it in the release.