Commit Graph

2 Commits

Author SHA1 Message Date
Ran Benita 622c4ce02e mark/expression: support compiling once and reusing for multiple evaluations
In current pytest, the same expression is matched against all items. But
it is re-parsed for every match.

Add support for "compiling" an expression and reusing the result. Errors
may only occur during compilation.

This is done by parsing the expression into a Python `ast.Expression`,
then `compile()`ing it into a code object. Evaluation is then done using
`eval()`.

Note: historically we used to use `eval` directly on the user input --
this is not the case here, the expression is entirely under our control
according to our grammar, we just JIT-compile it to Python as a
(completely safe) optimization.
2020-05-12 12:53:12 +03:00
Ran Benita a718ad6363 Stop using Python's eval() for -m and -k
Previously, the expressions given to the `-m` and `-k` options were
evaluated with `eval`. This causes a few issues:

- Python keywords cannot be used.

- Constants like numbers, None, True, False are not handled correctly.

- Various syntax like numeric operators and `X if Y else Z` is supported
  unintentionally.

- `eval()` is somewhat dangerous for arbitrary input.

- Can fail in many ways so requires `except Exception`.

The format we want to support is quite simple, so change to a custom
parser. This fixes the issues above, and gives us full control of the
format, so can be documented comprehensively and even be extended in the
future if we wish.
2020-05-01 12:59:06 +03:00