Mercurial > public > mercurial-scm > hg
comparison 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 |
comparison
equal
deleted
inserted
replaced
37289:5fadc63ac99f | 37290:cc5a040fe150 |
---|---|
7 # This software may be used and distributed according to the terms of the | 7 # This software may be used and distributed according to the terms of the |
8 # GNU General Public License version 2 or any later version. | 8 # GNU General Public License version 2 or any later version. |
9 | 9 |
10 from __future__ import absolute_import | 10 from __future__ import absolute_import |
11 | 11 |
12 import __future__ | |
12 import codecs | 13 import codecs |
13 import re as remod | 14 import re as remod |
14 import textwrap | 15 import textwrap |
15 | 16 |
16 from ..i18n import _ | 17 from ..i18n import _ |
495 """Parse s into a boolean. | 496 """Parse s into a boolean. |
496 | 497 |
497 If s is not a valid boolean, returns None. | 498 If s is not a valid boolean, returns None. |
498 """ | 499 """ |
499 return _booleans.get(s.lower(), None) | 500 return _booleans.get(s.lower(), None) |
501 | |
502 def evalpython(s): | |
503 """Evaluate a string containing a Python expression. | |
504 | |
505 THIS FUNCTION IS NOT SAFE TO USE ON UNTRUSTED INPUT. IT'S USE SHOULD BE | |
506 LIMITED TO DEVELOPER-FACING FUNCTIONALITY. | |
507 """ | |
508 globs = { | |
509 r'__builtins__': { | |
510 r'None': None, | |
511 r'False': False, | |
512 r'True': True, | |
513 r'int': int, | |
514 r'set': set, | |
515 r'tuple': tuple, | |
516 # Don't need to expose dict and list because we can use | |
517 # literals. | |
518 }, | |
519 } | |
520 | |
521 # We can't use eval() directly because it inherits compiler | |
522 # flags from this module and we need unicode literals for Python 3 | |
523 # compatibility. | |
524 code = compile(s, r'<string>', r'eval', | |
525 __future__.unicode_literals.compiler_flag, True) | |
526 return eval(code, globs, {}) |