[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2024-04-13 00:00:18 +00:00
parent 72ad6dc953
commit f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions

View file

@ -1,8 +1,10 @@
from __future__ import annotations
from .terminalwriter import get_terminal_width
from .terminalwriter import TerminalWriter
__all__ = [
"TerminalWriter",
"get_terminal_width",
'TerminalWriter',
'get_terminal_width',
]

View file

@ -13,11 +13,13 @@
# tuples with fairly non-descriptive content. This is modeled very much
# after Lisp/Scheme - style pretty-printing of lists. If you find it
# useful, thank small children who sleep at night.
from __future__ import annotations
import collections as _collections
import dataclasses as _dataclasses
from io import StringIO as _StringIO
import re
import types as _types
from io import StringIO as _StringIO
from typing import Any
from typing import Callable
from typing import Dict
@ -39,7 +41,7 @@ class _safe_key:
"""
__slots__ = ["obj"]
__slots__ = ['obj']
def __init__(self, obj):
self.obj = obj
@ -64,7 +66,7 @@ class PrettyPrinter:
self,
indent: int = 4,
width: int = 80,
depth: Optional[int] = None,
depth: int | None = None,
) -> None:
"""Handle pretty printing operations onto a stream using a set of
configured parameters.
@ -80,11 +82,11 @@ class PrettyPrinter:
"""
if indent < 0:
raise ValueError("indent must be >= 0")
raise ValueError('indent must be >= 0')
if depth is not None and depth <= 0:
raise ValueError("depth must be > 0")
raise ValueError('depth must be > 0')
if not width:
raise ValueError("width must be != 0")
raise ValueError('width must be != 0')
self._depth = depth
self._indent_per_level = indent
self._width = width
@ -100,7 +102,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
objid = id(object)
@ -114,17 +116,16 @@ class PrettyPrinter:
p(self, object, stream, indent, allowance, context, level + 1)
context.remove(objid)
elif (
_dataclasses.is_dataclass(object)
and not isinstance(object, type)
and object.__dataclass_params__.repr
and
_dataclasses.is_dataclass(object) and
not isinstance(object, type) and
object.__dataclass_params__.repr and
# Check dataclass has generated repr method.
hasattr(object.__repr__, "__wrapped__")
and "__create_fn__" in object.__repr__.__wrapped__.__qualname__
hasattr(object.__repr__, '__wrapped__') and
'__create_fn__' in object.__repr__.__wrapped__.__qualname__
):
context.add(objid)
self._pprint_dataclass(
object, stream, indent, allowance, context, level + 1
object, stream, indent, allowance, context, level + 1,
)
context.remove(objid)
else:
@ -136,7 +137,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
cls_name = object.__class__.__name__
@ -145,13 +146,13 @@ class PrettyPrinter:
for f in _dataclasses.fields(object)
if f.repr
]
stream.write(cls_name + "(")
stream.write(cls_name + '(')
self._format_namespace_items(items, stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch: Dict[
_dispatch: dict[
Callable[..., str],
Callable[["PrettyPrinter", Any, IO[str], int, int, Set[int], int], None],
Callable[[PrettyPrinter, Any, IO[str], int, int, set[int], int], None],
] = {}
def _pprint_dict(
@ -160,14 +161,14 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
write = stream.write
write("{")
write('{')
items = sorted(object.items(), key=_safe_tuple)
self._format_dict_items(items, stream, indent, allowance, context, level)
write("}")
write('}')
_dispatch[dict.__repr__] = _pprint_dict
@ -177,16 +178,16 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if not len(object):
stream.write(repr(object))
return
cls = object.__class__
stream.write(cls.__name__ + "(")
stream.write(cls.__name__ + '(')
self._pprint_dict(object, stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch[_collections.OrderedDict.__repr__] = _pprint_ordered_dict
@ -196,12 +197,12 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
stream.write("[")
stream.write('[')
self._format_items(object, stream, indent, allowance, context, level)
stream.write("]")
stream.write(']')
_dispatch[list.__repr__] = _pprint_list
@ -211,12 +212,12 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
stream.write("(")
stream.write('(')
self._format_items(object, stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch[tuple.__repr__] = _pprint_tuple
@ -226,7 +227,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if not len(object):
@ -234,11 +235,11 @@ class PrettyPrinter:
return
typ = object.__class__
if typ is set:
stream.write("{")
endchar = "}"
stream.write('{')
endchar = '}'
else:
stream.write(typ.__name__ + "({")
endchar = "})"
stream.write(typ.__name__ + '({')
endchar = '})'
object = sorted(object, key=_safe_key)
self._format_items(object, stream, indent, allowance, context, level)
stream.write(endchar)
@ -252,7 +253,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
write = stream.write
@ -273,12 +274,12 @@ class PrettyPrinter:
chunks.append(rep)
else:
# A list of alternating (non-space, space) strings
parts = re.findall(r"\S*\s*", line)
parts = re.findall(r'\S*\s*', line)
assert parts
assert not parts[-1]
parts.pop() # drop empty last part
max_width2 = max_width
current = ""
current = ''
for j, part in enumerate(parts):
candidate = current + part
if j == len(parts) - 1 and i == len(lines) - 1:
@ -295,13 +296,13 @@ class PrettyPrinter:
write(rep)
return
if level == 1:
write("(")
write('(')
for i, rep in enumerate(chunks):
if i > 0:
write("\n" + " " * indent)
write('\n' + ' ' * indent)
write(rep)
if level == 1:
write(")")
write(')')
_dispatch[str.__repr__] = _pprint_str
@ -311,7 +312,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
write = stream.write
@ -322,15 +323,15 @@ class PrettyPrinter:
if parens:
indent += 1
allowance += 1
write("(")
delim = ""
write('(')
delim = ''
for rep in _wrap_bytes_repr(object, self._width - indent, allowance):
write(delim)
write(rep)
if not delim:
delim = "\n" + " " * indent
delim = '\n' + ' ' * indent
if parens:
write(")")
write(')')
_dispatch[bytes.__repr__] = _pprint_bytes
@ -340,15 +341,15 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
write = stream.write
write("bytearray(")
write('bytearray(')
self._pprint_bytes(
bytes(object), stream, indent + 10, allowance + 1, context, level + 1
bytes(object), stream, indent + 10, allowance + 1, context, level + 1,
)
write(")")
write(')')
_dispatch[bytearray.__repr__] = _pprint_bytearray
@ -358,12 +359,12 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
stream.write("mappingproxy(")
stream.write('mappingproxy(')
self._format(object.copy(), stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch[_types.MappingProxyType.__repr__] = _pprint_mappingproxy
@ -373,29 +374,29 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if type(object) is _types.SimpleNamespace:
# The SimpleNamespace repr is "namespace" instead of the class
# name, so we do the same here. For subclasses; use the class name.
cls_name = "namespace"
cls_name = 'namespace'
else:
cls_name = object.__class__.__name__
items = object.__dict__.items()
stream.write(cls_name + "(")
stream.write(cls_name + '(')
self._format_namespace_items(items, stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch[_types.SimpleNamespace.__repr__] = _pprint_simplenamespace
def _format_dict_items(
self,
items: List[Tuple[Any, Any]],
items: list[tuple[Any, Any]],
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if not items:
@ -403,23 +404,23 @@ class PrettyPrinter:
write = stream.write
item_indent = indent + self._indent_per_level
delimnl = "\n" + " " * item_indent
delimnl = '\n' + ' ' * item_indent
for key, ent in items:
write(delimnl)
write(self._repr(key, context, level))
write(": ")
write(': ')
self._format(ent, stream, item_indent, 1, context, level)
write(",")
write(',')
write("\n" + " " * indent)
write('\n' + ' ' * indent)
def _format_namespace_items(
self,
items: List[Tuple[Any, Any]],
items: list[tuple[Any, Any]],
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if not items:
@ -427,15 +428,15 @@ class PrettyPrinter:
write = stream.write
item_indent = indent + self._indent_per_level
delimnl = "\n" + " " * item_indent
delimnl = '\n' + ' ' * item_indent
for key, ent in items:
write(delimnl)
write(key)
write("=")
write('=')
if id(ent) in context:
# Special-case representation of recursion to match standard
# recursive dataclass repr.
write("...")
write('...')
else:
self._format(
ent,
@ -446,17 +447,17 @@ class PrettyPrinter:
level,
)
write(",")
write(',')
write("\n" + " " * indent)
write('\n' + ' ' * indent)
def _format_items(
self,
items: List[Any],
items: list[Any],
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if not items:
@ -464,16 +465,16 @@ class PrettyPrinter:
write = stream.write
item_indent = indent + self._indent_per_level
delimnl = "\n" + " " * item_indent
delimnl = '\n' + ' ' * item_indent
for item in items:
write(delimnl)
self._format(item, stream, item_indent, 1, context, level)
write(",")
write(',')
write("\n" + " " * indent)
write('\n' + ' ' * indent)
def _repr(self, object: Any, context: Set[int], level: int) -> str:
def _repr(self, object: Any, context: set[int], level: int) -> str:
return self._safe_repr(object, context.copy(), self._depth, level)
def _pprint_default_dict(
@ -482,13 +483,13 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
rdf = self._repr(object.default_factory, context, level)
stream.write(f"{object.__class__.__name__}({rdf}, ")
stream.write(f'{object.__class__.__name__}({rdf}, ')
self._pprint_dict(object, stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch[_collections.defaultdict.__repr__] = _pprint_default_dict
@ -498,18 +499,18 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
stream.write(object.__class__.__name__ + "(")
stream.write(object.__class__.__name__ + '(')
if object:
stream.write("{")
stream.write('{')
items = object.most_common()
self._format_dict_items(items, stream, indent, allowance, context, level)
stream.write("}")
stream.write('}')
stream.write(")")
stream.write(')')
_dispatch[_collections.Counter.__repr__] = _pprint_counter
@ -519,16 +520,16 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
if not len(object.maps) or (len(object.maps) == 1 and not len(object.maps[0])):
stream.write(repr(object))
return
stream.write(object.__class__.__name__ + "(")
stream.write(object.__class__.__name__ + '(')
self._format_items(object.maps, stream, indent, allowance, context, level)
stream.write(")")
stream.write(')')
_dispatch[_collections.ChainMap.__repr__] = _pprint_chain_map
@ -538,16 +539,16 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
stream.write(object.__class__.__name__ + "(")
stream.write(object.__class__.__name__ + '(')
if object.maxlen is not None:
stream.write("maxlen=%d, " % object.maxlen)
stream.write("[")
stream.write('maxlen=%d, ' % object.maxlen)
stream.write('[')
self._format_items(object, stream, indent, allowance + 1, context, level)
stream.write("])")
stream.write('])')
_dispatch[_collections.deque.__repr__] = _pprint_deque
@ -557,7 +558,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
self._format(object.data, stream, indent, allowance, context, level - 1)
@ -570,7 +571,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
self._format(object.data, stream, indent, allowance, context, level - 1)
@ -583,7 +584,7 @@ class PrettyPrinter:
stream: IO[str],
indent: int,
allowance: int,
context: Set[int],
context: set[int],
level: int,
) -> None:
self._format(object.data, stream, indent, allowance, context, level - 1)
@ -591,49 +592,49 @@ class PrettyPrinter:
_dispatch[_collections.UserString.__repr__] = _pprint_user_string
def _safe_repr(
self, object: Any, context: Set[int], maxlevels: Optional[int], level: int
self, object: Any, context: set[int], maxlevels: int | None, level: int,
) -> str:
typ = type(object)
if typ in _builtin_scalars:
return repr(object)
r = getattr(typ, "__repr__", None)
r = getattr(typ, '__repr__', None)
if issubclass(typ, dict) and r is dict.__repr__:
if not object:
return "{}"
return '{}'
objid = id(object)
if maxlevels and level >= maxlevels:
return "{...}"
return '{...}'
if objid in context:
return _recursion(object)
context.add(objid)
components: List[str] = []
components: list[str] = []
append = components.append
level += 1
for k, v in sorted(object.items(), key=_safe_tuple):
krepr = self._safe_repr(k, context, maxlevels, level)
vrepr = self._safe_repr(v, context, maxlevels, level)
append(f"{krepr}: {vrepr}")
append(f'{krepr}: {vrepr}')
context.remove(objid)
return "{%s}" % ", ".join(components)
return '{%s}' % ', '.join(components)
if (issubclass(typ, list) and r is list.__repr__) or (
issubclass(typ, tuple) and r is tuple.__repr__
):
if issubclass(typ, list):
if not object:
return "[]"
format = "[%s]"
return '[]'
format = '[%s]'
elif len(object) == 1:
format = "(%s,)"
format = '(%s,)'
else:
if not object:
return "()"
format = "(%s)"
return '()'
format = '(%s)'
objid = id(object)
if maxlevels and level >= maxlevels:
return format % "..."
return format % '...'
if objid in context:
return _recursion(object)
context.add(objid)
@ -644,25 +645,25 @@ class PrettyPrinter:
orepr = self._safe_repr(o, context, maxlevels, level)
append(orepr)
context.remove(objid)
return format % ", ".join(components)
return format % ', '.join(components)
return repr(object)
_builtin_scalars = frozenset(
{str, bytes, bytearray, float, complex, bool, type(None), int}
{str, bytes, bytearray, float, complex, bool, type(None), int},
)
def _recursion(object: Any) -> str:
return f"<Recursion on {type(object).__name__} with id={id(object)}>"
return f'<Recursion on {type(object).__name__} with id={id(object)}>'
def _wrap_bytes_repr(object: Any, width: int, allowance: int) -> Iterator[str]:
current = b""
current = b''
last = len(object) // 4 * 4
for i in range(0, len(object), 4):
part = object[i : i + 4]
part = object[i: i + 4]
candidate = current + part
if i == last:
width -= allowance

View file

@ -1,3 +1,5 @@
from __future__ import annotations
import pprint
import reprlib
from typing import Optional
@ -18,9 +20,9 @@ def _format_repr_exception(exc: BaseException, obj: object) -> str:
except (KeyboardInterrupt, SystemExit):
raise
except BaseException as exc:
exc_info = f"unpresentable exception ({_try_repr_or_str(exc)})"
exc_info = f'unpresentable exception ({_try_repr_or_str(exc)})'
return (
f"<[{exc_info} raised in repr()] {type(obj).__name__} object at 0x{id(obj):x}>"
f'<[{exc_info} raised in repr()] {type(obj).__name__} object at 0x{id(obj):x}>'
)
@ -28,7 +30,7 @@ def _ellipsize(s: str, maxsize: int) -> str:
if len(s) > maxsize:
i = max(0, (maxsize - 3) // 2)
j = max(0, maxsize - 3 - i)
return s[:i] + "..." + s[len(s) - j :]
return s[:i] + '...' + s[len(s) - j:]
return s
@ -38,7 +40,7 @@ class SafeRepr(reprlib.Repr):
information on exceptions raised during the call.
"""
def __init__(self, maxsize: Optional[int], use_ascii: bool = False) -> None:
def __init__(self, maxsize: int | None, use_ascii: bool = False) -> None:
"""
:param maxsize:
If not None, will truncate the resulting repr to that specific size, using ellipsis
@ -97,7 +99,7 @@ DEFAULT_REPR_MAX_SIZE = 240
def saferepr(
obj: object, maxsize: Optional[int] = DEFAULT_REPR_MAX_SIZE, use_ascii: bool = False
obj: object, maxsize: int | None = DEFAULT_REPR_MAX_SIZE, use_ascii: bool = False,
) -> str:
"""Return a size-limited safe repr-string for the given object.

View file

@ -1,4 +1,5 @@
"""Helper functions for writing to terminals and files."""
from __future__ import annotations
import os
import shutil
@ -26,16 +27,16 @@ def get_terminal_width() -> int:
def should_do_markup(file: TextIO) -> bool:
if os.environ.get("PY_COLORS") == "1":
if os.environ.get('PY_COLORS') == '1':
return True
if os.environ.get("PY_COLORS") == "0":
if os.environ.get('PY_COLORS') == '0':
return False
if os.environ.get("NO_COLOR"):
if os.environ.get('NO_COLOR'):
return False
if os.environ.get("FORCE_COLOR"):
if os.environ.get('FORCE_COLOR'):
return True
return (
hasattr(file, "isatty") and file.isatty() and os.environ.get("TERM") != "dumb"
hasattr(file, 'isatty') and file.isatty() and os.environ.get('TERM') != 'dumb'
)
@ -64,10 +65,10 @@ class TerminalWriter:
invert=7,
)
def __init__(self, file: Optional[TextIO] = None) -> None:
def __init__(self, file: TextIO | None = None) -> None:
if file is None:
file = sys.stdout
if hasattr(file, "isatty") and file.isatty() and sys.platform == "win32":
if hasattr(file, 'isatty') and file.isatty() and sys.platform == 'win32':
try:
import colorama
except ImportError:
@ -77,8 +78,8 @@ class TerminalWriter:
assert file is not None
self._file = file
self.hasmarkup = should_do_markup(file)
self._current_line = ""
self._terminal_width: Optional[int] = None
self._current_line = ''
self._terminal_width: int | None = None
self.code_highlight = True
@property
@ -99,25 +100,25 @@ class TerminalWriter:
def markup(self, text: str, **markup: bool) -> str:
for name in markup:
if name not in self._esctable:
raise ValueError(f"unknown markup: {name!r}")
raise ValueError(f'unknown markup: {name!r}')
if self.hasmarkup:
esc = [self._esctable[name] for name, on in markup.items() if on]
if esc:
text = "".join("\x1b[%sm" % cod for cod in esc) + text + "\x1b[0m"
text = ''.join('\x1b[%sm' % cod for cod in esc) + text + '\x1b[0m'
return text
def sep(
self,
sepchar: str,
title: Optional[str] = None,
fullwidth: Optional[int] = None,
title: str | None = None,
fullwidth: int | None = None,
**markup: bool,
) -> None:
if fullwidth is None:
fullwidth = self.fullwidth
# The goal is to have the line be as long as possible
# under the condition that len(line) <= fullwidth.
if sys.platform == "win32":
if sys.platform == 'win32':
# If we print in the last column on windows we are on a
# new line but there is no way to verify/neutralize this
# (we may not know the exact line width).
@ -130,7 +131,7 @@ class TerminalWriter:
# N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
N = max((fullwidth - len(title) - 2) // (2 * len(sepchar)), 1)
fill = sepchar * N
line = f"{fill} {title} {fill}"
line = f'{fill} {title} {fill}'
else:
# we want len(sepchar)*N <= fullwidth
# i.e. N <= fullwidth // len(sepchar)
@ -145,8 +146,8 @@ class TerminalWriter:
def write(self, msg: str, *, flush: bool = False, **markup: bool) -> None:
if msg:
current_line = msg.rsplit("\n", 1)[-1]
if "\n" in msg:
current_line = msg.rsplit('\n', 1)[-1]
if '\n' in msg:
self._current_line = current_line
else:
self._current_line += current_line
@ -162,15 +163,15 @@ class TerminalWriter:
# When the Unicode situation improves we should consider
# letting the error propagate instead of masking it (see #7475
# for one brief attempt).
msg = msg.encode("unicode-escape").decode("ascii")
msg = msg.encode('unicode-escape').decode('ascii')
self._file.write(msg)
if flush:
self.flush()
def line(self, s: str = "", **markup: bool) -> None:
def line(self, s: str = '', **markup: bool) -> None:
self.write(s, **markup)
self.write("\n")
self.write('\n')
def flush(self) -> None:
self._file.flush()
@ -184,17 +185,17 @@ class TerminalWriter:
"""
if indents and len(indents) != len(lines):
raise ValueError(
f"indents size ({len(indents)}) should have same size as lines ({len(lines)})"
f'indents size ({len(indents)}) should have same size as lines ({len(lines)})',
)
if not indents:
indents = [""] * len(lines)
source = "\n".join(lines)
indents = [''] * len(lines)
source = '\n'.join(lines)
new_lines = self._highlight(source).splitlines()
for indent, new_line in zip(indents, new_lines):
self.line(indent + new_line)
def _highlight(
self, source: str, lexer: Literal["diff", "python"] = "python"
self, source: str, lexer: Literal['diff', 'python'] = 'python',
) -> str:
"""Highlight the given source if we have markup support."""
from _pytest.config.exceptions import UsageError
@ -205,9 +206,9 @@ class TerminalWriter:
try:
from pygments.formatters.terminal import TerminalFormatter
if lexer == "python":
if lexer == 'python':
from pygments.lexers.python import PythonLexer as Lexer
elif lexer == "diff":
elif lexer == 'diff':
from pygments.lexers.diff import DiffLexer as Lexer
from pygments import highlight
import pygments.util
@ -219,30 +220,30 @@ class TerminalWriter:
source,
Lexer(),
TerminalFormatter(
bg=os.getenv("PYTEST_THEME_MODE", "dark"),
style=os.getenv("PYTEST_THEME"),
bg=os.getenv('PYTEST_THEME_MODE', 'dark'),
style=os.getenv('PYTEST_THEME'),
),
)
# pygments terminal formatter may add a newline when there wasn't one.
# We don't want this, remove.
if highlighted[-1] == "\n" and source[-1] != "\n":
if highlighted[-1] == '\n' and source[-1] != '\n':
highlighted = highlighted[:-1]
# Some lexers will not set the initial color explicitly
# which may lead to the previous color being propagated to the
# start of the expression, so reset first.
return "\x1b[0m" + highlighted
return '\x1b[0m' + highlighted
except pygments.util.ClassNotFound as e:
raise UsageError(
"PYTEST_THEME environment variable had an invalid value: '{}'. "
"Only valid pygment styles are allowed.".format(
os.getenv("PYTEST_THEME")
)
'Only valid pygment styles are allowed.'.format(
os.getenv('PYTEST_THEME'),
),
) from e
except pygments.util.OptionError as e:
raise UsageError(
"PYTEST_THEME_MODE environment variable had an invalid value: '{}'. "
"The only allowed values are 'dark' and 'light'.".format(
os.getenv("PYTEST_THEME_MODE")
)
os.getenv('PYTEST_THEME_MODE'),
),
) from e

View file

@ -1,5 +1,7 @@
from functools import lru_cache
from __future__ import annotations
import unicodedata
from functools import lru_cache
@lru_cache(100)
@ -17,25 +19,25 @@ def wcwidth(c: str) -> int:
# Some Cf/Zp/Zl characters which should be zero-width.
if (
o == 0x0000
or 0x200B <= o <= 0x200F
or 0x2028 <= o <= 0x202E
or 0x2060 <= o <= 0x2063
o == 0x0000 or
0x200B <= o <= 0x200F or
0x2028 <= o <= 0x202E or
0x2060 <= o <= 0x2063
):
return 0
category = unicodedata.category(c)
# Control characters.
if category == "Cc":
if category == 'Cc':
return -1
# Combining characters with zero width.
if category in ("Me", "Mn"):
if category in ('Me', 'Mn'):
return 0
# Full/Wide east asian characters.
if unicodedata.east_asian_width(c) in ("F", "W"):
if unicodedata.east_asian_width(c) in ('F', 'W'):
return 2
return 1
@ -47,7 +49,7 @@ def wcswidth(s: str) -> int:
Returns -1 if the string contains non-printable characters.
"""
width = 0
for c in unicodedata.normalize("NFC", s):
for c in unicodedata.normalize('NFC', s):
wc = wcwidth(c)
if wc < 0:
return -1