Skip to content

Commit 59b7075

Browse files
committed
Upgrade to Python 3.10+
1 parent ca3175a commit 59b7075

File tree

9 files changed

+102
-121
lines changed

9 files changed

+102
-121
lines changed

curtsies/escseqparse.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def remove_ansi(s: str) -> str:
4141
return re.sub(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]", "", s)
4242

4343

44-
def parse(s: str) -> list[Union[str, dict[str, Union[str, bool, None]]]]:
44+
def parse(s: str) -> list[str | dict[str, str | bool | None]]:
4545
r"""
4646
Returns a list of strings or format dictionaries to describe the strings.
4747
@@ -52,7 +52,7 @@ def parse(s: str) -> list[Union[str, dict[str, Union[str, bool, None]]]]:
5252
>>> parse("\x1b[33m[\x1b[39m\x1b[33m]\x1b[39m\x1b[33m[\x1b[39m\x1b[33m]\x1b[39m\x1b[33m[\x1b[39m\x1b[33m]\x1b[39m\x1b[33m[\x1b[39m")
5353
[{'fg': 'yellow'}, '[', {'fg': None}, {'fg': 'yellow'}, ']', {'fg': None}, {'fg': 'yellow'}, '[', {'fg': None}, {'fg': 'yellow'}, ']', {'fg': None}, {'fg': 'yellow'}, '[', {'fg': None}, {'fg': 'yellow'}, ']', {'fg': None}, {'fg': 'yellow'}, '[', {'fg': None}]
5454
"""
55-
stuff: list[Union[str, dict[str, Union[str, bool, None]]]] = []
55+
stuff: list[str | dict[str, str | bool | None]] = []
5656
rest = s
5757
while True:
5858
front, token, rest = peel_off_esc_code(rest)
@@ -73,7 +73,7 @@ def parse(s: str) -> list[Union[str, dict[str, Union[str, bool, None]]]]:
7373
return stuff
7474

7575

76-
def peel_off_esc_code(s: str) -> tuple[str, Optional[Token], str]:
76+
def peel_off_esc_code(s: str) -> tuple[str, Token | None, str]:
7777
r"""Returns processed text, the next token, and unprocessed text
7878
7979
>>> front, d, rest = peel_off_esc_code('somestuff')
@@ -125,12 +125,12 @@ def peel_off_esc_code(s: str) -> tuple[str, Optional[Token], str]:
125125
return s, None, ""
126126

127127

128-
def token_type(info: Token) -> Optional[list[dict[str, Union[str, bool, None]]]]:
128+
def token_type(info: Token) -> list[dict[str, str | bool | None]] | None:
129129
if info["command"] == "m":
130130
# The default action for ESC[m is to act like ESC[0m
131131
# Ref: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes
132132
values = cast(list[int], info["numbers"]) if len(info["numbers"]) else [0]
133-
tokens: list[dict[str, Union[str, bool, None]]] = []
133+
tokens: list[dict[str, str | bool | None]] = []
134134
for value in values:
135135
if value in FG_NUMBER_TO_COLOR:
136136
tokens.append({"fg": FG_NUMBER_TO_COLOR[value]})

curtsies/events.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ def __init__(self, when: float) -> None:
105105

106106

107107
class WindowChangeEvent(Event):
108-
def __init__(
109-
self, rows: int, columns: int, cursor_dy: Optional[int] = None
110-
) -> None:
108+
def __init__(self, rows: int, columns: int, cursor_dy: int | None = None) -> None:
111109
self.rows = rows
112110
self.columns = columns
113111
self.cursor_dy = cursor_dy
@@ -202,7 +200,7 @@ def get_key(
202200
encoding: str,
203201
keynames: Keynames = Keynames.CURTSIES,
204202
full: bool = False,
205-
) -> Optional[str]:
203+
) -> str | None:
206204
"""Return key pressed from bytes_ or None
207205
208206
Return a key name or None meaning it's an incomplete sequence of bytes
@@ -281,7 +279,7 @@ def could_be_unfinished_utf8(seq: bytes) -> bool:
281279
)
282280

283281

284-
def pp_event(seq: Union[Event, str]) -> Union[str, bytes]:
282+
def pp_event(seq: Event | str) -> str | bytes:
285283
"""Returns pretty representation of an Event or keypress"""
286284

287285
if isinstance(seq, Event):
@@ -290,7 +288,7 @@ def pp_event(seq: Union[Event, str]) -> Union[str, bytes]:
290288
# Get the original sequence back if seq is a pretty name already
291289
rev_curses = {v: k for k, v in CURSES_NAMES.items()}
292290
rev_curtsies = {v: k for k, v in CURTSIES_NAMES.items()}
293-
bytes_seq: Optional[bytes] = None
291+
bytes_seq: bytes | None = None
294292
if seq in rev_curses:
295293
bytes_seq = rev_curses[seq]
296294
elif seq in rev_curtsies:
@@ -303,7 +301,7 @@ def pp_event(seq: Union[Event, str]) -> Union[str, bytes]:
303301
return repr(seq).lstrip("u")[1:-1]
304302

305303

306-
def curtsies_name(seq: bytes) -> Union[str, bytes]:
304+
def curtsies_name(seq: bytes) -> str | bytes:
307305
return CURTSIES_NAMES.get(seq, seq)
308306

309307

curtsies/formatstring.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
from itertools import chain
2626
from typing import (
2727
Any,
28-
Callable,
2928
Dict,
3029
List,
3130
Optional,
@@ -34,7 +33,7 @@
3433
cast,
3534
no_type_check,
3635
)
37-
from collections.abc import Iterable, Iterator, Mapping, MutableMapping
36+
from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMapping
3837

3938
from .escseqparse import parse, remove_ansi
4039
from .termformatconstants import (
@@ -59,21 +58,21 @@
5958
}
6059

6160
two_arg_xforms: Mapping[str, Callable[[str, int], str]] = {
62-
"fg": lambda s, v: "{}{}{}".format(seq(v), s, seq(RESET_FG)),
61+
"fg": lambda s, v: f"{seq(v)}{s}{seq(RESET_FG)}",
6362
"bg": lambda s, v: seq(v) + s + seq(RESET_BG),
6463
}
6564

6665

6766
class FrozenAttributes(dict[str, Union[int, bool]]):
6867
"""Immutable dictionary class for format string attributes"""
6968

70-
def __setitem__(self, key: str, value: Union[int, bool]) -> None:
69+
def __setitem__(self, key: str, value: int | bool) -> None:
7170
raise Exception("Cannot change value.")
7271

7372
def update(self, *args: Any, **kwds: Any) -> None:
7473
raise Exception("Cannot change value.")
7574

76-
def extend(self, dictlike: Mapping[str, Union[int, bool]]) -> "FrozenAttributes":
75+
def extend(self, dictlike: Mapping[str, int | bool]) -> "FrozenAttributes":
7776
return FrozenAttributes(chain(self.items(), dictlike.items()))
7877

7978
def remove(self, *keys: str) -> "FrozenAttributes":
@@ -103,9 +102,7 @@ class Chunk:
103102
104103
Subject to change, not part of the API"""
105104

106-
def __init__(
107-
self, string: str, atts: Optional[Mapping[str, Union[int, bool]]] = None
108-
):
105+
def __init__(self, string: str, atts: Mapping[str, int | bool] | None = None):
109106
if not isinstance(string, str):
110107
raise ValueError("unicode string required, got %r" % string)
111108
self._s = string
@@ -212,7 +209,7 @@ def reinit(self, chunk: Chunk) -> None:
212209
divides.append(divides[-1] + wcwidth(c))
213210
self.divides = divides
214211

215-
def request(self, max_width: int) -> Optional[tuple[int, Chunk]]:
212+
def request(self, max_width: int) -> tuple[int, Chunk] | None:
216213
"""Requests a sub-chunk of max_width or shorter. Returns None if no chunks left."""
217214
if max_width < 1:
218215
raise ValueError("requires positive integer max_width")
@@ -279,10 +276,10 @@ def __init__(self, *components: Chunk) -> None:
279276
self.chunks = list(components)
280277

281278
# caching these leads to a significant speedup
282-
self._unicode: Optional[str] = None
283-
self._len: Optional[int] = None
284-
self._s: Optional[str] = None
285-
self._width: Optional[int] = None
279+
self._unicode: str | None = None
280+
self._len: int | None = None
281+
self._s: str | None = None
282+
self._width: int | None = None
286283

287284
@staticmethod
288285
def from_str(s: str) -> "FmtStr":
@@ -349,7 +346,7 @@ def setslice_with_length(
349346
return result
350347

351348
def splice(
352-
self, new_str: Union[str, "FmtStr"], start: int, end: Optional[int] = None
349+
self, new_str: Union[str, "FmtStr"], start: int, end: int | None = None
353350
) -> "FmtStr":
354351
"""Returns a new FmtStr with the input string spliced into the
355352
the original FmtStr at start and end.
@@ -401,7 +398,7 @@ def splice(
401398
def append(self, string: Union[str, "FmtStr"]) -> "FmtStr":
402399
return self.splice(string, len(self.s))
403400

404-
def copy_with_new_atts(self, **attributes: Union[bool, int]) -> "FmtStr":
401+
def copy_with_new_atts(self, **attributes: bool | int) -> "FmtStr":
405402
"""Returns a new FmtStr with the same content but new formatting"""
406403

407404
return FmtStr(
@@ -426,8 +423,8 @@ def join(self, iterable: Iterable[Union[str, "FmtStr"]]) -> "FmtStr":
426423
# TODO make this split work like str.split
427424
def split(
428425
self,
429-
sep: Optional[str] = None,
430-
maxsplit: Optional[int] = None,
426+
sep: str | None = None,
427+
maxsplit: int | None = None,
431428
regex: bool = False,
432429
) -> list["FmtStr"]:
433430
"""Split based on separator, optionally using a regex.
@@ -462,7 +459,7 @@ def splitlines(self, keepends: bool = False) -> list["FmtStr"]:
462459

463460
# proxying to the string via __getattr__ is insufficient
464461
# because we shouldn't drop foreground or formatting info
465-
def ljust(self, width: int, fillchar: Optional[str] = None) -> "FmtStr":
462+
def ljust(self, width: int, fillchar: str | None = None) -> "FmtStr":
466463
"""S.ljust(width[, fillchar]) -> string
467464
468465
If a fillchar is provided, less formatting information will be preserved
@@ -477,7 +474,7 @@ def ljust(self, width: int, fillchar: Optional[str] = None) -> "FmtStr":
477474
uniform = self.new_with_atts_removed("bg")
478475
return uniform + fmtstr(to_add, **self.shared_atts) if to_add else uniform
479476

480-
def rjust(self, width: int, fillchar: Optional[str] = None) -> "FmtStr":
477+
def rjust(self, width: int, fillchar: str | None = None) -> "FmtStr":
481478
"""S.rjust(width[, fillchar]) -> string
482479
483480
If a fillchar is provided, less formatting information will be preserved
@@ -557,7 +554,7 @@ def __mul__(self, other: int) -> "FmtStr":
557554
# TODO ensure empty FmtStr isn't a problem
558555

559556
@property
560-
def shared_atts(self) -> dict[str, Union[int, bool]]:
557+
def shared_atts(self) -> dict[str, int | bool]:
561558
"""Gets atts shared among all nonzero length component Chunks"""
562559
# TODO cache this, could get ugly for large FmtStrs
563560
atts = {}
@@ -611,7 +608,7 @@ def s(self) -> str:
611608
self._s = "".join(fs.s for fs in self.chunks)
612609
return self._s
613610

614-
def __getitem__(self, index: Union[int, slice]) -> "FmtStr":
611+
def __getitem__(self, index: int | slice) -> "FmtStr":
615612
index = normalize_slice(len(self), index)
616613
counter = 0
617614
parts = []
@@ -631,7 +628,7 @@ def __getitem__(self, index: Union[int, slice]) -> "FmtStr":
631628
break
632629
return FmtStr(*parts) if parts else fmtstr("")
633630

634-
def width_aware_slice(self, index: Union[int, slice]) -> "FmtStr":
631+
def width_aware_slice(self, index: int | slice) -> "FmtStr":
635632
"""Slice based on the number of columns it would take to display the substring."""
636633
if wcswidth(self.s, None) == -1:
637634
raise ValueError("bad values for width aware slicing")
@@ -687,7 +684,7 @@ def _width_aware_splitlines(self, columns: int) -> Iterator["FmtStr"]:
687684
if chunks_of_line:
688685
yield FmtStr(*chunks_of_line)
689686

690-
def _getitem_normalized(self, index: Union[int, slice]) -> "FmtStr":
687+
def _getitem_normalized(self, index: int | slice) -> "FmtStr":
691688
"""Builds the more compact fmtstrs by using fromstr( of the control sequences)"""
692689
index = normalize_slice(len(self), index)
693690
counter = 0
@@ -749,7 +746,7 @@ def width_aware_slice(s: str, start: int, end: int, replacement_char: str = " ")
749746
return "".join(new_chunk_chars)
750747

751748

752-
def linesplit(string: Union[str, FmtStr], columns: int) -> list[FmtStr]:
749+
def linesplit(string: str | FmtStr, columns: int) -> list[FmtStr]:
753750
"""Returns a list of lines, split on the last possible space of each line.
754751
755752
Split spaces will be removed. Whitespaces will be normalized to one space.
@@ -794,7 +791,7 @@ def linesplit(string: Union[str, FmtStr], columns: int) -> list[FmtStr]:
794791
return lines
795792

796793

797-
def normalize_slice(length: int, index: Union[int, slice]) -> slice:
794+
def normalize_slice(length: int, index: int | slice) -> slice:
798795
"Fill in the Nones in a slice."
799796
is_int = False
800797
if isinstance(index, int):
@@ -818,8 +815,8 @@ def normalize_slice(length: int, index: Union[int, slice]) -> slice:
818815

819816
def parse_args(
820817
args: tuple[str, ...],
821-
kwargs: MutableMapping[str, Union[int, bool, str]],
822-
) -> MutableMapping[str, Union[int, bool]]:
818+
kwargs: MutableMapping[str, int | bool | str],
819+
) -> MutableMapping[str, int | bool]:
823820
"""Returns a kwargs dictionary by turning args into kwargs"""
824821
if "style" in kwargs:
825822
args += (cast(str, kwargs["style"]),)
@@ -855,7 +852,7 @@ def parse_args(
855852
return cast(MutableMapping[str, Union[int, bool]], kwargs)
856853

857854

858-
def fmtstr(string: Union[str, FmtStr], *args: Any, **kwargs: Any) -> FmtStr:
855+
def fmtstr(string: str | FmtStr, *args: Any, **kwargs: Any) -> FmtStr:
859856
"""
860857
Convenience function for creating a FmtStr
861858

curtsies/formatstringarray.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,12 @@ def __getitem__(self, slicetuple: slice) -> list[FmtStr]:
7272
pass
7373

7474
@overload
75-
def __getitem__(
76-
self, slicetuple: tuple[Union[slice, int], Union[slice, int]]
77-
) -> list[FmtStr]:
75+
def __getitem__(self, slicetuple: tuple[slice | int, slice | int]) -> list[FmtStr]:
7876
pass
7977

8078
def __getitem__(
81-
self, slicetuple: Union[int, slice, tuple[Union[int, slice], Union[int, slice]]]
82-
) -> Union[FmtStr, list[FmtStr]]:
79+
self, slicetuple: int | slice | tuple[int | slice, int | slice]
80+
) -> FmtStr | list[FmtStr]:
8381
if isinstance(slicetuple, int):
8482
if slicetuple < 0:
8583
slicetuple = len(self.rows) - slicetuple
@@ -250,8 +248,8 @@ def blink(x: str) -> str:
250248

251249

252250
def fsarray(
253-
strings: Sequence[Union[FmtStr, str]],
254-
width: Optional[int] = None,
251+
strings: Sequence[FmtStr | str],
252+
width: int | None = None,
255253
*args: Any,
256254
**kwargs: Any,
257255
) -> FSArray:
@@ -283,7 +281,7 @@ def fsarray(
283281
return arr
284282

285283

286-
def simple_format(x: Union[FSArray, Sequence[FmtStr]]) -> str:
284+
def simple_format(x: FSArray | Sequence[FmtStr]) -> str:
287285
return "\n".join(str(l) for l in x)
288286

289287

0 commit comments

Comments
 (0)