tests versuch 2
This commit is contained in:
parent
fdf385fe06
commit
c88f7df83a
2363 changed files with 408191 additions and 0 deletions
177
venv/lib/python3.11/site-packages/pip/_vendor/rich/__init__.py
Normal file
177
venv/lib/python3.11/site-packages/pip/_vendor/rich/__init__.py
Normal file
|
@ -0,0 +1,177 @@
|
|||
"""Rich text and beautiful formatting in the terminal."""
|
||||
|
||||
import os
|
||||
from typing import IO, TYPE_CHECKING, Any, Callable, Optional, Union
|
||||
|
||||
from ._extension import load_ipython_extension # noqa: F401
|
||||
|
||||
__all__ = ["get_console", "reconfigure", "print", "inspect", "print_json"]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .console import Console
|
||||
|
||||
# Global console used by alternative print
|
||||
_console: Optional["Console"] = None
|
||||
|
||||
try:
|
||||
_IMPORT_CWD = os.path.abspath(os.getcwd())
|
||||
except FileNotFoundError:
|
||||
# Can happen if the cwd has been deleted
|
||||
_IMPORT_CWD = ""
|
||||
|
||||
|
||||
def get_console() -> "Console":
|
||||
"""Get a global :class:`~rich.console.Console` instance. This function is used when Rich requires a Console,
|
||||
and hasn't been explicitly given one.
|
||||
|
||||
Returns:
|
||||
Console: A console instance.
|
||||
"""
|
||||
global _console
|
||||
if _console is None:
|
||||
from .console import Console
|
||||
|
||||
_console = Console()
|
||||
|
||||
return _console
|
||||
|
||||
|
||||
def reconfigure(*args: Any, **kwargs: Any) -> None:
|
||||
"""Reconfigures the global console by replacing it with another.
|
||||
|
||||
Args:
|
||||
*args (Any): Positional arguments for the replacement :class:`~rich.console.Console`.
|
||||
**kwargs (Any): Keyword arguments for the replacement :class:`~rich.console.Console`.
|
||||
"""
|
||||
from pip._vendor.rich.console import Console
|
||||
|
||||
new_console = Console(*args, **kwargs)
|
||||
_console = get_console()
|
||||
_console.__dict__ = new_console.__dict__
|
||||
|
||||
|
||||
def print(
|
||||
*objects: Any,
|
||||
sep: str = " ",
|
||||
end: str = "\n",
|
||||
file: Optional[IO[str]] = None,
|
||||
flush: bool = False,
|
||||
) -> None:
|
||||
r"""Print object(s) supplied via positional arguments.
|
||||
This function has an identical signature to the built-in print.
|
||||
For more advanced features, see the :class:`~rich.console.Console` class.
|
||||
|
||||
Args:
|
||||
sep (str, optional): Separator between printed objects. Defaults to " ".
|
||||
end (str, optional): Character to write at end of output. Defaults to "\\n".
|
||||
file (IO[str], optional): File to write to, or None for stdout. Defaults to None.
|
||||
flush (bool, optional): Has no effect as Rich always flushes output. Defaults to False.
|
||||
|
||||
"""
|
||||
from .console import Console
|
||||
|
||||
write_console = get_console() if file is None else Console(file=file)
|
||||
return write_console.print(*objects, sep=sep, end=end)
|
||||
|
||||
|
||||
def print_json(
|
||||
json: Optional[str] = None,
|
||||
*,
|
||||
data: Any = None,
|
||||
indent: Union[None, int, str] = 2,
|
||||
highlight: bool = True,
|
||||
skip_keys: bool = False,
|
||||
ensure_ascii: bool = False,
|
||||
check_circular: bool = True,
|
||||
allow_nan: bool = True,
|
||||
default: Optional[Callable[[Any], Any]] = None,
|
||||
sort_keys: bool = False,
|
||||
) -> None:
|
||||
"""Pretty prints JSON. Output will be valid JSON.
|
||||
|
||||
Args:
|
||||
json (str): A string containing JSON.
|
||||
data (Any): If json is not supplied, then encode this data.
|
||||
indent (int, optional): Number of spaces to indent. Defaults to 2.
|
||||
highlight (bool, optional): Enable highlighting of output: Defaults to True.
|
||||
skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False.
|
||||
ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False.
|
||||
check_circular (bool, optional): Check for circular references. Defaults to True.
|
||||
allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True.
|
||||
default (Callable, optional): A callable that converts values that can not be encoded
|
||||
in to something that can be JSON encoded. Defaults to None.
|
||||
sort_keys (bool, optional): Sort dictionary keys. Defaults to False.
|
||||
"""
|
||||
|
||||
get_console().print_json(
|
||||
json,
|
||||
data=data,
|
||||
indent=indent,
|
||||
highlight=highlight,
|
||||
skip_keys=skip_keys,
|
||||
ensure_ascii=ensure_ascii,
|
||||
check_circular=check_circular,
|
||||
allow_nan=allow_nan,
|
||||
default=default,
|
||||
sort_keys=sort_keys,
|
||||
)
|
||||
|
||||
|
||||
def inspect(
|
||||
obj: Any,
|
||||
*,
|
||||
console: Optional["Console"] = None,
|
||||
title: Optional[str] = None,
|
||||
help: bool = False,
|
||||
methods: bool = False,
|
||||
docs: bool = True,
|
||||
private: bool = False,
|
||||
dunder: bool = False,
|
||||
sort: bool = True,
|
||||
all: bool = False,
|
||||
value: bool = True,
|
||||
) -> None:
|
||||
"""Inspect any Python object.
|
||||
|
||||
* inspect(<OBJECT>) to see summarized info.
|
||||
* inspect(<OBJECT>, methods=True) to see methods.
|
||||
* inspect(<OBJECT>, help=True) to see full (non-abbreviated) help.
|
||||
* inspect(<OBJECT>, private=True) to see private attributes (single underscore).
|
||||
* inspect(<OBJECT>, dunder=True) to see attributes beginning with double underscore.
|
||||
* inspect(<OBJECT>, all=True) to see all attributes.
|
||||
|
||||
Args:
|
||||
obj (Any): An object to inspect.
|
||||
title (str, optional): Title to display over inspect result, or None use type. Defaults to None.
|
||||
help (bool, optional): Show full help text rather than just first paragraph. Defaults to False.
|
||||
methods (bool, optional): Enable inspection of callables. Defaults to False.
|
||||
docs (bool, optional): Also render doc strings. Defaults to True.
|
||||
private (bool, optional): Show private attributes (beginning with underscore). Defaults to False.
|
||||
dunder (bool, optional): Show attributes starting with double underscore. Defaults to False.
|
||||
sort (bool, optional): Sort attributes alphabetically. Defaults to True.
|
||||
all (bool, optional): Show all attributes. Defaults to False.
|
||||
value (bool, optional): Pretty print value. Defaults to True.
|
||||
"""
|
||||
_console = console or get_console()
|
||||
from pip._vendor.rich._inspect import Inspect
|
||||
|
||||
# Special case for inspect(inspect)
|
||||
is_inspect = obj is inspect
|
||||
|
||||
_inspect = Inspect(
|
||||
obj,
|
||||
title=title,
|
||||
help=is_inspect or help,
|
||||
methods=is_inspect or methods,
|
||||
docs=is_inspect or docs,
|
||||
private=private,
|
||||
dunder=dunder,
|
||||
sort=sort,
|
||||
all=all,
|
||||
value=value,
|
||||
)
|
||||
_console.print(_inspect)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
print("Hello, **World**")
|
274
venv/lib/python3.11/site-packages/pip/_vendor/rich/__main__.py
Normal file
274
venv/lib/python3.11/site-packages/pip/_vendor/rich/__main__.py
Normal file
|
@ -0,0 +1,274 @@
|
|||
import colorsys
|
||||
import io
|
||||
from time import process_time
|
||||
|
||||
from pip._vendor.rich import box
|
||||
from pip._vendor.rich.color import Color
|
||||
from pip._vendor.rich.console import Console, ConsoleOptions, Group, RenderableType, RenderResult
|
||||
from pip._vendor.rich.markdown import Markdown
|
||||
from pip._vendor.rich.measure import Measurement
|
||||
from pip._vendor.rich.pretty import Pretty
|
||||
from pip._vendor.rich.segment import Segment
|
||||
from pip._vendor.rich.style import Style
|
||||
from pip._vendor.rich.syntax import Syntax
|
||||
from pip._vendor.rich.table import Table
|
||||
from pip._vendor.rich.text import Text
|
||||
|
||||
|
||||
class ColorBox:
|
||||
def __rich_console__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
for y in range(0, 5):
|
||||
for x in range(options.max_width):
|
||||
h = x / options.max_width
|
||||
l = 0.1 + ((y / 5) * 0.7)
|
||||
r1, g1, b1 = colorsys.hls_to_rgb(h, l, 1.0)
|
||||
r2, g2, b2 = colorsys.hls_to_rgb(h, l + 0.7 / 10, 1.0)
|
||||
bgcolor = Color.from_rgb(r1 * 255, g1 * 255, b1 * 255)
|
||||
color = Color.from_rgb(r2 * 255, g2 * 255, b2 * 255)
|
||||
yield Segment("▄", Style(color=color, bgcolor=bgcolor))
|
||||
yield Segment.line()
|
||||
|
||||
def __rich_measure__(
|
||||
self, console: "Console", options: ConsoleOptions
|
||||
) -> Measurement:
|
||||
return Measurement(1, options.max_width)
|
||||
|
||||
|
||||
def make_test_card() -> Table:
|
||||
"""Get a renderable that demonstrates a number of features."""
|
||||
table = Table.grid(padding=1, pad_edge=True)
|
||||
table.title = "Rich features"
|
||||
table.add_column("Feature", no_wrap=True, justify="center", style="bold red")
|
||||
table.add_column("Demonstration")
|
||||
|
||||
color_table = Table(
|
||||
box=None,
|
||||
expand=False,
|
||||
show_header=False,
|
||||
show_edge=False,
|
||||
pad_edge=False,
|
||||
)
|
||||
color_table.add_row(
|
||||
(
|
||||
"✓ [bold green]4-bit color[/]\n"
|
||||
"✓ [bold blue]8-bit color[/]\n"
|
||||
"✓ [bold magenta]Truecolor (16.7 million)[/]\n"
|
||||
"✓ [bold yellow]Dumb terminals[/]\n"
|
||||
"✓ [bold cyan]Automatic color conversion"
|
||||
),
|
||||
ColorBox(),
|
||||
)
|
||||
|
||||
table.add_row("Colors", color_table)
|
||||
|
||||
table.add_row(
|
||||
"Styles",
|
||||
"All ansi styles: [bold]bold[/], [dim]dim[/], [italic]italic[/italic], [underline]underline[/], [strike]strikethrough[/], [reverse]reverse[/], and even [blink]blink[/].",
|
||||
)
|
||||
|
||||
lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in metus sed sapien ultricies pretium a at justo. Maecenas luctus velit et auctor maximus."
|
||||
lorem_table = Table.grid(padding=1, collapse_padding=True)
|
||||
lorem_table.pad_edge = False
|
||||
lorem_table.add_row(
|
||||
Text(lorem, justify="left", style="green"),
|
||||
Text(lorem, justify="center", style="yellow"),
|
||||
Text(lorem, justify="right", style="blue"),
|
||||
Text(lorem, justify="full", style="red"),
|
||||
)
|
||||
table.add_row(
|
||||
"Text",
|
||||
Group(
|
||||
Text.from_markup(
|
||||
"""Word wrap text. Justify [green]left[/], [yellow]center[/], [blue]right[/] or [red]full[/].\n"""
|
||||
),
|
||||
lorem_table,
|
||||
),
|
||||
)
|
||||
|
||||
def comparison(renderable1: RenderableType, renderable2: RenderableType) -> Table:
|
||||
table = Table(show_header=False, pad_edge=False, box=None, expand=True)
|
||||
table.add_column("1", ratio=1)
|
||||
table.add_column("2", ratio=1)
|
||||
table.add_row(renderable1, renderable2)
|
||||
return table
|
||||
|
||||
table.add_row(
|
||||
"Asian\nlanguage\nsupport",
|
||||
":flag_for_china: 该库支持中文,日文和韩文文本!\n:flag_for_japan: ライブラリは中国語、日本語、韓国語のテキストをサポートしています\n:flag_for_south_korea: 이 라이브러리는 중국어, 일본어 및 한국어 텍스트를 지원합니다",
|
||||
)
|
||||
|
||||
markup_example = (
|
||||
"[bold magenta]Rich[/] supports a simple [i]bbcode[/i]-like [b]markup[/b] for [yellow]color[/], [underline]style[/], and emoji! "
|
||||
":+1: :apple: :ant: :bear: :baguette_bread: :bus: "
|
||||
)
|
||||
table.add_row("Markup", markup_example)
|
||||
|
||||
example_table = Table(
|
||||
show_edge=False,
|
||||
show_header=True,
|
||||
expand=False,
|
||||
row_styles=["none", "dim"],
|
||||
box=box.SIMPLE,
|
||||
)
|
||||
example_table.add_column("[green]Date", style="green", no_wrap=True)
|
||||
example_table.add_column("[blue]Title", style="blue")
|
||||
example_table.add_column(
|
||||
"[cyan]Production Budget",
|
||||
style="cyan",
|
||||
justify="right",
|
||||
no_wrap=True,
|
||||
)
|
||||
example_table.add_column(
|
||||
"[magenta]Box Office",
|
||||
style="magenta",
|
||||
justify="right",
|
||||
no_wrap=True,
|
||||
)
|
||||
example_table.add_row(
|
||||
"Dec 20, 2019",
|
||||
"Star Wars: The Rise of Skywalker",
|
||||
"$275,000,000",
|
||||
"$375,126,118",
|
||||
)
|
||||
example_table.add_row(
|
||||
"May 25, 2018",
|
||||
"[b]Solo[/]: A Star Wars Story",
|
||||
"$275,000,000",
|
||||
"$393,151,347",
|
||||
)
|
||||
example_table.add_row(
|
||||
"Dec 15, 2017",
|
||||
"Star Wars Ep. VIII: The Last Jedi",
|
||||
"$262,000,000",
|
||||
"[bold]$1,332,539,889[/bold]",
|
||||
)
|
||||
example_table.add_row(
|
||||
"May 19, 1999",
|
||||
"Star Wars Ep. [b]I[/b]: [i]The phantom Menace",
|
||||
"$115,000,000",
|
||||
"$1,027,044,677",
|
||||
)
|
||||
|
||||
table.add_row("Tables", example_table)
|
||||
|
||||
code = '''\
|
||||
def iter_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for last value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
previous_value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
for value in iter_values:
|
||||
yield False, previous_value
|
||||
previous_value = value
|
||||
yield True, previous_value'''
|
||||
|
||||
pretty_data = {
|
||||
"foo": [
|
||||
3.1427,
|
||||
(
|
||||
"Paul Atreides",
|
||||
"Vladimir Harkonnen",
|
||||
"Thufir Hawat",
|
||||
),
|
||||
],
|
||||
"atomic": (False, True, None),
|
||||
}
|
||||
table.add_row(
|
||||
"Syntax\nhighlighting\n&\npretty\nprinting",
|
||||
comparison(
|
||||
Syntax(code, "python3", line_numbers=True, indent_guides=True),
|
||||
Pretty(pretty_data, indent_guides=True),
|
||||
),
|
||||
)
|
||||
|
||||
markdown_example = """\
|
||||
# Markdown
|
||||
|
||||
Supports much of the *markdown* __syntax__!
|
||||
|
||||
- Headers
|
||||
- Basic formatting: **bold**, *italic*, `code`
|
||||
- Block quotes
|
||||
- Lists, and more...
|
||||
"""
|
||||
table.add_row(
|
||||
"Markdown", comparison("[cyan]" + markdown_example, Markdown(markdown_example))
|
||||
)
|
||||
|
||||
table.add_row(
|
||||
"+more!",
|
||||
"""Progress bars, columns, styled logging handler, tracebacks, etc...""",
|
||||
)
|
||||
return table
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
|
||||
console = Console(
|
||||
file=io.StringIO(),
|
||||
force_terminal=True,
|
||||
)
|
||||
test_card = make_test_card()
|
||||
|
||||
# Print once to warm cache
|
||||
start = process_time()
|
||||
console.print(test_card)
|
||||
pre_cache_taken = round((process_time() - start) * 1000.0, 1)
|
||||
|
||||
console.file = io.StringIO()
|
||||
|
||||
start = process_time()
|
||||
console.print(test_card)
|
||||
taken = round((process_time() - start) * 1000.0, 1)
|
||||
|
||||
c = Console(record=True)
|
||||
c.print(test_card)
|
||||
|
||||
print(f"rendered in {pre_cache_taken}ms (cold cache)")
|
||||
print(f"rendered in {taken}ms (warm cache)")
|
||||
|
||||
from pip._vendor.rich.panel import Panel
|
||||
|
||||
console = Console()
|
||||
|
||||
sponsor_message = Table.grid(padding=1)
|
||||
sponsor_message.add_column(style="green", justify="right")
|
||||
sponsor_message.add_column(no_wrap=True)
|
||||
|
||||
sponsor_message.add_row(
|
||||
"Textualize",
|
||||
"[u blue link=https://github.com/textualize]https://github.com/textualize",
|
||||
)
|
||||
sponsor_message.add_row(
|
||||
"Twitter",
|
||||
"[u blue link=https://twitter.com/willmcgugan]https://twitter.com/willmcgugan",
|
||||
)
|
||||
|
||||
intro_message = Text.from_markup(
|
||||
"""\
|
||||
We hope you enjoy using Rich!
|
||||
|
||||
Rich is maintained with [red]:heart:[/] by [link=https://www.textualize.io]Textualize.io[/]
|
||||
|
||||
- Will McGugan"""
|
||||
)
|
||||
|
||||
message = Table.grid(padding=2)
|
||||
message.add_column()
|
||||
message.add_column(no_wrap=True)
|
||||
message.add_row(intro_message, sponsor_message)
|
||||
|
||||
console.print(
|
||||
Panel.fit(
|
||||
message,
|
||||
box=box.ROUNDED,
|
||||
padding=(1, 2),
|
||||
title="[b red]Thanks for trying out Rich!",
|
||||
border_style="bright_blue",
|
||||
),
|
||||
justify="center",
|
||||
)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,451 @@
|
|||
# Auto generated by make_terminal_widths.py
|
||||
|
||||
CELL_WIDTHS = [
|
||||
(0, 0, 0),
|
||||
(1, 31, -1),
|
||||
(127, 159, -1),
|
||||
(768, 879, 0),
|
||||
(1155, 1161, 0),
|
||||
(1425, 1469, 0),
|
||||
(1471, 1471, 0),
|
||||
(1473, 1474, 0),
|
||||
(1476, 1477, 0),
|
||||
(1479, 1479, 0),
|
||||
(1552, 1562, 0),
|
||||
(1611, 1631, 0),
|
||||
(1648, 1648, 0),
|
||||
(1750, 1756, 0),
|
||||
(1759, 1764, 0),
|
||||
(1767, 1768, 0),
|
||||
(1770, 1773, 0),
|
||||
(1809, 1809, 0),
|
||||
(1840, 1866, 0),
|
||||
(1958, 1968, 0),
|
||||
(2027, 2035, 0),
|
||||
(2045, 2045, 0),
|
||||
(2070, 2073, 0),
|
||||
(2075, 2083, 0),
|
||||
(2085, 2087, 0),
|
||||
(2089, 2093, 0),
|
||||
(2137, 2139, 0),
|
||||
(2259, 2273, 0),
|
||||
(2275, 2306, 0),
|
||||
(2362, 2362, 0),
|
||||
(2364, 2364, 0),
|
||||
(2369, 2376, 0),
|
||||
(2381, 2381, 0),
|
||||
(2385, 2391, 0),
|
||||
(2402, 2403, 0),
|
||||
(2433, 2433, 0),
|
||||
(2492, 2492, 0),
|
||||
(2497, 2500, 0),
|
||||
(2509, 2509, 0),
|
||||
(2530, 2531, 0),
|
||||
(2558, 2558, 0),
|
||||
(2561, 2562, 0),
|
||||
(2620, 2620, 0),
|
||||
(2625, 2626, 0),
|
||||
(2631, 2632, 0),
|
||||
(2635, 2637, 0),
|
||||
(2641, 2641, 0),
|
||||
(2672, 2673, 0),
|
||||
(2677, 2677, 0),
|
||||
(2689, 2690, 0),
|
||||
(2748, 2748, 0),
|
||||
(2753, 2757, 0),
|
||||
(2759, 2760, 0),
|
||||
(2765, 2765, 0),
|
||||
(2786, 2787, 0),
|
||||
(2810, 2815, 0),
|
||||
(2817, 2817, 0),
|
||||
(2876, 2876, 0),
|
||||
(2879, 2879, 0),
|
||||
(2881, 2884, 0),
|
||||
(2893, 2893, 0),
|
||||
(2901, 2902, 0),
|
||||
(2914, 2915, 0),
|
||||
(2946, 2946, 0),
|
||||
(3008, 3008, 0),
|
||||
(3021, 3021, 0),
|
||||
(3072, 3072, 0),
|
||||
(3076, 3076, 0),
|
||||
(3134, 3136, 0),
|
||||
(3142, 3144, 0),
|
||||
(3146, 3149, 0),
|
||||
(3157, 3158, 0),
|
||||
(3170, 3171, 0),
|
||||
(3201, 3201, 0),
|
||||
(3260, 3260, 0),
|
||||
(3263, 3263, 0),
|
||||
(3270, 3270, 0),
|
||||
(3276, 3277, 0),
|
||||
(3298, 3299, 0),
|
||||
(3328, 3329, 0),
|
||||
(3387, 3388, 0),
|
||||
(3393, 3396, 0),
|
||||
(3405, 3405, 0),
|
||||
(3426, 3427, 0),
|
||||
(3457, 3457, 0),
|
||||
(3530, 3530, 0),
|
||||
(3538, 3540, 0),
|
||||
(3542, 3542, 0),
|
||||
(3633, 3633, 0),
|
||||
(3636, 3642, 0),
|
||||
(3655, 3662, 0),
|
||||
(3761, 3761, 0),
|
||||
(3764, 3772, 0),
|
||||
(3784, 3789, 0),
|
||||
(3864, 3865, 0),
|
||||
(3893, 3893, 0),
|
||||
(3895, 3895, 0),
|
||||
(3897, 3897, 0),
|
||||
(3953, 3966, 0),
|
||||
(3968, 3972, 0),
|
||||
(3974, 3975, 0),
|
||||
(3981, 3991, 0),
|
||||
(3993, 4028, 0),
|
||||
(4038, 4038, 0),
|
||||
(4141, 4144, 0),
|
||||
(4146, 4151, 0),
|
||||
(4153, 4154, 0),
|
||||
(4157, 4158, 0),
|
||||
(4184, 4185, 0),
|
||||
(4190, 4192, 0),
|
||||
(4209, 4212, 0),
|
||||
(4226, 4226, 0),
|
||||
(4229, 4230, 0),
|
||||
(4237, 4237, 0),
|
||||
(4253, 4253, 0),
|
||||
(4352, 4447, 2),
|
||||
(4957, 4959, 0),
|
||||
(5906, 5908, 0),
|
||||
(5938, 5940, 0),
|
||||
(5970, 5971, 0),
|
||||
(6002, 6003, 0),
|
||||
(6068, 6069, 0),
|
||||
(6071, 6077, 0),
|
||||
(6086, 6086, 0),
|
||||
(6089, 6099, 0),
|
||||
(6109, 6109, 0),
|
||||
(6155, 6157, 0),
|
||||
(6277, 6278, 0),
|
||||
(6313, 6313, 0),
|
||||
(6432, 6434, 0),
|
||||
(6439, 6440, 0),
|
||||
(6450, 6450, 0),
|
||||
(6457, 6459, 0),
|
||||
(6679, 6680, 0),
|
||||
(6683, 6683, 0),
|
||||
(6742, 6742, 0),
|
||||
(6744, 6750, 0),
|
||||
(6752, 6752, 0),
|
||||
(6754, 6754, 0),
|
||||
(6757, 6764, 0),
|
||||
(6771, 6780, 0),
|
||||
(6783, 6783, 0),
|
||||
(6832, 6848, 0),
|
||||
(6912, 6915, 0),
|
||||
(6964, 6964, 0),
|
||||
(6966, 6970, 0),
|
||||
(6972, 6972, 0),
|
||||
(6978, 6978, 0),
|
||||
(7019, 7027, 0),
|
||||
(7040, 7041, 0),
|
||||
(7074, 7077, 0),
|
||||
(7080, 7081, 0),
|
||||
(7083, 7085, 0),
|
||||
(7142, 7142, 0),
|
||||
(7144, 7145, 0),
|
||||
(7149, 7149, 0),
|
||||
(7151, 7153, 0),
|
||||
(7212, 7219, 0),
|
||||
(7222, 7223, 0),
|
||||
(7376, 7378, 0),
|
||||
(7380, 7392, 0),
|
||||
(7394, 7400, 0),
|
||||
(7405, 7405, 0),
|
||||
(7412, 7412, 0),
|
||||
(7416, 7417, 0),
|
||||
(7616, 7673, 0),
|
||||
(7675, 7679, 0),
|
||||
(8203, 8207, 0),
|
||||
(8232, 8238, 0),
|
||||
(8288, 8291, 0),
|
||||
(8400, 8432, 0),
|
||||
(8986, 8987, 2),
|
||||
(9001, 9002, 2),
|
||||
(9193, 9196, 2),
|
||||
(9200, 9200, 2),
|
||||
(9203, 9203, 2),
|
||||
(9725, 9726, 2),
|
||||
(9748, 9749, 2),
|
||||
(9800, 9811, 2),
|
||||
(9855, 9855, 2),
|
||||
(9875, 9875, 2),
|
||||
(9889, 9889, 2),
|
||||
(9898, 9899, 2),
|
||||
(9917, 9918, 2),
|
||||
(9924, 9925, 2),
|
||||
(9934, 9934, 2),
|
||||
(9940, 9940, 2),
|
||||
(9962, 9962, 2),
|
||||
(9970, 9971, 2),
|
||||
(9973, 9973, 2),
|
||||
(9978, 9978, 2),
|
||||
(9981, 9981, 2),
|
||||
(9989, 9989, 2),
|
||||
(9994, 9995, 2),
|
||||
(10024, 10024, 2),
|
||||
(10060, 10060, 2),
|
||||
(10062, 10062, 2),
|
||||
(10067, 10069, 2),
|
||||
(10071, 10071, 2),
|
||||
(10133, 10135, 2),
|
||||
(10160, 10160, 2),
|
||||
(10175, 10175, 2),
|
||||
(11035, 11036, 2),
|
||||
(11088, 11088, 2),
|
||||
(11093, 11093, 2),
|
||||
(11503, 11505, 0),
|
||||
(11647, 11647, 0),
|
||||
(11744, 11775, 0),
|
||||
(11904, 11929, 2),
|
||||
(11931, 12019, 2),
|
||||
(12032, 12245, 2),
|
||||
(12272, 12283, 2),
|
||||
(12288, 12329, 2),
|
||||
(12330, 12333, 0),
|
||||
(12334, 12350, 2),
|
||||
(12353, 12438, 2),
|
||||
(12441, 12442, 0),
|
||||
(12443, 12543, 2),
|
||||
(12549, 12591, 2),
|
||||
(12593, 12686, 2),
|
||||
(12688, 12771, 2),
|
||||
(12784, 12830, 2),
|
||||
(12832, 12871, 2),
|
||||
(12880, 19903, 2),
|
||||
(19968, 42124, 2),
|
||||
(42128, 42182, 2),
|
||||
(42607, 42610, 0),
|
||||
(42612, 42621, 0),
|
||||
(42654, 42655, 0),
|
||||
(42736, 42737, 0),
|
||||
(43010, 43010, 0),
|
||||
(43014, 43014, 0),
|
||||
(43019, 43019, 0),
|
||||
(43045, 43046, 0),
|
||||
(43052, 43052, 0),
|
||||
(43204, 43205, 0),
|
||||
(43232, 43249, 0),
|
||||
(43263, 43263, 0),
|
||||
(43302, 43309, 0),
|
||||
(43335, 43345, 0),
|
||||
(43360, 43388, 2),
|
||||
(43392, 43394, 0),
|
||||
(43443, 43443, 0),
|
||||
(43446, 43449, 0),
|
||||
(43452, 43453, 0),
|
||||
(43493, 43493, 0),
|
||||
(43561, 43566, 0),
|
||||
(43569, 43570, 0),
|
||||
(43573, 43574, 0),
|
||||
(43587, 43587, 0),
|
||||
(43596, 43596, 0),
|
||||
(43644, 43644, 0),
|
||||
(43696, 43696, 0),
|
||||
(43698, 43700, 0),
|
||||
(43703, 43704, 0),
|
||||
(43710, 43711, 0),
|
||||
(43713, 43713, 0),
|
||||
(43756, 43757, 0),
|
||||
(43766, 43766, 0),
|
||||
(44005, 44005, 0),
|
||||
(44008, 44008, 0),
|
||||
(44013, 44013, 0),
|
||||
(44032, 55203, 2),
|
||||
(63744, 64255, 2),
|
||||
(64286, 64286, 0),
|
||||
(65024, 65039, 0),
|
||||
(65040, 65049, 2),
|
||||
(65056, 65071, 0),
|
||||
(65072, 65106, 2),
|
||||
(65108, 65126, 2),
|
||||
(65128, 65131, 2),
|
||||
(65281, 65376, 2),
|
||||
(65504, 65510, 2),
|
||||
(66045, 66045, 0),
|
||||
(66272, 66272, 0),
|
||||
(66422, 66426, 0),
|
||||
(68097, 68099, 0),
|
||||
(68101, 68102, 0),
|
||||
(68108, 68111, 0),
|
||||
(68152, 68154, 0),
|
||||
(68159, 68159, 0),
|
||||
(68325, 68326, 0),
|
||||
(68900, 68903, 0),
|
||||
(69291, 69292, 0),
|
||||
(69446, 69456, 0),
|
||||
(69633, 69633, 0),
|
||||
(69688, 69702, 0),
|
||||
(69759, 69761, 0),
|
||||
(69811, 69814, 0),
|
||||
(69817, 69818, 0),
|
||||
(69888, 69890, 0),
|
||||
(69927, 69931, 0),
|
||||
(69933, 69940, 0),
|
||||
(70003, 70003, 0),
|
||||
(70016, 70017, 0),
|
||||
(70070, 70078, 0),
|
||||
(70089, 70092, 0),
|
||||
(70095, 70095, 0),
|
||||
(70191, 70193, 0),
|
||||
(70196, 70196, 0),
|
||||
(70198, 70199, 0),
|
||||
(70206, 70206, 0),
|
||||
(70367, 70367, 0),
|
||||
(70371, 70378, 0),
|
||||
(70400, 70401, 0),
|
||||
(70459, 70460, 0),
|
||||
(70464, 70464, 0),
|
||||
(70502, 70508, 0),
|
||||
(70512, 70516, 0),
|
||||
(70712, 70719, 0),
|
||||
(70722, 70724, 0),
|
||||
(70726, 70726, 0),
|
||||
(70750, 70750, 0),
|
||||
(70835, 70840, 0),
|
||||
(70842, 70842, 0),
|
||||
(70847, 70848, 0),
|
||||
(70850, 70851, 0),
|
||||
(71090, 71093, 0),
|
||||
(71100, 71101, 0),
|
||||
(71103, 71104, 0),
|
||||
(71132, 71133, 0),
|
||||
(71219, 71226, 0),
|
||||
(71229, 71229, 0),
|
||||
(71231, 71232, 0),
|
||||
(71339, 71339, 0),
|
||||
(71341, 71341, 0),
|
||||
(71344, 71349, 0),
|
||||
(71351, 71351, 0),
|
||||
(71453, 71455, 0),
|
||||
(71458, 71461, 0),
|
||||
(71463, 71467, 0),
|
||||
(71727, 71735, 0),
|
||||
(71737, 71738, 0),
|
||||
(71995, 71996, 0),
|
||||
(71998, 71998, 0),
|
||||
(72003, 72003, 0),
|
||||
(72148, 72151, 0),
|
||||
(72154, 72155, 0),
|
||||
(72160, 72160, 0),
|
||||
(72193, 72202, 0),
|
||||
(72243, 72248, 0),
|
||||
(72251, 72254, 0),
|
||||
(72263, 72263, 0),
|
||||
(72273, 72278, 0),
|
||||
(72281, 72283, 0),
|
||||
(72330, 72342, 0),
|
||||
(72344, 72345, 0),
|
||||
(72752, 72758, 0),
|
||||
(72760, 72765, 0),
|
||||
(72767, 72767, 0),
|
||||
(72850, 72871, 0),
|
||||
(72874, 72880, 0),
|
||||
(72882, 72883, 0),
|
||||
(72885, 72886, 0),
|
||||
(73009, 73014, 0),
|
||||
(73018, 73018, 0),
|
||||
(73020, 73021, 0),
|
||||
(73023, 73029, 0),
|
||||
(73031, 73031, 0),
|
||||
(73104, 73105, 0),
|
||||
(73109, 73109, 0),
|
||||
(73111, 73111, 0),
|
||||
(73459, 73460, 0),
|
||||
(92912, 92916, 0),
|
||||
(92976, 92982, 0),
|
||||
(94031, 94031, 0),
|
||||
(94095, 94098, 0),
|
||||
(94176, 94179, 2),
|
||||
(94180, 94180, 0),
|
||||
(94192, 94193, 2),
|
||||
(94208, 100343, 2),
|
||||
(100352, 101589, 2),
|
||||
(101632, 101640, 2),
|
||||
(110592, 110878, 2),
|
||||
(110928, 110930, 2),
|
||||
(110948, 110951, 2),
|
||||
(110960, 111355, 2),
|
||||
(113821, 113822, 0),
|
||||
(119143, 119145, 0),
|
||||
(119163, 119170, 0),
|
||||
(119173, 119179, 0),
|
||||
(119210, 119213, 0),
|
||||
(119362, 119364, 0),
|
||||
(121344, 121398, 0),
|
||||
(121403, 121452, 0),
|
||||
(121461, 121461, 0),
|
||||
(121476, 121476, 0),
|
||||
(121499, 121503, 0),
|
||||
(121505, 121519, 0),
|
||||
(122880, 122886, 0),
|
||||
(122888, 122904, 0),
|
||||
(122907, 122913, 0),
|
||||
(122915, 122916, 0),
|
||||
(122918, 122922, 0),
|
||||
(123184, 123190, 0),
|
||||
(123628, 123631, 0),
|
||||
(125136, 125142, 0),
|
||||
(125252, 125258, 0),
|
||||
(126980, 126980, 2),
|
||||
(127183, 127183, 2),
|
||||
(127374, 127374, 2),
|
||||
(127377, 127386, 2),
|
||||
(127488, 127490, 2),
|
||||
(127504, 127547, 2),
|
||||
(127552, 127560, 2),
|
||||
(127568, 127569, 2),
|
||||
(127584, 127589, 2),
|
||||
(127744, 127776, 2),
|
||||
(127789, 127797, 2),
|
||||
(127799, 127868, 2),
|
||||
(127870, 127891, 2),
|
||||
(127904, 127946, 2),
|
||||
(127951, 127955, 2),
|
||||
(127968, 127984, 2),
|
||||
(127988, 127988, 2),
|
||||
(127992, 128062, 2),
|
||||
(128064, 128064, 2),
|
||||
(128066, 128252, 2),
|
||||
(128255, 128317, 2),
|
||||
(128331, 128334, 2),
|
||||
(128336, 128359, 2),
|
||||
(128378, 128378, 2),
|
||||
(128405, 128406, 2),
|
||||
(128420, 128420, 2),
|
||||
(128507, 128591, 2),
|
||||
(128640, 128709, 2),
|
||||
(128716, 128716, 2),
|
||||
(128720, 128722, 2),
|
||||
(128725, 128727, 2),
|
||||
(128747, 128748, 2),
|
||||
(128756, 128764, 2),
|
||||
(128992, 129003, 2),
|
||||
(129292, 129338, 2),
|
||||
(129340, 129349, 2),
|
||||
(129351, 129400, 2),
|
||||
(129402, 129483, 2),
|
||||
(129485, 129535, 2),
|
||||
(129648, 129652, 2),
|
||||
(129656, 129658, 2),
|
||||
(129664, 129670, 2),
|
||||
(129680, 129704, 2),
|
||||
(129712, 129718, 2),
|
||||
(129728, 129730, 2),
|
||||
(129744, 129750, 2),
|
||||
(131072, 196605, 2),
|
||||
(196608, 262141, 2),
|
||||
(917760, 917999, 0),
|
||||
]
|
3610
venv/lib/python3.11/site-packages/pip/_vendor/rich/_emoji_codes.py
Normal file
3610
venv/lib/python3.11/site-packages/pip/_vendor/rich/_emoji_codes.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,32 @@
|
|||
from typing import Callable, Match, Optional
|
||||
import re
|
||||
|
||||
from ._emoji_codes import EMOJI
|
||||
|
||||
|
||||
_ReStringMatch = Match[str] # regex match object
|
||||
_ReSubCallable = Callable[[_ReStringMatch], str] # Callable invoked by re.sub
|
||||
_EmojiSubMethod = Callable[[_ReSubCallable, str], str] # Sub method of a compiled re
|
||||
|
||||
|
||||
def _emoji_replace(
|
||||
text: str,
|
||||
default_variant: Optional[str] = None,
|
||||
_emoji_sub: _EmojiSubMethod = re.compile(r"(:(\S*?)(?:(?:\-)(emoji|text))?:)").sub,
|
||||
) -> str:
|
||||
"""Replace emoji code in text."""
|
||||
get_emoji = EMOJI.__getitem__
|
||||
variants = {"text": "\uFE0E", "emoji": "\uFE0F"}
|
||||
get_variant = variants.get
|
||||
default_variant_code = variants.get(default_variant, "") if default_variant else ""
|
||||
|
||||
def do_replace(match: Match[str]) -> str:
|
||||
emoji_code, emoji_name, variant = match.groups()
|
||||
try:
|
||||
return get_emoji(emoji_name.lower()) + get_variant(
|
||||
variant, default_variant_code
|
||||
)
|
||||
except KeyError:
|
||||
return emoji_code
|
||||
|
||||
return _emoji_sub(do_replace, text)
|
|
@ -0,0 +1,76 @@
|
|||
CONSOLE_HTML_FORMAT = """\
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
{stylesheet}
|
||||
body {{
|
||||
color: {foreground};
|
||||
background-color: {background};
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<html>
|
||||
<body>
|
||||
<pre style="font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><code>{code}</code></pre>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
CONSOLE_SVG_FORMAT = """\
|
||||
<svg class="rich-terminal" viewBox="0 0 {width} {height}" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Generated with Rich https://www.textualize.io -->
|
||||
<style>
|
||||
|
||||
@font-face {{
|
||||
font-family: "Fira Code";
|
||||
src: local("FiraCode-Regular"),
|
||||
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
|
||||
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}}
|
||||
@font-face {{
|
||||
font-family: "Fira Code";
|
||||
src: local("FiraCode-Bold"),
|
||||
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
|
||||
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
|
||||
font-style: bold;
|
||||
font-weight: 700;
|
||||
}}
|
||||
|
||||
.{unique_id}-matrix {{
|
||||
font-family: Fira Code, monospace;
|
||||
font-size: {char_height}px;
|
||||
line-height: {line_height}px;
|
||||
font-variant-east-asian: full-width;
|
||||
}}
|
||||
|
||||
.{unique_id}-title {{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
font-family: arial;
|
||||
}}
|
||||
|
||||
{styles}
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<clipPath id="{unique_id}-clip-terminal">
|
||||
<rect x="0" y="0" width="{terminal_width}" height="{terminal_height}" />
|
||||
</clipPath>
|
||||
{lines}
|
||||
</defs>
|
||||
|
||||
{chrome}
|
||||
<g transform="translate({terminal_x}, {terminal_y})" clip-path="url(#{unique_id}-clip-terminal)">
|
||||
{backgrounds}
|
||||
<g class="{unique_id}-matrix">
|
||||
{matrix}
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
"""
|
||||
|
||||
_SVG_FONT_FAMILY = "Rich Fira Code"
|
||||
_SVG_CLASSES_PREFIX = "rich-svg"
|
|
@ -0,0 +1,10 @@
|
|||
from typing import Any
|
||||
|
||||
|
||||
def load_ipython_extension(ip: Any) -> None: # pragma: no cover
|
||||
# prevent circular import
|
||||
from pip._vendor.rich.pretty import install
|
||||
from pip._vendor.rich.traceback import install as tr_install
|
||||
|
||||
install()
|
||||
tr_install()
|
|
@ -0,0 +1,24 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import IO, Callable
|
||||
|
||||
|
||||
def get_fileno(file_like: IO[str]) -> int | None:
|
||||
"""Get fileno() from a file, accounting for poorly implemented file-like objects.
|
||||
|
||||
Args:
|
||||
file_like (IO): A file-like object.
|
||||
|
||||
Returns:
|
||||
int | None: The result of fileno if available, or None if operation failed.
|
||||
"""
|
||||
fileno: Callable[[], int] | None = getattr(file_like, "fileno", None)
|
||||
if fileno is not None:
|
||||
try:
|
||||
return fileno()
|
||||
except Exception:
|
||||
# `fileno` is documented as potentially raising a OSError
|
||||
# Alas, from the issues, there are so many poorly implemented file-like objects,
|
||||
# that `fileno()` can raise just about anything.
|
||||
return None
|
||||
return None
|
270
venv/lib/python3.11/site-packages/pip/_vendor/rich/_inspect.py
Normal file
270
venv/lib/python3.11/site-packages/pip/_vendor/rich/_inspect.py
Normal file
|
@ -0,0 +1,270 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
import inspect
|
||||
from inspect import cleandoc, getdoc, getfile, isclass, ismodule, signature
|
||||
from typing import Any, Collection, Iterable, Optional, Tuple, Type, Union
|
||||
|
||||
from .console import Group, RenderableType
|
||||
from .control import escape_control_codes
|
||||
from .highlighter import ReprHighlighter
|
||||
from .jupyter import JupyterMixin
|
||||
from .panel import Panel
|
||||
from .pretty import Pretty
|
||||
from .table import Table
|
||||
from .text import Text, TextType
|
||||
|
||||
|
||||
def _first_paragraph(doc: str) -> str:
|
||||
"""Get the first paragraph from a docstring."""
|
||||
paragraph, _, _ = doc.partition("\n\n")
|
||||
return paragraph
|
||||
|
||||
|
||||
class Inspect(JupyterMixin):
|
||||
"""A renderable to inspect any Python Object.
|
||||
|
||||
Args:
|
||||
obj (Any): An object to inspect.
|
||||
title (str, optional): Title to display over inspect result, or None use type. Defaults to None.
|
||||
help (bool, optional): Show full help text rather than just first paragraph. Defaults to False.
|
||||
methods (bool, optional): Enable inspection of callables. Defaults to False.
|
||||
docs (bool, optional): Also render doc strings. Defaults to True.
|
||||
private (bool, optional): Show private attributes (beginning with underscore). Defaults to False.
|
||||
dunder (bool, optional): Show attributes starting with double underscore. Defaults to False.
|
||||
sort (bool, optional): Sort attributes alphabetically. Defaults to True.
|
||||
all (bool, optional): Show all attributes. Defaults to False.
|
||||
value (bool, optional): Pretty print value of object. Defaults to True.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
obj: Any,
|
||||
*,
|
||||
title: Optional[TextType] = None,
|
||||
help: bool = False,
|
||||
methods: bool = False,
|
||||
docs: bool = True,
|
||||
private: bool = False,
|
||||
dunder: bool = False,
|
||||
sort: bool = True,
|
||||
all: bool = True,
|
||||
value: bool = True,
|
||||
) -> None:
|
||||
self.highlighter = ReprHighlighter()
|
||||
self.obj = obj
|
||||
self.title = title or self._make_title(obj)
|
||||
if all:
|
||||
methods = private = dunder = True
|
||||
self.help = help
|
||||
self.methods = methods
|
||||
self.docs = docs or help
|
||||
self.private = private or dunder
|
||||
self.dunder = dunder
|
||||
self.sort = sort
|
||||
self.value = value
|
||||
|
||||
def _make_title(self, obj: Any) -> Text:
|
||||
"""Make a default title."""
|
||||
title_str = (
|
||||
str(obj)
|
||||
if (isclass(obj) or callable(obj) or ismodule(obj))
|
||||
else str(type(obj))
|
||||
)
|
||||
title_text = self.highlighter(title_str)
|
||||
return title_text
|
||||
|
||||
def __rich__(self) -> Panel:
|
||||
return Panel.fit(
|
||||
Group(*self._render()),
|
||||
title=self.title,
|
||||
border_style="scope.border",
|
||||
padding=(0, 1),
|
||||
)
|
||||
|
||||
def _get_signature(self, name: str, obj: Any) -> Optional[Text]:
|
||||
"""Get a signature for a callable."""
|
||||
try:
|
||||
_signature = str(signature(obj)) + ":"
|
||||
except ValueError:
|
||||
_signature = "(...)"
|
||||
except TypeError:
|
||||
return None
|
||||
|
||||
source_filename: Optional[str] = None
|
||||
try:
|
||||
source_filename = getfile(obj)
|
||||
except (OSError, TypeError):
|
||||
# OSError is raised if obj has no source file, e.g. when defined in REPL.
|
||||
pass
|
||||
|
||||
callable_name = Text(name, style="inspect.callable")
|
||||
if source_filename:
|
||||
callable_name.stylize(f"link file://{source_filename}")
|
||||
signature_text = self.highlighter(_signature)
|
||||
|
||||
qualname = name or getattr(obj, "__qualname__", name)
|
||||
|
||||
# If obj is a module, there may be classes (which are callable) to display
|
||||
if inspect.isclass(obj):
|
||||
prefix = "class"
|
||||
elif inspect.iscoroutinefunction(obj):
|
||||
prefix = "async def"
|
||||
else:
|
||||
prefix = "def"
|
||||
|
||||
qual_signature = Text.assemble(
|
||||
(f"{prefix} ", f"inspect.{prefix.replace(' ', '_')}"),
|
||||
(qualname, "inspect.callable"),
|
||||
signature_text,
|
||||
)
|
||||
|
||||
return qual_signature
|
||||
|
||||
def _render(self) -> Iterable[RenderableType]:
|
||||
"""Render object."""
|
||||
|
||||
def sort_items(item: Tuple[str, Any]) -> Tuple[bool, str]:
|
||||
key, (_error, value) = item
|
||||
return (callable(value), key.strip("_").lower())
|
||||
|
||||
def safe_getattr(attr_name: str) -> Tuple[Any, Any]:
|
||||
"""Get attribute or any exception."""
|
||||
try:
|
||||
return (None, getattr(obj, attr_name))
|
||||
except Exception as error:
|
||||
return (error, None)
|
||||
|
||||
obj = self.obj
|
||||
keys = dir(obj)
|
||||
total_items = len(keys)
|
||||
if not self.dunder:
|
||||
keys = [key for key in keys if not key.startswith("__")]
|
||||
if not self.private:
|
||||
keys = [key for key in keys if not key.startswith("_")]
|
||||
not_shown_count = total_items - len(keys)
|
||||
items = [(key, safe_getattr(key)) for key in keys]
|
||||
if self.sort:
|
||||
items.sort(key=sort_items)
|
||||
|
||||
items_table = Table.grid(padding=(0, 1), expand=False)
|
||||
items_table.add_column(justify="right")
|
||||
add_row = items_table.add_row
|
||||
highlighter = self.highlighter
|
||||
|
||||
if callable(obj):
|
||||
signature = self._get_signature("", obj)
|
||||
if signature is not None:
|
||||
yield signature
|
||||
yield ""
|
||||
|
||||
if self.docs:
|
||||
_doc = self._get_formatted_doc(obj)
|
||||
if _doc is not None:
|
||||
doc_text = Text(_doc, style="inspect.help")
|
||||
doc_text = highlighter(doc_text)
|
||||
yield doc_text
|
||||
yield ""
|
||||
|
||||
if self.value and not (isclass(obj) or callable(obj) or ismodule(obj)):
|
||||
yield Panel(
|
||||
Pretty(obj, indent_guides=True, max_length=10, max_string=60),
|
||||
border_style="inspect.value.border",
|
||||
)
|
||||
yield ""
|
||||
|
||||
for key, (error, value) in items:
|
||||
key_text = Text.assemble(
|
||||
(
|
||||
key,
|
||||
"inspect.attr.dunder" if key.startswith("__") else "inspect.attr",
|
||||
),
|
||||
(" =", "inspect.equals"),
|
||||
)
|
||||
if error is not None:
|
||||
warning = key_text.copy()
|
||||
warning.stylize("inspect.error")
|
||||
add_row(warning, highlighter(repr(error)))
|
||||
continue
|
||||
|
||||
if callable(value):
|
||||
if not self.methods:
|
||||
continue
|
||||
|
||||
_signature_text = self._get_signature(key, value)
|
||||
if _signature_text is None:
|
||||
add_row(key_text, Pretty(value, highlighter=highlighter))
|
||||
else:
|
||||
if self.docs:
|
||||
docs = self._get_formatted_doc(value)
|
||||
if docs is not None:
|
||||
_signature_text.append("\n" if "\n" in docs else " ")
|
||||
doc = highlighter(docs)
|
||||
doc.stylize("inspect.doc")
|
||||
_signature_text.append(doc)
|
||||
|
||||
add_row(key_text, _signature_text)
|
||||
else:
|
||||
add_row(key_text, Pretty(value, highlighter=highlighter))
|
||||
if items_table.row_count:
|
||||
yield items_table
|
||||
elif not_shown_count:
|
||||
yield Text.from_markup(
|
||||
f"[b cyan]{not_shown_count}[/][i] attribute(s) not shown.[/i] "
|
||||
f"Run [b][magenta]inspect[/]([not b]inspect[/])[/b] for options."
|
||||
)
|
||||
|
||||
def _get_formatted_doc(self, object_: Any) -> Optional[str]:
|
||||
"""
|
||||
Extract the docstring of an object, process it and returns it.
|
||||
The processing consists in cleaning up the doctring's indentation,
|
||||
taking only its 1st paragraph if `self.help` is not True,
|
||||
and escape its control codes.
|
||||
|
||||
Args:
|
||||
object_ (Any): the object to get the docstring from.
|
||||
|
||||
Returns:
|
||||
Optional[str]: the processed docstring, or None if no docstring was found.
|
||||
"""
|
||||
docs = getdoc(object_)
|
||||
if docs is None:
|
||||
return None
|
||||
docs = cleandoc(docs).strip()
|
||||
if not self.help:
|
||||
docs = _first_paragraph(docs)
|
||||
return escape_control_codes(docs)
|
||||
|
||||
|
||||
def get_object_types_mro(obj: Union[object, Type[Any]]) -> Tuple[type, ...]:
|
||||
"""Returns the MRO of an object's class, or of the object itself if it's a class."""
|
||||
if not hasattr(obj, "__mro__"):
|
||||
# N.B. we cannot use `if type(obj) is type` here because it doesn't work with
|
||||
# some types of classes, such as the ones that use abc.ABCMeta.
|
||||
obj = type(obj)
|
||||
return getattr(obj, "__mro__", ())
|
||||
|
||||
|
||||
def get_object_types_mro_as_strings(obj: object) -> Collection[str]:
|
||||
"""
|
||||
Returns the MRO of an object's class as full qualified names, or of the object itself if it's a class.
|
||||
|
||||
Examples:
|
||||
`object_types_mro_as_strings(JSONDecoder)` will return `['json.decoder.JSONDecoder', 'builtins.object']`
|
||||
"""
|
||||
return [
|
||||
f'{getattr(type_, "__module__", "")}.{getattr(type_, "__qualname__", "")}'
|
||||
for type_ in get_object_types_mro(obj)
|
||||
]
|
||||
|
||||
|
||||
def is_object_one_of_types(
|
||||
obj: object, fully_qualified_types_names: Collection[str]
|
||||
) -> bool:
|
||||
"""
|
||||
Returns `True` if the given object's class (or the object itself, if it's a class) has one of the
|
||||
fully qualified names in its MRO.
|
||||
"""
|
||||
for type_name in get_object_types_mro_as_strings(obj):
|
||||
if type_name in fully_qualified_types_names:
|
||||
return True
|
||||
return False
|
|
@ -0,0 +1,94 @@
|
|||
from datetime import datetime
|
||||
from typing import Iterable, List, Optional, TYPE_CHECKING, Union, Callable
|
||||
|
||||
|
||||
from .text import Text, TextType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .console import Console, ConsoleRenderable, RenderableType
|
||||
from .table import Table
|
||||
|
||||
FormatTimeCallable = Callable[[datetime], Text]
|
||||
|
||||
|
||||
class LogRender:
|
||||
def __init__(
|
||||
self,
|
||||
show_time: bool = True,
|
||||
show_level: bool = False,
|
||||
show_path: bool = True,
|
||||
time_format: Union[str, FormatTimeCallable] = "[%x %X]",
|
||||
omit_repeated_times: bool = True,
|
||||
level_width: Optional[int] = 8,
|
||||
) -> None:
|
||||
self.show_time = show_time
|
||||
self.show_level = show_level
|
||||
self.show_path = show_path
|
||||
self.time_format = time_format
|
||||
self.omit_repeated_times = omit_repeated_times
|
||||
self.level_width = level_width
|
||||
self._last_time: Optional[Text] = None
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
console: "Console",
|
||||
renderables: Iterable["ConsoleRenderable"],
|
||||
log_time: Optional[datetime] = None,
|
||||
time_format: Optional[Union[str, FormatTimeCallable]] = None,
|
||||
level: TextType = "",
|
||||
path: Optional[str] = None,
|
||||
line_no: Optional[int] = None,
|
||||
link_path: Optional[str] = None,
|
||||
) -> "Table":
|
||||
from .containers import Renderables
|
||||
from .table import Table
|
||||
|
||||
output = Table.grid(padding=(0, 1))
|
||||
output.expand = True
|
||||
if self.show_time:
|
||||
output.add_column(style="log.time")
|
||||
if self.show_level:
|
||||
output.add_column(style="log.level", width=self.level_width)
|
||||
output.add_column(ratio=1, style="log.message", overflow="fold")
|
||||
if self.show_path and path:
|
||||
output.add_column(style="log.path")
|
||||
row: List["RenderableType"] = []
|
||||
if self.show_time:
|
||||
log_time = log_time or console.get_datetime()
|
||||
time_format = time_format or self.time_format
|
||||
if callable(time_format):
|
||||
log_time_display = time_format(log_time)
|
||||
else:
|
||||
log_time_display = Text(log_time.strftime(time_format))
|
||||
if log_time_display == self._last_time and self.omit_repeated_times:
|
||||
row.append(Text(" " * len(log_time_display)))
|
||||
else:
|
||||
row.append(log_time_display)
|
||||
self._last_time = log_time_display
|
||||
if self.show_level:
|
||||
row.append(level)
|
||||
|
||||
row.append(Renderables(renderables))
|
||||
if self.show_path and path:
|
||||
path_text = Text()
|
||||
path_text.append(
|
||||
path, style=f"link file://{link_path}" if link_path else ""
|
||||
)
|
||||
if line_no:
|
||||
path_text.append(":")
|
||||
path_text.append(
|
||||
f"{line_no}",
|
||||
style=f"link file://{link_path}#{line_no}" if link_path else "",
|
||||
)
|
||||
row.append(path_text)
|
||||
|
||||
output.add_row(*row)
|
||||
return output
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from pip._vendor.rich.console import Console
|
||||
|
||||
c = Console()
|
||||
c.print("[on blue]Hello", justify="right")
|
||||
c.log("[on blue]hello", justify="right")
|
43
venv/lib/python3.11/site-packages/pip/_vendor/rich/_loop.py
Normal file
43
venv/lib/python3.11/site-packages/pip/_vendor/rich/_loop.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
from typing import Iterable, Tuple, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def loop_first(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for first value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
yield True, value
|
||||
for value in iter_values:
|
||||
yield False, value
|
||||
|
||||
|
||||
def loop_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for last value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
previous_value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
for value in iter_values:
|
||||
yield False, previous_value
|
||||
previous_value = value
|
||||
yield True, previous_value
|
||||
|
||||
|
||||
def loop_first_last(values: Iterable[T]) -> Iterable[Tuple[bool, bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for first and last value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
previous_value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
first = True
|
||||
for value in iter_values:
|
||||
yield first, False, previous_value
|
||||
first = False
|
||||
previous_value = value
|
||||
yield first, True, previous_value
|
|
@ -0,0 +1,69 @@
|
|||
from types import TracebackType
|
||||
from typing import IO, Iterable, Iterator, List, Optional, Type
|
||||
|
||||
|
||||
class NullFile(IO[str]):
|
||||
def close(self) -> None:
|
||||
pass
|
||||
|
||||
def isatty(self) -> bool:
|
||||
return False
|
||||
|
||||
def read(self, __n: int = 1) -> str:
|
||||
return ""
|
||||
|
||||
def readable(self) -> bool:
|
||||
return False
|
||||
|
||||
def readline(self, __limit: int = 1) -> str:
|
||||
return ""
|
||||
|
||||
def readlines(self, __hint: int = 1) -> List[str]:
|
||||
return []
|
||||
|
||||
def seek(self, __offset: int, __whence: int = 1) -> int:
|
||||
return 0
|
||||
|
||||
def seekable(self) -> bool:
|
||||
return False
|
||||
|
||||
def tell(self) -> int:
|
||||
return 0
|
||||
|
||||
def truncate(self, __size: Optional[int] = 1) -> int:
|
||||
return 0
|
||||
|
||||
def writable(self) -> bool:
|
||||
return False
|
||||
|
||||
def writelines(self, __lines: Iterable[str]) -> None:
|
||||
pass
|
||||
|
||||
def __next__(self) -> str:
|
||||
return ""
|
||||
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
return iter([""])
|
||||
|
||||
def __enter__(self) -> IO[str]:
|
||||
pass
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
__t: Optional[Type[BaseException]],
|
||||
__value: Optional[BaseException],
|
||||
__traceback: Optional[TracebackType],
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
def write(self, text: str) -> int:
|
||||
return 0
|
||||
|
||||
def flush(self) -> None:
|
||||
pass
|
||||
|
||||
def fileno(self) -> int:
|
||||
return -1
|
||||
|
||||
|
||||
NULL_FILE = NullFile()
|
309
venv/lib/python3.11/site-packages/pip/_vendor/rich/_palettes.py
Normal file
309
venv/lib/python3.11/site-packages/pip/_vendor/rich/_palettes.py
Normal file
|
@ -0,0 +1,309 @@
|
|||
from .palette import Palette
|
||||
|
||||
|
||||
# Taken from https://en.wikipedia.org/wiki/ANSI_escape_code (Windows 10 column)
|
||||
WINDOWS_PALETTE = Palette(
|
||||
[
|
||||
(12, 12, 12),
|
||||
(197, 15, 31),
|
||||
(19, 161, 14),
|
||||
(193, 156, 0),
|
||||
(0, 55, 218),
|
||||
(136, 23, 152),
|
||||
(58, 150, 221),
|
||||
(204, 204, 204),
|
||||
(118, 118, 118),
|
||||
(231, 72, 86),
|
||||
(22, 198, 12),
|
||||
(249, 241, 165),
|
||||
(59, 120, 255),
|
||||
(180, 0, 158),
|
||||
(97, 214, 214),
|
||||
(242, 242, 242),
|
||||
]
|
||||
)
|
||||
|
||||
# # The standard ansi colors (including bright variants)
|
||||
STANDARD_PALETTE = Palette(
|
||||
[
|
||||
(0, 0, 0),
|
||||
(170, 0, 0),
|
||||
(0, 170, 0),
|
||||
(170, 85, 0),
|
||||
(0, 0, 170),
|
||||
(170, 0, 170),
|
||||
(0, 170, 170),
|
||||
(170, 170, 170),
|
||||
(85, 85, 85),
|
||||
(255, 85, 85),
|
||||
(85, 255, 85),
|
||||
(255, 255, 85),
|
||||
(85, 85, 255),
|
||||
(255, 85, 255),
|
||||
(85, 255, 255),
|
||||
(255, 255, 255),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# The 256 color palette
|
||||
EIGHT_BIT_PALETTE = Palette(
|
||||
[
|
||||
(0, 0, 0),
|
||||
(128, 0, 0),
|
||||
(0, 128, 0),
|
||||
(128, 128, 0),
|
||||
(0, 0, 128),
|
||||
(128, 0, 128),
|
||||
(0, 128, 128),
|
||||
(192, 192, 192),
|
||||
(128, 128, 128),
|
||||
(255, 0, 0),
|
||||
(0, 255, 0),
|
||||
(255, 255, 0),
|
||||
(0, 0, 255),
|
||||
(255, 0, 255),
|
||||
(0, 255, 255),
|
||||
(255, 255, 255),
|
||||
(0, 0, 0),
|
||||
(0, 0, 95),
|
||||
(0, 0, 135),
|
||||
(0, 0, 175),
|
||||
(0, 0, 215),
|
||||
(0, 0, 255),
|
||||
(0, 95, 0),
|
||||
(0, 95, 95),
|
||||
(0, 95, 135),
|
||||
(0, 95, 175),
|
||||
(0, 95, 215),
|
||||
(0, 95, 255),
|
||||
(0, 135, 0),
|
||||
(0, 135, 95),
|
||||
(0, 135, 135),
|
||||
(0, 135, 175),
|
||||
(0, 135, 215),
|
||||
(0, 135, 255),
|
||||
(0, 175, 0),
|
||||
(0, 175, 95),
|
||||
(0, 175, 135),
|
||||
(0, 175, 175),
|
||||
(0, 175, 215),
|
||||
(0, 175, 255),
|
||||
(0, 215, 0),
|
||||
(0, 215, 95),
|
||||
(0, 215, 135),
|
||||
(0, 215, 175),
|
||||
(0, 215, 215),
|
||||
(0, 215, 255),
|
||||
(0, 255, 0),
|
||||
(0, 255, 95),
|
||||
(0, 255, 135),
|
||||
(0, 255, 175),
|
||||
(0, 255, 215),
|
||||
(0, 255, 255),
|
||||
(95, 0, 0),
|
||||
(95, 0, 95),
|
||||
(95, 0, 135),
|
||||
(95, 0, 175),
|
||||
(95, 0, 215),
|
||||
(95, 0, 255),
|
||||
(95, 95, 0),
|
||||
(95, 95, 95),
|
||||
(95, 95, 135),
|
||||
(95, 95, 175),
|
||||
(95, 95, 215),
|
||||
(95, 95, 255),
|
||||
(95, 135, 0),
|
||||
(95, 135, 95),
|
||||
(95, 135, 135),
|
||||
(95, 135, 175),
|
||||
(95, 135, 215),
|
||||
(95, 135, 255),
|
||||
(95, 175, 0),
|
||||
(95, 175, 95),
|
||||
(95, 175, 135),
|
||||
(95, 175, 175),
|
||||
(95, 175, 215),
|
||||
(95, 175, 255),
|
||||
(95, 215, 0),
|
||||
(95, 215, 95),
|
||||
(95, 215, 135),
|
||||
(95, 215, 175),
|
||||
(95, 215, 215),
|
||||
(95, 215, 255),
|
||||
(95, 255, 0),
|
||||
(95, 255, 95),
|
||||
(95, 255, 135),
|
||||
(95, 255, 175),
|
||||
(95, 255, 215),
|
||||
(95, 255, 255),
|
||||
(135, 0, 0),
|
||||
(135, 0, 95),
|
||||
(135, 0, 135),
|
||||
(135, 0, 175),
|
||||
(135, 0, 215),
|
||||
(135, 0, 255),
|
||||
(135, 95, 0),
|
||||
(135, 95, 95),
|
||||
(135, 95, 135),
|
||||
(135, 95, 175),
|
||||
(135, 95, 215),
|
||||
(135, 95, 255),
|
||||
(135, 135, 0),
|
||||
(135, 135, 95),
|
||||
(135, 135, 135),
|
||||
(135, 135, 175),
|
||||
(135, 135, 215),
|
||||
(135, 135, 255),
|
||||
(135, 175, 0),
|
||||
(135, 175, 95),
|
||||
(135, 175, 135),
|
||||
(135, 175, 175),
|
||||
(135, 175, 215),
|
||||
(135, 175, 255),
|
||||
(135, 215, 0),
|
||||
(135, 215, 95),
|
||||
(135, 215, 135),
|
||||
(135, 215, 175),
|
||||
(135, 215, 215),
|
||||
(135, 215, 255),
|
||||
(135, 255, 0),
|
||||
(135, 255, 95),
|
||||
(135, 255, 135),
|
||||
(135, 255, 175),
|
||||
(135, 255, 215),
|
||||
(135, 255, 255),
|
||||
(175, 0, 0),
|
||||
(175, 0, 95),
|
||||
(175, 0, 135),
|
||||
(175, 0, 175),
|
||||
(175, 0, 215),
|
||||
(175, 0, 255),
|
||||
(175, 95, 0),
|
||||
(175, 95, 95),
|
||||
(175, 95, 135),
|
||||
(175, 95, 175),
|
||||
(175, 95, 215),
|
||||
(175, 95, 255),
|
||||
(175, 135, 0),
|
||||
(175, 135, 95),
|
||||
(175, 135, 135),
|
||||
(175, 135, 175),
|
||||
(175, 135, 215),
|
||||
(175, 135, 255),
|
||||
(175, 175, 0),
|
||||
(175, 175, 95),
|
||||
(175, 175, 135),
|
||||
(175, 175, 175),
|
||||
(175, 175, 215),
|
||||
(175, 175, 255),
|
||||
(175, 215, 0),
|
||||
(175, 215, 95),
|
||||
(175, 215, 135),
|
||||
(175, 215, 175),
|
||||
(175, 215, 215),
|
||||
(175, 215, 255),
|
||||
(175, 255, 0),
|
||||
(175, 255, 95),
|
||||
(175, 255, 135),
|
||||
(175, 255, 175),
|
||||
(175, 255, 215),
|
||||
(175, 255, 255),
|
||||
(215, 0, 0),
|
||||
(215, 0, 95),
|
||||
(215, 0, 135),
|
||||
(215, 0, 175),
|
||||
(215, 0, 215),
|
||||
(215, 0, 255),
|
||||
(215, 95, 0),
|
||||
(215, 95, 95),
|
||||
(215, 95, 135),
|
||||
(215, 95, 175),
|
||||
(215, 95, 215),
|
||||
(215, 95, 255),
|
||||
(215, 135, 0),
|
||||
(215, 135, 95),
|
||||
(215, 135, 135),
|
||||
(215, 135, 175),
|
||||
(215, 135, 215),
|
||||
(215, 135, 255),
|
||||
(215, 175, 0),
|
||||
(215, 175, 95),
|
||||
(215, 175, 135),
|
||||
(215, 175, 175),
|
||||
(215, 175, 215),
|
||||
(215, 175, 255),
|
||||
(215, 215, 0),
|
||||
(215, 215, 95),
|
||||
(215, 215, 135),
|
||||
(215, 215, 175),
|
||||
(215, 215, 215),
|
||||
(215, 215, 255),
|
||||
(215, 255, 0),
|
||||
(215, 255, 95),
|
||||
(215, 255, 135),
|
||||
(215, 255, 175),
|
||||
(215, 255, 215),
|
||||
(215, 255, 255),
|
||||
(255, 0, 0),
|
||||
(255, 0, 95),
|
||||
(255, 0, 135),
|
||||
(255, 0, 175),
|
||||
(255, 0, 215),
|
||||
(255, 0, 255),
|
||||
(255, 95, 0),
|
||||
(255, 95, 95),
|
||||
(255, 95, 135),
|
||||
(255, 95, 175),
|
||||
(255, 95, 215),
|
||||
(255, 95, 255),
|
||||
(255, 135, 0),
|
||||
(255, 135, 95),
|
||||
(255, 135, 135),
|
||||
(255, 135, 175),
|
||||
(255, 135, 215),
|
||||
(255, 135, 255),
|
||||
(255, 175, 0),
|
||||
(255, 175, 95),
|
||||
(255, 175, 135),
|
||||
(255, 175, 175),
|
||||
(255, 175, 215),
|
||||
(255, 175, 255),
|
||||
(255, 215, 0),
|
||||
(255, 215, 95),
|
||||
(255, 215, 135),
|
||||
(255, 215, 175),
|
||||
(255, 215, 215),
|
||||
(255, 215, 255),
|
||||
(255, 255, 0),
|
||||
(255, 255, 95),
|
||||
(255, 255, 135),
|
||||
(255, 255, 175),
|
||||
(255, 255, 215),
|
||||
(255, 255, 255),
|
||||
(8, 8, 8),
|
||||
(18, 18, 18),
|
||||
(28, 28, 28),
|
||||
(38, 38, 38),
|
||||
(48, 48, 48),
|
||||
(58, 58, 58),
|
||||
(68, 68, 68),
|
||||
(78, 78, 78),
|
||||
(88, 88, 88),
|
||||
(98, 98, 98),
|
||||
(108, 108, 108),
|
||||
(118, 118, 118),
|
||||
(128, 128, 128),
|
||||
(138, 138, 138),
|
||||
(148, 148, 148),
|
||||
(158, 158, 158),
|
||||
(168, 168, 168),
|
||||
(178, 178, 178),
|
||||
(188, 188, 188),
|
||||
(198, 198, 198),
|
||||
(208, 208, 208),
|
||||
(218, 218, 218),
|
||||
(228, 228, 228),
|
||||
(238, 238, 238),
|
||||
]
|
||||
)
|
17
venv/lib/python3.11/site-packages/pip/_vendor/rich/_pick.py
Normal file
17
venv/lib/python3.11/site-packages/pip/_vendor/rich/_pick.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from typing import Optional
|
||||
|
||||
|
||||
def pick_bool(*values: Optional[bool]) -> bool:
|
||||
"""Pick the first non-none bool or return the last value.
|
||||
|
||||
Args:
|
||||
*values (bool): Any number of boolean or None values.
|
||||
|
||||
Returns:
|
||||
bool: First non-none boolean.
|
||||
"""
|
||||
assert values, "1 or more values required"
|
||||
for value in values:
|
||||
if value is not None:
|
||||
return value
|
||||
return bool(value)
|
160
venv/lib/python3.11/site-packages/pip/_vendor/rich/_ratio.py
Normal file
160
venv/lib/python3.11/site-packages/pip/_vendor/rich/_ratio.py
Normal file
|
@ -0,0 +1,160 @@
|
|||
import sys
|
||||
from fractions import Fraction
|
||||
from math import ceil
|
||||
from typing import cast, List, Optional, Sequence
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
from typing import Protocol
|
||||
else:
|
||||
from pip._vendor.typing_extensions import Protocol # pragma: no cover
|
||||
|
||||
|
||||
class Edge(Protocol):
|
||||
"""Any object that defines an edge (such as Layout)."""
|
||||
|
||||
size: Optional[int] = None
|
||||
ratio: int = 1
|
||||
minimum_size: int = 1
|
||||
|
||||
|
||||
def ratio_resolve(total: int, edges: Sequence[Edge]) -> List[int]:
|
||||
"""Divide total space to satisfy size, ratio, and minimum_size, constraints.
|
||||
|
||||
The returned list of integers should add up to total in most cases, unless it is
|
||||
impossible to satisfy all the constraints. For instance, if there are two edges
|
||||
with a minimum size of 20 each and `total` is 30 then the returned list will be
|
||||
greater than total. In practice, this would mean that a Layout object would
|
||||
clip the rows that would overflow the screen height.
|
||||
|
||||
Args:
|
||||
total (int): Total number of characters.
|
||||
edges (List[Edge]): Edges within total space.
|
||||
|
||||
Returns:
|
||||
List[int]: Number of characters for each edge.
|
||||
"""
|
||||
# Size of edge or None for yet to be determined
|
||||
sizes = [(edge.size or None) for edge in edges]
|
||||
|
||||
_Fraction = Fraction
|
||||
|
||||
# While any edges haven't been calculated
|
||||
while None in sizes:
|
||||
# Get flexible edges and index to map these back on to sizes list
|
||||
flexible_edges = [
|
||||
(index, edge)
|
||||
for index, (size, edge) in enumerate(zip(sizes, edges))
|
||||
if size is None
|
||||
]
|
||||
# Remaining space in total
|
||||
remaining = total - sum(size or 0 for size in sizes)
|
||||
if remaining <= 0:
|
||||
# No room for flexible edges
|
||||
return [
|
||||
((edge.minimum_size or 1) if size is None else size)
|
||||
for size, edge in zip(sizes, edges)
|
||||
]
|
||||
# Calculate number of characters in a ratio portion
|
||||
portion = _Fraction(
|
||||
remaining, sum((edge.ratio or 1) for _, edge in flexible_edges)
|
||||
)
|
||||
|
||||
# If any edges will be less than their minimum, replace size with the minimum
|
||||
for index, edge in flexible_edges:
|
||||
if portion * edge.ratio <= edge.minimum_size:
|
||||
sizes[index] = edge.minimum_size
|
||||
# New fixed size will invalidate calculations, so we need to repeat the process
|
||||
break
|
||||
else:
|
||||
# Distribute flexible space and compensate for rounding error
|
||||
# Since edge sizes can only be integers we need to add the remainder
|
||||
# to the following line
|
||||
remainder = _Fraction(0)
|
||||
for index, edge in flexible_edges:
|
||||
size, remainder = divmod(portion * edge.ratio + remainder, 1)
|
||||
sizes[index] = size
|
||||
break
|
||||
# Sizes now contains integers only
|
||||
return cast(List[int], sizes)
|
||||
|
||||
|
||||
def ratio_reduce(
|
||||
total: int, ratios: List[int], maximums: List[int], values: List[int]
|
||||
) -> List[int]:
|
||||
"""Divide an integer total in to parts based on ratios.
|
||||
|
||||
Args:
|
||||
total (int): The total to divide.
|
||||
ratios (List[int]): A list of integer ratios.
|
||||
maximums (List[int]): List of maximums values for each slot.
|
||||
values (List[int]): List of values
|
||||
|
||||
Returns:
|
||||
List[int]: A list of integers guaranteed to sum to total.
|
||||
"""
|
||||
ratios = [ratio if _max else 0 for ratio, _max in zip(ratios, maximums)]
|
||||
total_ratio = sum(ratios)
|
||||
if not total_ratio:
|
||||
return values[:]
|
||||
total_remaining = total
|
||||
result: List[int] = []
|
||||
append = result.append
|
||||
for ratio, maximum, value in zip(ratios, maximums, values):
|
||||
if ratio and total_ratio > 0:
|
||||
distributed = min(maximum, round(ratio * total_remaining / total_ratio))
|
||||
append(value - distributed)
|
||||
total_remaining -= distributed
|
||||
total_ratio -= ratio
|
||||
else:
|
||||
append(value)
|
||||
return result
|
||||
|
||||
|
||||
def ratio_distribute(
|
||||
total: int, ratios: List[int], minimums: Optional[List[int]] = None
|
||||
) -> List[int]:
|
||||
"""Distribute an integer total in to parts based on ratios.
|
||||
|
||||
Args:
|
||||
total (int): The total to divide.
|
||||
ratios (List[int]): A list of integer ratios.
|
||||
minimums (List[int]): List of minimum values for each slot.
|
||||
|
||||
Returns:
|
||||
List[int]: A list of integers guaranteed to sum to total.
|
||||
"""
|
||||
if minimums:
|
||||
ratios = [ratio if _min else 0 for ratio, _min in zip(ratios, minimums)]
|
||||
total_ratio = sum(ratios)
|
||||
assert total_ratio > 0, "Sum of ratios must be > 0"
|
||||
|
||||
total_remaining = total
|
||||
distributed_total: List[int] = []
|
||||
append = distributed_total.append
|
||||
if minimums is None:
|
||||
_minimums = [0] * len(ratios)
|
||||
else:
|
||||
_minimums = minimums
|
||||
for ratio, minimum in zip(ratios, _minimums):
|
||||
if total_ratio > 0:
|
||||
distributed = max(minimum, ceil(ratio * total_remaining / total_ratio))
|
||||
else:
|
||||
distributed = total_remaining
|
||||
append(distributed)
|
||||
total_ratio -= ratio
|
||||
total_remaining -= distributed
|
||||
return distributed_total
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class E:
|
||||
|
||||
size: Optional[int] = None
|
||||
ratio: int = 1
|
||||
minimum_size: int = 1
|
||||
|
||||
resolved = ratio_resolve(110, [E(None, 1, 1), E(None, 1, 1), E(None, 1, 1)])
|
||||
print(sum(resolved))
|
482
venv/lib/python3.11/site-packages/pip/_vendor/rich/_spinners.py
Normal file
482
venv/lib/python3.11/site-packages/pip/_vendor/rich/_spinners.py
Normal file
|
@ -0,0 +1,482 @@
|
|||
"""
|
||||
Spinners are from:
|
||||
* cli-spinners:
|
||||
MIT License
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
SPINNERS = {
|
||||
"dots": {
|
||||
"interval": 80,
|
||||
"frames": "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏",
|
||||
},
|
||||
"dots2": {"interval": 80, "frames": "⣾⣽⣻⢿⡿⣟⣯⣷"},
|
||||
"dots3": {
|
||||
"interval": 80,
|
||||
"frames": "⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓",
|
||||
},
|
||||
"dots4": {
|
||||
"interval": 80,
|
||||
"frames": "⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆",
|
||||
},
|
||||
"dots5": {
|
||||
"interval": 80,
|
||||
"frames": "⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋",
|
||||
},
|
||||
"dots6": {
|
||||
"interval": 80,
|
||||
"frames": "⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁",
|
||||
},
|
||||
"dots7": {
|
||||
"interval": 80,
|
||||
"frames": "⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈",
|
||||
},
|
||||
"dots8": {
|
||||
"interval": 80,
|
||||
"frames": "⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈",
|
||||
},
|
||||
"dots9": {"interval": 80, "frames": "⢹⢺⢼⣸⣇⡧⡗⡏"},
|
||||
"dots10": {"interval": 80, "frames": "⢄⢂⢁⡁⡈⡐⡠"},
|
||||
"dots11": {"interval": 100, "frames": "⠁⠂⠄⡀⢀⠠⠐⠈"},
|
||||
"dots12": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"⢀⠀",
|
||||
"⡀⠀",
|
||||
"⠄⠀",
|
||||
"⢂⠀",
|
||||
"⡂⠀",
|
||||
"⠅⠀",
|
||||
"⢃⠀",
|
||||
"⡃⠀",
|
||||
"⠍⠀",
|
||||
"⢋⠀",
|
||||
"⡋⠀",
|
||||
"⠍⠁",
|
||||
"⢋⠁",
|
||||
"⡋⠁",
|
||||
"⠍⠉",
|
||||
"⠋⠉",
|
||||
"⠋⠉",
|
||||
"⠉⠙",
|
||||
"⠉⠙",
|
||||
"⠉⠩",
|
||||
"⠈⢙",
|
||||
"⠈⡙",
|
||||
"⢈⠩",
|
||||
"⡀⢙",
|
||||
"⠄⡙",
|
||||
"⢂⠩",
|
||||
"⡂⢘",
|
||||
"⠅⡘",
|
||||
"⢃⠨",
|
||||
"⡃⢐",
|
||||
"⠍⡐",
|
||||
"⢋⠠",
|
||||
"⡋⢀",
|
||||
"⠍⡁",
|
||||
"⢋⠁",
|
||||
"⡋⠁",
|
||||
"⠍⠉",
|
||||
"⠋⠉",
|
||||
"⠋⠉",
|
||||
"⠉⠙",
|
||||
"⠉⠙",
|
||||
"⠉⠩",
|
||||
"⠈⢙",
|
||||
"⠈⡙",
|
||||
"⠈⠩",
|
||||
"⠀⢙",
|
||||
"⠀⡙",
|
||||
"⠀⠩",
|
||||
"⠀⢘",
|
||||
"⠀⡘",
|
||||
"⠀⠨",
|
||||
"⠀⢐",
|
||||
"⠀⡐",
|
||||
"⠀⠠",
|
||||
"⠀⢀",
|
||||
"⠀⡀",
|
||||
],
|
||||
},
|
||||
"dots8Bit": {
|
||||
"interval": 80,
|
||||
"frames": "⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙"
|
||||
"⡚⡛⡜⡝⡞⡟⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻"
|
||||
"⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕"
|
||||
"⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷"
|
||||
"⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿",
|
||||
},
|
||||
"line": {"interval": 130, "frames": ["-", "\\", "|", "/"]},
|
||||
"line2": {"interval": 100, "frames": "⠂-–—–-"},
|
||||
"pipe": {"interval": 100, "frames": "┤┘┴└├┌┬┐"},
|
||||
"simpleDots": {"interval": 400, "frames": [". ", ".. ", "...", " "]},
|
||||
"simpleDotsScrolling": {
|
||||
"interval": 200,
|
||||
"frames": [". ", ".. ", "...", " ..", " .", " "],
|
||||
},
|
||||
"star": {"interval": 70, "frames": "✶✸✹✺✹✷"},
|
||||
"star2": {"interval": 80, "frames": "+x*"},
|
||||
"flip": {
|
||||
"interval": 70,
|
||||
"frames": "___-``'´-___",
|
||||
},
|
||||
"hamburger": {"interval": 100, "frames": "☱☲☴"},
|
||||
"growVertical": {
|
||||
"interval": 120,
|
||||
"frames": "▁▃▄▅▆▇▆▅▄▃",
|
||||
},
|
||||
"growHorizontal": {
|
||||
"interval": 120,
|
||||
"frames": "▏▎▍▌▋▊▉▊▋▌▍▎",
|
||||
},
|
||||
"balloon": {"interval": 140, "frames": " .oO@* "},
|
||||
"balloon2": {"interval": 120, "frames": ".oO°Oo."},
|
||||
"noise": {"interval": 100, "frames": "▓▒░"},
|
||||
"bounce": {"interval": 120, "frames": "⠁⠂⠄⠂"},
|
||||
"boxBounce": {"interval": 120, "frames": "▖▘▝▗"},
|
||||
"boxBounce2": {"interval": 100, "frames": "▌▀▐▄"},
|
||||
"triangle": {"interval": 50, "frames": "◢◣◤◥"},
|
||||
"arc": {"interval": 100, "frames": "◜◠◝◞◡◟"},
|
||||
"circle": {"interval": 120, "frames": "◡⊙◠"},
|
||||
"squareCorners": {"interval": 180, "frames": "◰◳◲◱"},
|
||||
"circleQuarters": {"interval": 120, "frames": "◴◷◶◵"},
|
||||
"circleHalves": {"interval": 50, "frames": "◐◓◑◒"},
|
||||
"squish": {"interval": 100, "frames": "╫╪"},
|
||||
"toggle": {"interval": 250, "frames": "⊶⊷"},
|
||||
"toggle2": {"interval": 80, "frames": "▫▪"},
|
||||
"toggle3": {"interval": 120, "frames": "□■"},
|
||||
"toggle4": {"interval": 100, "frames": "■□▪▫"},
|
||||
"toggle5": {"interval": 100, "frames": "▮▯"},
|
||||
"toggle6": {"interval": 300, "frames": "ဝ၀"},
|
||||
"toggle7": {"interval": 80, "frames": "⦾⦿"},
|
||||
"toggle8": {"interval": 100, "frames": "◍◌"},
|
||||
"toggle9": {"interval": 100, "frames": "◉◎"},
|
||||
"toggle10": {"interval": 100, "frames": "㊂㊀㊁"},
|
||||
"toggle11": {"interval": 50, "frames": "⧇⧆"},
|
||||
"toggle12": {"interval": 120, "frames": "☗☖"},
|
||||
"toggle13": {"interval": 80, "frames": "=*-"},
|
||||
"arrow": {"interval": 100, "frames": "←↖↑↗→↘↓↙"},
|
||||
"arrow2": {
|
||||
"interval": 80,
|
||||
"frames": ["⬆️ ", "↗️ ", "➡️ ", "↘️ ", "⬇️ ", "↙️ ", "⬅️ ", "↖️ "],
|
||||
},
|
||||
"arrow3": {
|
||||
"interval": 120,
|
||||
"frames": ["▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸"],
|
||||
},
|
||||
"bouncingBar": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"[ ]",
|
||||
"[= ]",
|
||||
"[== ]",
|
||||
"[=== ]",
|
||||
"[ ===]",
|
||||
"[ ==]",
|
||||
"[ =]",
|
||||
"[ ]",
|
||||
"[ =]",
|
||||
"[ ==]",
|
||||
"[ ===]",
|
||||
"[====]",
|
||||
"[=== ]",
|
||||
"[== ]",
|
||||
"[= ]",
|
||||
],
|
||||
},
|
||||
"bouncingBall": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"( ● )",
|
||||
"( ● )",
|
||||
"( ● )",
|
||||
"( ● )",
|
||||
"( ●)",
|
||||
"( ● )",
|
||||
"( ● )",
|
||||
"( ● )",
|
||||
"( ● )",
|
||||
"(● )",
|
||||
],
|
||||
},
|
||||
"smiley": {"interval": 200, "frames": ["😄 ", "😝 "]},
|
||||
"monkey": {"interval": 300, "frames": ["🙈 ", "🙈 ", "🙉 ", "🙊 "]},
|
||||
"hearts": {"interval": 100, "frames": ["💛 ", "💙 ", "💜 ", "💚 ", "❤️ "]},
|
||||
"clock": {
|
||||
"interval": 100,
|
||||
"frames": [
|
||||
"🕛 ",
|
||||
"🕐 ",
|
||||
"🕑 ",
|
||||
"🕒 ",
|
||||
"🕓 ",
|
||||
"🕔 ",
|
||||
"🕕 ",
|
||||
"🕖 ",
|
||||
"🕗 ",
|
||||
"🕘 ",
|
||||
"🕙 ",
|
||||
"🕚 ",
|
||||
],
|
||||
},
|
||||
"earth": {"interval": 180, "frames": ["🌍 ", "🌎 ", "🌏 "]},
|
||||
"material": {
|
||||
"interval": 17,
|
||||
"frames": [
|
||||
"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"███████▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"████████▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"█████████▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"█████████▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"██████████▁▁▁▁▁▁▁▁▁▁",
|
||||
"███████████▁▁▁▁▁▁▁▁▁",
|
||||
"█████████████▁▁▁▁▁▁▁",
|
||||
"██████████████▁▁▁▁▁▁",
|
||||
"██████████████▁▁▁▁▁▁",
|
||||
"▁██████████████▁▁▁▁▁",
|
||||
"▁██████████████▁▁▁▁▁",
|
||||
"▁██████████████▁▁▁▁▁",
|
||||
"▁▁██████████████▁▁▁▁",
|
||||
"▁▁▁██████████████▁▁▁",
|
||||
"▁▁▁▁█████████████▁▁▁",
|
||||
"▁▁▁▁██████████████▁▁",
|
||||
"▁▁▁▁██████████████▁▁",
|
||||
"▁▁▁▁▁██████████████▁",
|
||||
"▁▁▁▁▁██████████████▁",
|
||||
"▁▁▁▁▁██████████████▁",
|
||||
"▁▁▁▁▁▁██████████████",
|
||||
"▁▁▁▁▁▁██████████████",
|
||||
"▁▁▁▁▁▁▁█████████████",
|
||||
"▁▁▁▁▁▁▁█████████████",
|
||||
"▁▁▁▁▁▁▁▁████████████",
|
||||
"▁▁▁▁▁▁▁▁████████████",
|
||||
"▁▁▁▁▁▁▁▁▁███████████",
|
||||
"▁▁▁▁▁▁▁▁▁███████████",
|
||||
"▁▁▁▁▁▁▁▁▁▁██████████",
|
||||
"▁▁▁▁▁▁▁▁▁▁██████████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁████████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
|
||||
"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
|
||||
"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
|
||||
"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
|
||||
"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
|
||||
"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
|
||||
"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
|
||||
"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
|
||||
"██████▁▁▁▁▁▁▁▁▁▁▁▁▁█",
|
||||
"████████▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"█████████▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"█████████▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"█████████▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"█████████▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"███████████▁▁▁▁▁▁▁▁▁",
|
||||
"████████████▁▁▁▁▁▁▁▁",
|
||||
"████████████▁▁▁▁▁▁▁▁",
|
||||
"██████████████▁▁▁▁▁▁",
|
||||
"██████████████▁▁▁▁▁▁",
|
||||
"▁██████████████▁▁▁▁▁",
|
||||
"▁██████████████▁▁▁▁▁",
|
||||
"▁▁▁█████████████▁▁▁▁",
|
||||
"▁▁▁▁▁████████████▁▁▁",
|
||||
"▁▁▁▁▁████████████▁▁▁",
|
||||
"▁▁▁▁▁▁███████████▁▁▁",
|
||||
"▁▁▁▁▁▁▁▁█████████▁▁▁",
|
||||
"▁▁▁▁▁▁▁▁█████████▁▁▁",
|
||||
"▁▁▁▁▁▁▁▁▁█████████▁▁",
|
||||
"▁▁▁▁▁▁▁▁▁█████████▁▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁█████████▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁████████▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁████████▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
],
|
||||
},
|
||||
"moon": {
|
||||
"interval": 80,
|
||||
"frames": ["🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "],
|
||||
},
|
||||
"runner": {"interval": 140, "frames": ["🚶 ", "🏃 "]},
|
||||
"pong": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"▐⠂ ▌",
|
||||
"▐⠈ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⡀ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠈ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⡀ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠈ ▌",
|
||||
"▐ ⠂▌",
|
||||
"▐ ⠠▌",
|
||||
"▐ ⡀▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠈ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⡀ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠈ ▌",
|
||||
"▐ ⠂ ▌",
|
||||
"▐ ⠠ ▌",
|
||||
"▐ ⡀ ▌",
|
||||
"▐⠠ ▌",
|
||||
],
|
||||
},
|
||||
"shark": {
|
||||
"interval": 120,
|
||||
"frames": [
|
||||
"▐|\\____________▌",
|
||||
"▐_|\\___________▌",
|
||||
"▐__|\\__________▌",
|
||||
"▐___|\\_________▌",
|
||||
"▐____|\\________▌",
|
||||
"▐_____|\\_______▌",
|
||||
"▐______|\\______▌",
|
||||
"▐_______|\\_____▌",
|
||||
"▐________|\\____▌",
|
||||
"▐_________|\\___▌",
|
||||
"▐__________|\\__▌",
|
||||
"▐___________|\\_▌",
|
||||
"▐____________|\\▌",
|
||||
"▐____________/|▌",
|
||||
"▐___________/|_▌",
|
||||
"▐__________/|__▌",
|
||||
"▐_________/|___▌",
|
||||
"▐________/|____▌",
|
||||
"▐_______/|_____▌",
|
||||
"▐______/|______▌",
|
||||
"▐_____/|_______▌",
|
||||
"▐____/|________▌",
|
||||
"▐___/|_________▌",
|
||||
"▐__/|__________▌",
|
||||
"▐_/|___________▌",
|
||||
"▐/|____________▌",
|
||||
],
|
||||
},
|
||||
"dqpb": {"interval": 100, "frames": "dqpb"},
|
||||
"weather": {
|
||||
"interval": 100,
|
||||
"frames": [
|
||||
"☀️ ",
|
||||
"☀️ ",
|
||||
"☀️ ",
|
||||
"🌤 ",
|
||||
"⛅️ ",
|
||||
"🌥 ",
|
||||
"☁️ ",
|
||||
"🌧 ",
|
||||
"🌨 ",
|
||||
"🌧 ",
|
||||
"🌨 ",
|
||||
"🌧 ",
|
||||
"🌨 ",
|
||||
"⛈ ",
|
||||
"🌨 ",
|
||||
"🌧 ",
|
||||
"🌨 ",
|
||||
"☁️ ",
|
||||
"🌥 ",
|
||||
"⛅️ ",
|
||||
"🌤 ",
|
||||
"☀️ ",
|
||||
"☀️ ",
|
||||
],
|
||||
},
|
||||
"christmas": {"interval": 400, "frames": "🌲🎄"},
|
||||
"grenade": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"، ",
|
||||
"′ ",
|
||||
" ´ ",
|
||||
" ‾ ",
|
||||
" ⸌",
|
||||
" ⸊",
|
||||
" |",
|
||||
" ⁎",
|
||||
" ⁕",
|
||||
" ෴ ",
|
||||
" ⁓",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
},
|
||||
"point": {"interval": 125, "frames": ["∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"]},
|
||||
"layer": {"interval": 150, "frames": "-=≡"},
|
||||
"betaWave": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"ρββββββ",
|
||||
"βρβββββ",
|
||||
"ββρββββ",
|
||||
"βββρβββ",
|
||||
"ββββρββ",
|
||||
"βββββρβ",
|
||||
"ββββββρ",
|
||||
],
|
||||
},
|
||||
"aesthetic": {
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"▰▱▱▱▱▱▱",
|
||||
"▰▰▱▱▱▱▱",
|
||||
"▰▰▰▱▱▱▱",
|
||||
"▰▰▰▰▱▱▱",
|
||||
"▰▰▰▰▰▱▱",
|
||||
"▰▰▰▰▰▰▱",
|
||||
"▰▰▰▰▰▰▰",
|
||||
"▰▱▱▱▱▱▱",
|
||||
],
|
||||
},
|
||||
}
|
16
venv/lib/python3.11/site-packages/pip/_vendor/rich/_stack.py
Normal file
16
venv/lib/python3.11/site-packages/pip/_vendor/rich/_stack.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from typing import List, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Stack(List[T]):
|
||||
"""A small shim over builtin list."""
|
||||
|
||||
@property
|
||||
def top(self) -> T:
|
||||
"""Get top of stack."""
|
||||
return self[-1]
|
||||
|
||||
def push(self, item: T) -> None:
|
||||
"""Push an item on to the stack (append in stack nomenclature)."""
|
||||
self.append(item)
|
19
venv/lib/python3.11/site-packages/pip/_vendor/rich/_timer.py
Normal file
19
venv/lib/python3.11/site-packages/pip/_vendor/rich/_timer.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
Timer context manager, only used in debug.
|
||||
|
||||
"""
|
||||
|
||||
from time import time
|
||||
|
||||
import contextlib
|
||||
from typing import Generator
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def timer(subject: str = "time") -> Generator[None, None, None]:
|
||||
"""print the elapsed time. (only used in debugging)"""
|
||||
start = time()
|
||||
yield
|
||||
elapsed = time() - start
|
||||
elapsed_ms = elapsed * 1000
|
||||
print(f"{subject} elapsed {elapsed_ms:.1f}ms")
|
|
@ -0,0 +1,662 @@
|
|||
"""Light wrapper around the Win32 Console API - this module should only be imported on Windows
|
||||
|
||||
The API that this module wraps is documented at https://docs.microsoft.com/en-us/windows/console/console-functions
|
||||
"""
|
||||
import ctypes
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
windll: Any = None
|
||||
if sys.platform == "win32":
|
||||
windll = ctypes.LibraryLoader(ctypes.WinDLL)
|
||||
else:
|
||||
raise ImportError(f"{__name__} can only be imported on Windows")
|
||||
|
||||
import time
|
||||
from ctypes import Structure, byref, wintypes
|
||||
from typing import IO, NamedTuple, Type, cast
|
||||
|
||||
from pip._vendor.rich.color import ColorSystem
|
||||
from pip._vendor.rich.style import Style
|
||||
|
||||
STDOUT = -11
|
||||
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
|
||||
|
||||
COORD = wintypes._COORD
|
||||
|
||||
|
||||
class LegacyWindowsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class WindowsCoordinates(NamedTuple):
|
||||
"""Coordinates in the Windows Console API are (y, x), not (x, y).
|
||||
This class is intended to prevent that confusion.
|
||||
Rows and columns are indexed from 0.
|
||||
This class can be used in place of wintypes._COORD in arguments and argtypes.
|
||||
"""
|
||||
|
||||
row: int
|
||||
col: int
|
||||
|
||||
@classmethod
|
||||
def from_param(cls, value: "WindowsCoordinates") -> COORD:
|
||||
"""Converts a WindowsCoordinates into a wintypes _COORD structure.
|
||||
This classmethod is internally called by ctypes to perform the conversion.
|
||||
|
||||
Args:
|
||||
value (WindowsCoordinates): The input coordinates to convert.
|
||||
|
||||
Returns:
|
||||
wintypes._COORD: The converted coordinates struct.
|
||||
"""
|
||||
return COORD(value.col, value.row)
|
||||
|
||||
|
||||
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
|
||||
_fields_ = [
|
||||
("dwSize", COORD),
|
||||
("dwCursorPosition", COORD),
|
||||
("wAttributes", wintypes.WORD),
|
||||
("srWindow", wintypes.SMALL_RECT),
|
||||
("dwMaximumWindowSize", COORD),
|
||||
]
|
||||
|
||||
|
||||
class CONSOLE_CURSOR_INFO(ctypes.Structure):
|
||||
_fields_ = [("dwSize", wintypes.DWORD), ("bVisible", wintypes.BOOL)]
|
||||
|
||||
|
||||
_GetStdHandle = windll.kernel32.GetStdHandle
|
||||
_GetStdHandle.argtypes = [
|
||||
wintypes.DWORD,
|
||||
]
|
||||
_GetStdHandle.restype = wintypes.HANDLE
|
||||
|
||||
|
||||
def GetStdHandle(handle: int = STDOUT) -> wintypes.HANDLE:
|
||||
"""Retrieves a handle to the specified standard device (standard input, standard output, or standard error).
|
||||
|
||||
Args:
|
||||
handle (int): Integer identifier for the handle. Defaults to -11 (stdout).
|
||||
|
||||
Returns:
|
||||
wintypes.HANDLE: The handle
|
||||
"""
|
||||
return cast(wintypes.HANDLE, _GetStdHandle(handle))
|
||||
|
||||
|
||||
_GetConsoleMode = windll.kernel32.GetConsoleMode
|
||||
_GetConsoleMode.argtypes = [wintypes.HANDLE, wintypes.LPDWORD]
|
||||
_GetConsoleMode.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def GetConsoleMode(std_handle: wintypes.HANDLE) -> int:
|
||||
"""Retrieves the current input mode of a console's input buffer
|
||||
or the current output mode of a console screen buffer.
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
|
||||
Raises:
|
||||
LegacyWindowsError: If any error occurs while calling the Windows console API.
|
||||
|
||||
Returns:
|
||||
int: Value representing the current console mode as documented at
|
||||
https://docs.microsoft.com/en-us/windows/console/getconsolemode#parameters
|
||||
"""
|
||||
|
||||
console_mode = wintypes.DWORD()
|
||||
success = bool(_GetConsoleMode(std_handle, console_mode))
|
||||
if not success:
|
||||
raise LegacyWindowsError("Unable to get legacy Windows Console Mode")
|
||||
return console_mode.value
|
||||
|
||||
|
||||
_FillConsoleOutputCharacterW = windll.kernel32.FillConsoleOutputCharacterW
|
||||
_FillConsoleOutputCharacterW.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
ctypes.c_char,
|
||||
wintypes.DWORD,
|
||||
cast(Type[COORD], WindowsCoordinates),
|
||||
ctypes.POINTER(wintypes.DWORD),
|
||||
]
|
||||
_FillConsoleOutputCharacterW.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def FillConsoleOutputCharacter(
|
||||
std_handle: wintypes.HANDLE,
|
||||
char: str,
|
||||
length: int,
|
||||
start: WindowsCoordinates,
|
||||
) -> int:
|
||||
"""Writes a character to the console screen buffer a specified number of times, beginning at the specified coordinates.
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
char (str): The character to write. Must be a string of length 1.
|
||||
length (int): The number of times to write the character.
|
||||
start (WindowsCoordinates): The coordinates to start writing at.
|
||||
|
||||
Returns:
|
||||
int: The number of characters written.
|
||||
"""
|
||||
character = ctypes.c_char(char.encode())
|
||||
num_characters = wintypes.DWORD(length)
|
||||
num_written = wintypes.DWORD(0)
|
||||
_FillConsoleOutputCharacterW(
|
||||
std_handle,
|
||||
character,
|
||||
num_characters,
|
||||
start,
|
||||
byref(num_written),
|
||||
)
|
||||
return num_written.value
|
||||
|
||||
|
||||
_FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute
|
||||
_FillConsoleOutputAttribute.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
wintypes.WORD,
|
||||
wintypes.DWORD,
|
||||
cast(Type[COORD], WindowsCoordinates),
|
||||
ctypes.POINTER(wintypes.DWORD),
|
||||
]
|
||||
_FillConsoleOutputAttribute.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def FillConsoleOutputAttribute(
|
||||
std_handle: wintypes.HANDLE,
|
||||
attributes: int,
|
||||
length: int,
|
||||
start: WindowsCoordinates,
|
||||
) -> int:
|
||||
"""Sets the character attributes for a specified number of character cells,
|
||||
beginning at the specified coordinates in a screen buffer.
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
attributes (int): Integer value representing the foreground and background colours of the cells.
|
||||
length (int): The number of cells to set the output attribute of.
|
||||
start (WindowsCoordinates): The coordinates of the first cell whose attributes are to be set.
|
||||
|
||||
Returns:
|
||||
int: The number of cells whose attributes were actually set.
|
||||
"""
|
||||
num_cells = wintypes.DWORD(length)
|
||||
style_attrs = wintypes.WORD(attributes)
|
||||
num_written = wintypes.DWORD(0)
|
||||
_FillConsoleOutputAttribute(
|
||||
std_handle, style_attrs, num_cells, start, byref(num_written)
|
||||
)
|
||||
return num_written.value
|
||||
|
||||
|
||||
_SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
|
||||
_SetConsoleTextAttribute.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
wintypes.WORD,
|
||||
]
|
||||
_SetConsoleTextAttribute.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def SetConsoleTextAttribute(
|
||||
std_handle: wintypes.HANDLE, attributes: wintypes.WORD
|
||||
) -> bool:
|
||||
"""Set the colour attributes for all text written after this function is called.
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
attributes (int): Integer value representing the foreground and background colours.
|
||||
|
||||
|
||||
Returns:
|
||||
bool: True if the attribute was set successfully, otherwise False.
|
||||
"""
|
||||
return bool(_SetConsoleTextAttribute(std_handle, attributes))
|
||||
|
||||
|
||||
_GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
|
||||
_GetConsoleScreenBufferInfo.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO),
|
||||
]
|
||||
_GetConsoleScreenBufferInfo.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def GetConsoleScreenBufferInfo(
|
||||
std_handle: wintypes.HANDLE,
|
||||
) -> CONSOLE_SCREEN_BUFFER_INFO:
|
||||
"""Retrieves information about the specified console screen buffer.
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
|
||||
Returns:
|
||||
CONSOLE_SCREEN_BUFFER_INFO: A CONSOLE_SCREEN_BUFFER_INFO ctype struct contain information about
|
||||
screen size, cursor position, colour attributes, and more."""
|
||||
console_screen_buffer_info = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
_GetConsoleScreenBufferInfo(std_handle, byref(console_screen_buffer_info))
|
||||
return console_screen_buffer_info
|
||||
|
||||
|
||||
_SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition
|
||||
_SetConsoleCursorPosition.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
cast(Type[COORD], WindowsCoordinates),
|
||||
]
|
||||
_SetConsoleCursorPosition.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def SetConsoleCursorPosition(
|
||||
std_handle: wintypes.HANDLE, coords: WindowsCoordinates
|
||||
) -> bool:
|
||||
"""Set the position of the cursor in the console screen
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
coords (WindowsCoordinates): The coordinates to move the cursor to.
|
||||
|
||||
Returns:
|
||||
bool: True if the function succeeds, otherwise False.
|
||||
"""
|
||||
return bool(_SetConsoleCursorPosition(std_handle, coords))
|
||||
|
||||
|
||||
_GetConsoleCursorInfo = windll.kernel32.GetConsoleCursorInfo
|
||||
_GetConsoleCursorInfo.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
ctypes.POINTER(CONSOLE_CURSOR_INFO),
|
||||
]
|
||||
_GetConsoleCursorInfo.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def GetConsoleCursorInfo(
|
||||
std_handle: wintypes.HANDLE, cursor_info: CONSOLE_CURSOR_INFO
|
||||
) -> bool:
|
||||
"""Get the cursor info - used to get cursor visibility and width
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
cursor_info (CONSOLE_CURSOR_INFO): CONSOLE_CURSOR_INFO ctype struct that receives information
|
||||
about the console's cursor.
|
||||
|
||||
Returns:
|
||||
bool: True if the function succeeds, otherwise False.
|
||||
"""
|
||||
return bool(_GetConsoleCursorInfo(std_handle, byref(cursor_info)))
|
||||
|
||||
|
||||
_SetConsoleCursorInfo = windll.kernel32.SetConsoleCursorInfo
|
||||
_SetConsoleCursorInfo.argtypes = [
|
||||
wintypes.HANDLE,
|
||||
ctypes.POINTER(CONSOLE_CURSOR_INFO),
|
||||
]
|
||||
_SetConsoleCursorInfo.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def SetConsoleCursorInfo(
|
||||
std_handle: wintypes.HANDLE, cursor_info: CONSOLE_CURSOR_INFO
|
||||
) -> bool:
|
||||
"""Set the cursor info - used for adjusting cursor visibility and width
|
||||
|
||||
Args:
|
||||
std_handle (wintypes.HANDLE): A handle to the console input buffer or the console screen buffer.
|
||||
cursor_info (CONSOLE_CURSOR_INFO): CONSOLE_CURSOR_INFO ctype struct containing the new cursor info.
|
||||
|
||||
Returns:
|
||||
bool: True if the function succeeds, otherwise False.
|
||||
"""
|
||||
return bool(_SetConsoleCursorInfo(std_handle, byref(cursor_info)))
|
||||
|
||||
|
||||
_SetConsoleTitle = windll.kernel32.SetConsoleTitleW
|
||||
_SetConsoleTitle.argtypes = [wintypes.LPCWSTR]
|
||||
_SetConsoleTitle.restype = wintypes.BOOL
|
||||
|
||||
|
||||
def SetConsoleTitle(title: str) -> bool:
|
||||
"""Sets the title of the current console window
|
||||
|
||||
Args:
|
||||
title (str): The new title of the console window.
|
||||
|
||||
Returns:
|
||||
bool: True if the function succeeds, otherwise False.
|
||||
"""
|
||||
return bool(_SetConsoleTitle(title))
|
||||
|
||||
|
||||
class LegacyWindowsTerm:
|
||||
"""This class allows interaction with the legacy Windows Console API. It should only be used in the context
|
||||
of environments where virtual terminal processing is not available. However, if it is used in a Windows environment,
|
||||
the entire API should work.
|
||||
|
||||
Args:
|
||||
file (IO[str]): The file which the Windows Console API HANDLE is retrieved from, defaults to sys.stdout.
|
||||
"""
|
||||
|
||||
BRIGHT_BIT = 8
|
||||
|
||||
# Indices are ANSI color numbers, values are the corresponding Windows Console API color numbers
|
||||
ANSI_TO_WINDOWS = [
|
||||
0, # black The Windows colours are defined in wincon.h as follows:
|
||||
4, # red define FOREGROUND_BLUE 0x0001 -- 0000 0001
|
||||
2, # green define FOREGROUND_GREEN 0x0002 -- 0000 0010
|
||||
6, # yellow define FOREGROUND_RED 0x0004 -- 0000 0100
|
||||
1, # blue define FOREGROUND_INTENSITY 0x0008 -- 0000 1000
|
||||
5, # magenta define BACKGROUND_BLUE 0x0010 -- 0001 0000
|
||||
3, # cyan define BACKGROUND_GREEN 0x0020 -- 0010 0000
|
||||
7, # white define BACKGROUND_RED 0x0040 -- 0100 0000
|
||||
8, # bright black (grey) define BACKGROUND_INTENSITY 0x0080 -- 1000 0000
|
||||
12, # bright red
|
||||
10, # bright green
|
||||
14, # bright yellow
|
||||
9, # bright blue
|
||||
13, # bright magenta
|
||||
11, # bright cyan
|
||||
15, # bright white
|
||||
]
|
||||
|
||||
def __init__(self, file: "IO[str]") -> None:
|
||||
handle = GetStdHandle(STDOUT)
|
||||
self._handle = handle
|
||||
default_text = GetConsoleScreenBufferInfo(handle).wAttributes
|
||||
self._default_text = default_text
|
||||
|
||||
self._default_fore = default_text & 7
|
||||
self._default_back = (default_text >> 4) & 7
|
||||
self._default_attrs = self._default_fore | (self._default_back << 4)
|
||||
|
||||
self._file = file
|
||||
self.write = file.write
|
||||
self.flush = file.flush
|
||||
|
||||
@property
|
||||
def cursor_position(self) -> WindowsCoordinates:
|
||||
"""Returns the current position of the cursor (0-based)
|
||||
|
||||
Returns:
|
||||
WindowsCoordinates: The current cursor position.
|
||||
"""
|
||||
coord: COORD = GetConsoleScreenBufferInfo(self._handle).dwCursorPosition
|
||||
return WindowsCoordinates(row=cast(int, coord.Y), col=cast(int, coord.X))
|
||||
|
||||
@property
|
||||
def screen_size(self) -> WindowsCoordinates:
|
||||
"""Returns the current size of the console screen buffer, in character columns and rows
|
||||
|
||||
Returns:
|
||||
WindowsCoordinates: The width and height of the screen as WindowsCoordinates.
|
||||
"""
|
||||
screen_size: COORD = GetConsoleScreenBufferInfo(self._handle).dwSize
|
||||
return WindowsCoordinates(
|
||||
row=cast(int, screen_size.Y), col=cast(int, screen_size.X)
|
||||
)
|
||||
|
||||
def write_text(self, text: str) -> None:
|
||||
"""Write text directly to the terminal without any modification of styles
|
||||
|
||||
Args:
|
||||
text (str): The text to write to the console
|
||||
"""
|
||||
self.write(text)
|
||||
self.flush()
|
||||
|
||||
def write_styled(self, text: str, style: Style) -> None:
|
||||
"""Write styled text to the terminal.
|
||||
|
||||
Args:
|
||||
text (str): The text to write
|
||||
style (Style): The style of the text
|
||||
"""
|
||||
color = style.color
|
||||
bgcolor = style.bgcolor
|
||||
if style.reverse:
|
||||
color, bgcolor = bgcolor, color
|
||||
|
||||
if color:
|
||||
fore = color.downgrade(ColorSystem.WINDOWS).number
|
||||
fore = fore if fore is not None else 7 # Default to ANSI 7: White
|
||||
if style.bold:
|
||||
fore = fore | self.BRIGHT_BIT
|
||||
if style.dim:
|
||||
fore = fore & ~self.BRIGHT_BIT
|
||||
fore = self.ANSI_TO_WINDOWS[fore]
|
||||
else:
|
||||
fore = self._default_fore
|
||||
|
||||
if bgcolor:
|
||||
back = bgcolor.downgrade(ColorSystem.WINDOWS).number
|
||||
back = back if back is not None else 0 # Default to ANSI 0: Black
|
||||
back = self.ANSI_TO_WINDOWS[back]
|
||||
else:
|
||||
back = self._default_back
|
||||
|
||||
assert fore is not None
|
||||
assert back is not None
|
||||
|
||||
SetConsoleTextAttribute(
|
||||
self._handle, attributes=ctypes.c_ushort(fore | (back << 4))
|
||||
)
|
||||
self.write_text(text)
|
||||
SetConsoleTextAttribute(self._handle, attributes=self._default_text)
|
||||
|
||||
def move_cursor_to(self, new_position: WindowsCoordinates) -> None:
|
||||
"""Set the position of the cursor
|
||||
|
||||
Args:
|
||||
new_position (WindowsCoordinates): The WindowsCoordinates representing the new position of the cursor.
|
||||
"""
|
||||
if new_position.col < 0 or new_position.row < 0:
|
||||
return
|
||||
SetConsoleCursorPosition(self._handle, coords=new_position)
|
||||
|
||||
def erase_line(self) -> None:
|
||||
"""Erase all content on the line the cursor is currently located at"""
|
||||
screen_size = self.screen_size
|
||||
cursor_position = self.cursor_position
|
||||
cells_to_erase = screen_size.col
|
||||
start_coordinates = WindowsCoordinates(row=cursor_position.row, col=0)
|
||||
FillConsoleOutputCharacter(
|
||||
self._handle, " ", length=cells_to_erase, start=start_coordinates
|
||||
)
|
||||
FillConsoleOutputAttribute(
|
||||
self._handle,
|
||||
self._default_attrs,
|
||||
length=cells_to_erase,
|
||||
start=start_coordinates,
|
||||
)
|
||||
|
||||
def erase_end_of_line(self) -> None:
|
||||
"""Erase all content from the cursor position to the end of that line"""
|
||||
cursor_position = self.cursor_position
|
||||
cells_to_erase = self.screen_size.col - cursor_position.col
|
||||
FillConsoleOutputCharacter(
|
||||
self._handle, " ", length=cells_to_erase, start=cursor_position
|
||||
)
|
||||
FillConsoleOutputAttribute(
|
||||
self._handle,
|
||||
self._default_attrs,
|
||||
length=cells_to_erase,
|
||||
start=cursor_position,
|
||||
)
|
||||
|
||||
def erase_start_of_line(self) -> None:
|
||||
"""Erase all content from the cursor position to the start of that line"""
|
||||
row, col = self.cursor_position
|
||||
start = WindowsCoordinates(row, 0)
|
||||
FillConsoleOutputCharacter(self._handle, " ", length=col, start=start)
|
||||
FillConsoleOutputAttribute(
|
||||
self._handle, self._default_attrs, length=col, start=start
|
||||
)
|
||||
|
||||
def move_cursor_up(self) -> None:
|
||||
"""Move the cursor up a single cell"""
|
||||
cursor_position = self.cursor_position
|
||||
SetConsoleCursorPosition(
|
||||
self._handle,
|
||||
coords=WindowsCoordinates(
|
||||
row=cursor_position.row - 1, col=cursor_position.col
|
||||
),
|
||||
)
|
||||
|
||||
def move_cursor_down(self) -> None:
|
||||
"""Move the cursor down a single cell"""
|
||||
cursor_position = self.cursor_position
|
||||
SetConsoleCursorPosition(
|
||||
self._handle,
|
||||
coords=WindowsCoordinates(
|
||||
row=cursor_position.row + 1,
|
||||
col=cursor_position.col,
|
||||
),
|
||||
)
|
||||
|
||||
def move_cursor_forward(self) -> None:
|
||||
"""Move the cursor forward a single cell. Wrap to the next line if required."""
|
||||
row, col = self.cursor_position
|
||||
if col == self.screen_size.col - 1:
|
||||
row += 1
|
||||
col = 0
|
||||
else:
|
||||
col += 1
|
||||
SetConsoleCursorPosition(
|
||||
self._handle, coords=WindowsCoordinates(row=row, col=col)
|
||||
)
|
||||
|
||||
def move_cursor_to_column(self, column: int) -> None:
|
||||
"""Move cursor to the column specified by the zero-based column index, staying on the same row
|
||||
|
||||
Args:
|
||||
column (int): The zero-based column index to move the cursor to.
|
||||
"""
|
||||
row, _ = self.cursor_position
|
||||
SetConsoleCursorPosition(self._handle, coords=WindowsCoordinates(row, column))
|
||||
|
||||
def move_cursor_backward(self) -> None:
|
||||
"""Move the cursor backward a single cell. Wrap to the previous line if required."""
|
||||
row, col = self.cursor_position
|
||||
if col == 0:
|
||||
row -= 1
|
||||
col = self.screen_size.col - 1
|
||||
else:
|
||||
col -= 1
|
||||
SetConsoleCursorPosition(
|
||||
self._handle, coords=WindowsCoordinates(row=row, col=col)
|
||||
)
|
||||
|
||||
def hide_cursor(self) -> None:
|
||||
"""Hide the cursor"""
|
||||
current_cursor_size = self._get_cursor_size()
|
||||
invisible_cursor = CONSOLE_CURSOR_INFO(dwSize=current_cursor_size, bVisible=0)
|
||||
SetConsoleCursorInfo(self._handle, cursor_info=invisible_cursor)
|
||||
|
||||
def show_cursor(self) -> None:
|
||||
"""Show the cursor"""
|
||||
current_cursor_size = self._get_cursor_size()
|
||||
visible_cursor = CONSOLE_CURSOR_INFO(dwSize=current_cursor_size, bVisible=1)
|
||||
SetConsoleCursorInfo(self._handle, cursor_info=visible_cursor)
|
||||
|
||||
def set_title(self, title: str) -> None:
|
||||
"""Set the title of the terminal window
|
||||
|
||||
Args:
|
||||
title (str): The new title of the console window
|
||||
"""
|
||||
assert len(title) < 255, "Console title must be less than 255 characters"
|
||||
SetConsoleTitle(title)
|
||||
|
||||
def _get_cursor_size(self) -> int:
|
||||
"""Get the percentage of the character cell that is filled by the cursor"""
|
||||
cursor_info = CONSOLE_CURSOR_INFO()
|
||||
GetConsoleCursorInfo(self._handle, cursor_info=cursor_info)
|
||||
return int(cursor_info.dwSize)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
handle = GetStdHandle()
|
||||
|
||||
from pip._vendor.rich.console import Console
|
||||
|
||||
console = Console()
|
||||
|
||||
term = LegacyWindowsTerm(sys.stdout)
|
||||
term.set_title("Win32 Console Examples")
|
||||
|
||||
style = Style(color="black", bgcolor="red")
|
||||
|
||||
heading = Style.parse("black on green")
|
||||
|
||||
# Check colour output
|
||||
console.rule("Checking colour output")
|
||||
console.print("[on red]on red!")
|
||||
console.print("[blue]blue!")
|
||||
console.print("[yellow]yellow!")
|
||||
console.print("[bold yellow]bold yellow!")
|
||||
console.print("[bright_yellow]bright_yellow!")
|
||||
console.print("[dim bright_yellow]dim bright_yellow!")
|
||||
console.print("[italic cyan]italic cyan!")
|
||||
console.print("[bold white on blue]bold white on blue!")
|
||||
console.print("[reverse bold white on blue]reverse bold white on blue!")
|
||||
console.print("[bold black on cyan]bold black on cyan!")
|
||||
console.print("[black on green]black on green!")
|
||||
console.print("[blue on green]blue on green!")
|
||||
console.print("[white on black]white on black!")
|
||||
console.print("[black on white]black on white!")
|
||||
console.print("[#1BB152 on #DA812D]#1BB152 on #DA812D!")
|
||||
|
||||
# Check cursor movement
|
||||
console.rule("Checking cursor movement")
|
||||
console.print()
|
||||
term.move_cursor_backward()
|
||||
term.move_cursor_backward()
|
||||
term.write_text("went back and wrapped to prev line")
|
||||
time.sleep(1)
|
||||
term.move_cursor_up()
|
||||
term.write_text("we go up")
|
||||
time.sleep(1)
|
||||
term.move_cursor_down()
|
||||
term.write_text("and down")
|
||||
time.sleep(1)
|
||||
term.move_cursor_up()
|
||||
term.move_cursor_backward()
|
||||
term.move_cursor_backward()
|
||||
term.write_text("we went up and back 2")
|
||||
time.sleep(1)
|
||||
term.move_cursor_down()
|
||||
term.move_cursor_backward()
|
||||
term.move_cursor_backward()
|
||||
term.write_text("we went down and back 2")
|
||||
time.sleep(1)
|
||||
|
||||
# Check erasing of lines
|
||||
term.hide_cursor()
|
||||
console.print()
|
||||
console.rule("Checking line erasing")
|
||||
console.print("\n...Deleting to the start of the line...")
|
||||
term.write_text("The red arrow shows the cursor location, and direction of erase")
|
||||
time.sleep(1)
|
||||
term.move_cursor_to_column(16)
|
||||
term.write_styled("<", Style.parse("black on red"))
|
||||
term.move_cursor_backward()
|
||||
time.sleep(1)
|
||||
term.erase_start_of_line()
|
||||
time.sleep(1)
|
||||
|
||||
console.print("\n\n...And to the end of the line...")
|
||||
term.write_text("The red arrow shows the cursor location, and direction of erase")
|
||||
time.sleep(1)
|
||||
|
||||
term.move_cursor_to_column(16)
|
||||
term.write_styled(">", Style.parse("black on red"))
|
||||
time.sleep(1)
|
||||
term.erase_end_of_line()
|
||||
time.sleep(1)
|
||||
|
||||
console.print("\n\n...Now the whole line will be erased...")
|
||||
term.write_styled("I'm going to disappear!", style=Style.parse("black on cyan"))
|
||||
time.sleep(1)
|
||||
term.erase_line()
|
||||
|
||||
term.show_cursor()
|
||||
print("\n")
|
|
@ -0,0 +1,72 @@
|
|||
import sys
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowsConsoleFeatures:
|
||||
"""Windows features available."""
|
||||
|
||||
vt: bool = False
|
||||
"""The console supports VT codes."""
|
||||
truecolor: bool = False
|
||||
"""The console supports truecolor."""
|
||||
|
||||
|
||||
try:
|
||||
import ctypes
|
||||
from ctypes import LibraryLoader
|
||||
|
||||
if sys.platform == "win32":
|
||||
windll = LibraryLoader(ctypes.WinDLL)
|
||||
else:
|
||||
windll = None
|
||||
raise ImportError("Not windows")
|
||||
|
||||
from pip._vendor.rich._win32_console import (
|
||||
ENABLE_VIRTUAL_TERMINAL_PROCESSING,
|
||||
GetConsoleMode,
|
||||
GetStdHandle,
|
||||
LegacyWindowsError,
|
||||
)
|
||||
|
||||
except (AttributeError, ImportError, ValueError):
|
||||
|
||||
# Fallback if we can't load the Windows DLL
|
||||
def get_windows_console_features() -> WindowsConsoleFeatures:
|
||||
features = WindowsConsoleFeatures()
|
||||
return features
|
||||
|
||||
else:
|
||||
|
||||
def get_windows_console_features() -> WindowsConsoleFeatures:
|
||||
"""Get windows console features.
|
||||
|
||||
Returns:
|
||||
WindowsConsoleFeatures: An instance of WindowsConsoleFeatures.
|
||||
"""
|
||||
handle = GetStdHandle()
|
||||
try:
|
||||
console_mode = GetConsoleMode(handle)
|
||||
success = True
|
||||
except LegacyWindowsError:
|
||||
console_mode = 0
|
||||
success = False
|
||||
vt = bool(success and console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
truecolor = False
|
||||
if vt:
|
||||
win_version = sys.getwindowsversion()
|
||||
truecolor = win_version.major > 10 or (
|
||||
win_version.major == 10 and win_version.build >= 15063
|
||||
)
|
||||
features = WindowsConsoleFeatures(vt=vt, truecolor=truecolor)
|
||||
return features
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import platform
|
||||
|
||||
features = get_windows_console_features()
|
||||
from pip._vendor.rich import print
|
||||
|
||||
print(f'platform="{platform.system()}"')
|
||||
print(repr(features))
|
|
@ -0,0 +1,56 @@
|
|||
from typing import Iterable, Sequence, Tuple, cast
|
||||
|
||||
from pip._vendor.rich._win32_console import LegacyWindowsTerm, WindowsCoordinates
|
||||
from pip._vendor.rich.segment import ControlCode, ControlType, Segment
|
||||
|
||||
|
||||
def legacy_windows_render(buffer: Iterable[Segment], term: LegacyWindowsTerm) -> None:
|
||||
"""Makes appropriate Windows Console API calls based on the segments in the buffer.
|
||||
|
||||
Args:
|
||||
buffer (Iterable[Segment]): Iterable of Segments to convert to Win32 API calls.
|
||||
term (LegacyWindowsTerm): Used to call the Windows Console API.
|
||||
"""
|
||||
for text, style, control in buffer:
|
||||
if not control:
|
||||
if style:
|
||||
term.write_styled(text, style)
|
||||
else:
|
||||
term.write_text(text)
|
||||
else:
|
||||
control_codes: Sequence[ControlCode] = control
|
||||
for control_code in control_codes:
|
||||
control_type = control_code[0]
|
||||
if control_type == ControlType.CURSOR_MOVE_TO:
|
||||
_, x, y = cast(Tuple[ControlType, int, int], control_code)
|
||||
term.move_cursor_to(WindowsCoordinates(row=y - 1, col=x - 1))
|
||||
elif control_type == ControlType.CARRIAGE_RETURN:
|
||||
term.write_text("\r")
|
||||
elif control_type == ControlType.HOME:
|
||||
term.move_cursor_to(WindowsCoordinates(0, 0))
|
||||
elif control_type == ControlType.CURSOR_UP:
|
||||
term.move_cursor_up()
|
||||
elif control_type == ControlType.CURSOR_DOWN:
|
||||
term.move_cursor_down()
|
||||
elif control_type == ControlType.CURSOR_FORWARD:
|
||||
term.move_cursor_forward()
|
||||
elif control_type == ControlType.CURSOR_BACKWARD:
|
||||
term.move_cursor_backward()
|
||||
elif control_type == ControlType.CURSOR_MOVE_TO_COLUMN:
|
||||
_, column = cast(Tuple[ControlType, int], control_code)
|
||||
term.move_cursor_to_column(column - 1)
|
||||
elif control_type == ControlType.HIDE_CURSOR:
|
||||
term.hide_cursor()
|
||||
elif control_type == ControlType.SHOW_CURSOR:
|
||||
term.show_cursor()
|
||||
elif control_type == ControlType.ERASE_IN_LINE:
|
||||
_, mode = cast(Tuple[ControlType, int], control_code)
|
||||
if mode == 0:
|
||||
term.erase_end_of_line()
|
||||
elif mode == 1:
|
||||
term.erase_start_of_line()
|
||||
elif mode == 2:
|
||||
term.erase_line()
|
||||
elif control_type == ControlType.SET_WINDOW_TITLE:
|
||||
_, title = cast(Tuple[ControlType, str], control_code)
|
||||
term.set_title(title)
|
56
venv/lib/python3.11/site-packages/pip/_vendor/rich/_wrap.py
Normal file
56
venv/lib/python3.11/site-packages/pip/_vendor/rich/_wrap.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
import re
|
||||
from typing import Iterable, List, Tuple
|
||||
|
||||
from ._loop import loop_last
|
||||
from .cells import cell_len, chop_cells
|
||||
|
||||
re_word = re.compile(r"\s*\S+\s*")
|
||||
|
||||
|
||||
def words(text: str) -> Iterable[Tuple[int, int, str]]:
|
||||
position = 0
|
||||
word_match = re_word.match(text, position)
|
||||
while word_match is not None:
|
||||
start, end = word_match.span()
|
||||
word = word_match.group(0)
|
||||
yield start, end, word
|
||||
word_match = re_word.match(text, end)
|
||||
|
||||
|
||||
def divide_line(text: str, width: int, fold: bool = True) -> List[int]:
|
||||
divides: List[int] = []
|
||||
append = divides.append
|
||||
line_position = 0
|
||||
_cell_len = cell_len
|
||||
for start, _end, word in words(text):
|
||||
word_length = _cell_len(word.rstrip())
|
||||
if line_position + word_length > width:
|
||||
if word_length > width:
|
||||
if fold:
|
||||
chopped_words = chop_cells(word, max_size=width, position=0)
|
||||
for last, line in loop_last(chopped_words):
|
||||
if start:
|
||||
append(start)
|
||||
|
||||
if last:
|
||||
line_position = _cell_len(line)
|
||||
else:
|
||||
start += len(line)
|
||||
else:
|
||||
if start:
|
||||
append(start)
|
||||
line_position = _cell_len(word)
|
||||
elif line_position and start:
|
||||
append(start)
|
||||
line_position = _cell_len(word)
|
||||
else:
|
||||
line_position += _cell_len(word)
|
||||
return divides
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from .console import Console
|
||||
|
||||
console = Console(width=10)
|
||||
console.print("12345 abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ 12345")
|
||||
print(chop_cells("abcdefghijklmnopqrstuvwxyz", 10, position=2))
|
33
venv/lib/python3.11/site-packages/pip/_vendor/rich/abc.py
Normal file
33
venv/lib/python3.11/site-packages/pip/_vendor/rich/abc.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
from abc import ABC
|
||||
|
||||
|
||||
class RichRenderable(ABC):
|
||||
"""An abstract base class for Rich renderables.
|
||||
|
||||
Note that there is no need to extend this class, the intended use is to check if an
|
||||
object supports the Rich renderable protocol. For example::
|
||||
|
||||
if isinstance(my_object, RichRenderable):
|
||||
console.print(my_object)
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def __subclasshook__(cls, other: type) -> bool:
|
||||
"""Check if this class supports the rich render protocol."""
|
||||
return hasattr(other, "__rich_console__") or hasattr(other, "__rich__")
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from pip._vendor.rich.text import Text
|
||||
|
||||
t = Text()
|
||||
print(isinstance(Text, RichRenderable))
|
||||
print(isinstance(t, RichRenderable))
|
||||
|
||||
class Foo:
|
||||
pass
|
||||
|
||||
f = Foo()
|
||||
print(isinstance(f, RichRenderable))
|
||||
print(isinstance("", RichRenderable))
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue