##// END OF EJS Templates
tests: enforce the use of `from __future__ import annotations`...
tests: enforce the use of `from __future__ import annotations` A recent MR and a separate recently landed MR that extracted code to a new file overlooked this, so I think it's worth flagging to ensure consistency. We don't enforce the import for empty files (like `__init__.py`). I'd rather this go into `import-checker.py`, but the import of interest only happens at the top of the file, and its `verify_modern_convention()` calls itself recursively as it transits the AST where the annotations might be. After a few hours of hacking on trying to get it to enforce the import, but only if annotations are used in the module (we generally don't have or check annotations in test files, so don't need this import), I gave up and resorted to this. It won't handle multi-line imports, but this isn't something I'd expect to change often, so this is good enough for now.

File last commit:

r52756:f4733654 default
r53246:662b08ac default
Show More
charencode.py
87 lines | 2.4 KiB | text/x-python | PythonLexer
# charencode.py - miscellaneous character encoding
#
# Copyright 2005-2009 Olivia Mackall <olivia@selenic.com> and others
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import annotations
import array
from .. import pycompat
def isasciistr(s: bytes) -> bool:
try:
s.decode('ascii')
return True
except UnicodeDecodeError:
return False
def asciilower(s: bytes) -> bytes:
"""convert a string to lowercase if ASCII
Raises UnicodeDecodeError if non-ASCII characters are found."""
s.decode('ascii')
return s.lower()
def asciiupper(s: bytes) -> bytes:
"""convert a string to uppercase if ASCII
Raises UnicodeDecodeError if non-ASCII characters are found."""
s.decode('ascii')
return s.upper()
_jsonmap = []
_jsonmap.extend(b"\\u%04x" % x for x in range(32))
_jsonmap.extend(pycompat.bytechr(x) for x in range(32, 127))
_jsonmap.append(b'\\u007f')
_jsonmap[0x09] = b'\\t'
_jsonmap[0x0A] = b'\\n'
_jsonmap[0x22] = b'\\"'
_jsonmap[0x5C] = b'\\\\'
_jsonmap[0x08] = b'\\b'
_jsonmap[0x0C] = b'\\f'
_jsonmap[0x0D] = b'\\r'
_paranoidjsonmap = _jsonmap[:]
_paranoidjsonmap[0x3C] = b'\\u003c' # '<' (e.g. escape "</script>")
_paranoidjsonmap[0x3E] = b'\\u003e' # '>'
_jsonmap.extend(pycompat.bytechr(x) for x in range(128, 256))
def jsonescapeu8fast(u8chars: bytes, paranoid: bool) -> bytes:
"""Convert a UTF-8 byte string to JSON-escaped form (fast path)
Raises ValueError if non-ASCII characters have to be escaped.
"""
if paranoid:
jm = _paranoidjsonmap
else:
jm = _jsonmap
try:
return b''.join(jm[x] for x in bytearray(u8chars))
except IndexError:
raise ValueError
_utf8strict = r'surrogatepass'
def jsonescapeu8fallback(u8chars: bytes, paranoid: bool) -> bytes:
"""Convert a UTF-8 byte string to JSON-escaped form (slow path)
Escapes all non-ASCII characters no matter if paranoid is False.
"""
if paranoid:
jm = _paranoidjsonmap
else:
jm = _jsonmap
# non-BMP char is represented as UTF-16 surrogate pair
u16b = u8chars.decode('utf-8', _utf8strict).encode('utf-16', _utf8strict)
u16codes = array.array('H', u16b)
u16codes.pop(0) # drop BOM
return b''.join(jm[x] if x < 128 else b'\\u%04x' % x for x in u16codes)