Mercurial > public > mercurial-scm > hg
diff mercurial/utils/stringutil.py @ 37290:cc5a040fe150
wireproto: syntax for encoding CBOR into frames
We just vendored a library for encoding and decoding the CBOR
data format. While the intent of that vendor was to support state
files, CBOR is really a nice data format. It is extensible and
compact.
I've been feeling dirty inventing my own data formats for
frame payloads. While custom formats can always beat out a generic
format, there is a cost to be paid in terms of implementation,
comprehension, etc. CBOR is compact enough that I'm not too
worried about efficiency loss. I think the benefits of using
a standardized format outweigh rolling our own formats. So
I plan to make heavy use of CBOR in the wire protocol going
forward.
This commit introduces support for encoding CBOR data in frame
payloads to our function to make a frame from a human string.
We do need to employ some low-level Python code in order to
evaluate a string as a Python expression. But other than that,
this should hopefully be pretty straightforward.
Unit tests for this function have been added.
Differential Revision: https://phab.mercurial-scm.org/D2948
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 28 Mar 2018 15:05:39 -0700 |
parents | 2ed180117f76 |
children | 2f859ad7ed8c |
line wrap: on
line diff
--- 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, {})