test bkp
This commit is contained in:
1 parent
6ccab0347b
commit
954a2fd6d6
18684 files changed
+601012
-190
No files matched your search
@@ -0,0 +1,163 @@
|
||||
"""
|
||||
Utilities and compatibility abstraction.
|
||||
|
||||
Licensed under MIT
|
||||
Copyright (c) 2015 - 2020 Isaac Muse <isaacmuse@gmail.com>
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import warnings
|
||||
import sys
|
||||
from typing import Any, Callable, AnyStr
|
||||
|
||||
PY311 = (3, 11) <= sys.version_info
|
||||
PY312 = (3, 12) <= sys.version_info
|
||||
|
||||
FMT_FIELD = 0
|
||||
FMT_INDEX = 1
|
||||
FMT_ATTR = 2
|
||||
FMT_CONV = 3
|
||||
FMT_SPEC = 4
|
||||
|
||||
|
||||
class StringIter:
|
||||
"""Preprocess replace tokens."""
|
||||
|
||||
def __init__(self, text: str) -> None:
|
||||
"""Initialize."""
|
||||
|
||||
self._string = text
|
||||
self._index = 0
|
||||
|
||||
def __iter__(self) -> StringIter:
|
||||
"""Iterate."""
|
||||
|
||||
return self
|
||||
|
||||
def __next__(self) -> str:
|
||||
"""Python 3 iterator compatible next."""
|
||||
|
||||
return self.iternext()
|
||||
|
||||
@property
|
||||
def index(self) -> int:
|
||||
"""Get Index."""
|
||||
|
||||
return self._index
|
||||
|
||||
def rewind(self, count: int) -> None:
|
||||
"""Rewind index."""
|
||||
|
||||
if count > self._index: # pragma: no cover
|
||||
raise ValueError("Can't rewind past beginning!")
|
||||
|
||||
self._index -= count
|
||||
|
||||
def iternext(self) -> str:
|
||||
"""Iterate through characters of the string."""
|
||||
|
||||
try:
|
||||
char = self._string[self._index]
|
||||
self._index += 1
|
||||
except IndexError as e:
|
||||
raise StopIteration from e
|
||||
|
||||
return char
|
||||
|
||||
|
||||
def _to_bstr(obj: Any) -> bytes:
|
||||
"""Convert to byte string."""
|
||||
|
||||
if isinstance(obj, str):
|
||||
return obj.encode('ascii', 'backslashreplace')
|
||||
elif not isinstance(obj, bytes):
|
||||
return str(obj).encode('ascii', 'backslashreplace')
|
||||
return obj
|
||||
|
||||
|
||||
def _to_str(obj: Any) -> str:
|
||||
"""Convert to string."""
|
||||
|
||||
if not isinstance(obj, str):
|
||||
return str(obj)
|
||||
return obj
|
||||
|
||||
|
||||
def format_captures(
|
||||
captures: list[AnyStr],
|
||||
formatting: tuple[tuple[int, Any]],
|
||||
converter: Callable[[Any], AnyStr],
|
||||
default: AnyStr
|
||||
) -> AnyStr:
|
||||
"""Perform a string format on a set of captures."""
|
||||
|
||||
capture = captures # type: Any
|
||||
for i, fmt in enumerate(formatting, 0):
|
||||
if i == 0:
|
||||
continue
|
||||
fmt_type, value = fmt
|
||||
if fmt_type == FMT_ATTR:
|
||||
# Attribute
|
||||
capture = getattr(capture, value)
|
||||
elif fmt_type == FMT_INDEX:
|
||||
# Index
|
||||
if value is not None:
|
||||
capture = capture[value]
|
||||
else:
|
||||
capture = default if not capture else capture[0]
|
||||
elif fmt_type == FMT_CONV:
|
||||
# Conversion
|
||||
if value == 'a':
|
||||
capture = ascii(capture)
|
||||
elif value == 'r':
|
||||
capture = repr(capture)
|
||||
elif value == 's':
|
||||
# If the object is not string or byte string already
|
||||
capture = str(capture)
|
||||
elif fmt_type == FMT_SPEC:
|
||||
# Integers and floats don't have an explicit 's' format type.
|
||||
if value[3] and value[3] == 's':
|
||||
if isinstance(capture, int): # pragma: no cover
|
||||
raise ValueError("Unknown format code 's' for object of type 'int'")
|
||||
if isinstance(capture, float): # pragma: no cover
|
||||
raise ValueError("Unknown format code 's' for object of type 'float'")
|
||||
|
||||
# Ensure object is a byte string
|
||||
capture = converter(capture)
|
||||
|
||||
spec_type = value[1]
|
||||
if spec_type == '^':
|
||||
capture = capture.center(value[2], value[0])
|
||||
elif spec_type == ">":
|
||||
capture = capture.rjust(value[2], value[0])
|
||||
else:
|
||||
capture = capture.ljust(value[2], value[0])
|
||||
|
||||
# Make sure the final object is a byte string
|
||||
return converter(capture)
|
||||
|
||||
|
||||
class Immutable:
|
||||
"""Immutable."""
|
||||
|
||||
__slots__: tuple[Any, ...] = ()
|
||||
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
"""Initialize."""
|
||||
|
||||
for k, v in kwargs.items():
|
||||
super().__setattr__(k, v)
|
||||
|
||||
def __setattr__(self, name: str, value: Any) -> None:
|
||||
"""Prevent mutability."""
|
||||
|
||||
raise AttributeError('Class is immutable!')
|
||||
|
||||
|
||||
def warn_deprecated(message: str, stacklevel: int = 2) -> None: # pragma: no cover
|
||||
"""Warn deprecated."""
|
||||
|
||||
warnings.warn(
|
||||
message,
|
||||
category=DeprecationWarning,
|
||||
stacklevel=stacklevel
|
||||
)
|
||||
Reference in new issue
Block a user