--- a/mercurial/utils/stringutil.py Mon Mar 26 13:59:56 2018 -0700
+++ b/mercurial/utils/stringutil.py Wed Mar 28 15:05:39 2018 -0700
@@ -9,6 +9,7 @@
from __future__ import absolute_import
+import __future__
import codecs
import re as remod
import textwrap
@@ -497,3 +498,29 @@
If s is not a valid boolean, returns None.
"""
return _booleans.get(s.lower(), None)
+
+def evalpython(s):
+ """Evaluate a string containing a Python expression.
+
+ THIS FUNCTION IS NOT SAFE TO USE ON UNTRUSTED INPUT. IT'S USE SHOULD BE
+ LIMITED TO DEVELOPER-FACING FUNCTIONALITY.
+ """
+ globs = {
+ r'__builtins__': {
+ r'None': None,
+ r'False': False,
+ r'True': True,
+ r'int': int,
+ r'set': set,
+ r'tuple': tuple,
+ # Don't need to expose dict and list because we can use
+ # literals.
+ },
+ }
+
+ # We can't use eval() directly because it inherits compiler
+ # flags from this module and we need unicode literals for Python 3
+ # compatibility.
+ code = compile(s, r'<string>', r'eval',
+ __future__.unicode_literals.compiler_flag, True)
+ return eval(code, globs, {})