Scheduler Evaluator: raise recursion limit

This raises the Python recursion limit for
evaluate() calls -- reasonable formulas currently
exceed the default limit of 1000 inside of pyparsing.

Closes-Bug: #1966904
Change-Id: I52e04b8f8e96cc2bcf0ab22ca77e999e1a06e26d
This commit is contained in:
Eric Harney 2022-03-29 10:13:00 -04:00
parent be71720bb9
commit 0d300c96ac
2 changed files with 15 additions and 0 deletions

View File

@ -17,6 +17,7 @@ from __future__ import annotations # Remove when only supporting python 3.9+
import operator
import re
import sys
from typing import Callable
import pyparsing
@ -291,10 +292,18 @@ def evaluate(expression, **kwargs):
global _vars
_vars = kwargs
# Some reasonable formulas break with the default recursion limit of
# 1000. Raise it here and reset it afterward.
orig_recursion_limit = sys.getrecursionlimit()
if orig_recursion_limit < 3000:
sys.setrecursionlimit(3000)
try:
result = _parser.parseString(expression, parseAll=True)[0]
except pyparsing.ParseException as e:
raise exception.EvaluatorParseException(
_("ParseException: %s") % e)
finally:
sys.setrecursionlimit(orig_recursion_limit)
return result.eval()

View File

@ -138,3 +138,9 @@ class EvaluatorTestCase(test.TestCase):
self.assertRaises(exception.EvaluatorParseException,
evaluator.evaluate,
"7 / 0")
def test_deep_function(self):
"""Ensures that maximum recursion depth is not exceeded."""
self.assertGreater(evaluator.evaluate(
'(((1 + max(1 + (10 / 20), 2, 3)) / 100) + 1)'),
1)