init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
172
.venv/lib/python3.8/site-packages/pip/_vendor/rich/__init__.py
Normal file
172
.venv/lib/python3.8/site-packages/pip/_vendor/rich/__init__.py
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
"""Rich text and beautiful formatting in the terminal."""
|
||||
|
||||
import os
|
||||
from typing import Callable, IO, TYPE_CHECKING, Any, Optional
|
||||
|
||||
from ._extension import load_ipython_extension
|
||||
|
||||
__all__ = ["get_console", "reconfigure", "print", "inspect"]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .console import Console
|
||||
|
||||
# Global console used by alternative print
|
||||
_console: Optional["Console"] = None
|
||||
|
||||
_IMPORT_CWD = os.path.abspath(os.getcwd())
|
||||
|
||||
|
||||
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:
|
||||
console (Console): Replacement console instance.
|
||||
"""
|
||||
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: int = 2,
|
||||
highlight: bool = True,
|
||||
skip_keys: bool = False,
|
||||
ensure_ascii: bool = True,
|
||||
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**")
|
||||
280
.venv/lib/python3.8/site-packages/pip/_vendor/rich/__main__.py
Normal file
280
.venv/lib/python3.8/site-packages/pip/_vendor/rich/__main__.py
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
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 yellow]256[/] colors or [bold green]16.7 million[/] colors [blue](if supported by your terminal)[/].",
|
||||
(
|
||||
"✓ [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)
|
||||
|
||||
text = console.file.getvalue()
|
||||
# https://bugs.python.org/issue37871
|
||||
for line in text.splitlines(True):
|
||||
print(line, end="")
|
||||
|
||||
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(
|
||||
"Buy devs a :coffee:",
|
||||
"[u blue link=https://ko-fi.com/textualize]https://ko-fi.com/textualize",
|
||||
)
|
||||
sponsor_message.add_row(
|
||||
"Twitter",
|
||||
"[u blue link=https://twitter.com/willmcgugan]https://twitter.com/willmcgugan",
|
||||
)
|
||||
sponsor_message.add_row(
|
||||
"Blog", "[u blue link=https://www.willmcgugan.com]https://www.willmcgugan.com"
|
||||
)
|
||||
|
||||
intro_message = Text.from_markup(
|
||||
"""\
|
||||
We hope you enjoy using Rich!
|
||||
|
||||
Rich is maintained with :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.
|
|
@ -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.8/site-packages/pip/_vendor/rich/_emoji_codes.py
Normal file
3610
.venv/lib/python3.8/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,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()
|
||||
210
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_inspect.py
Normal file
210
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_inspect.py
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from inspect import cleandoc, getdoc, getfile, isclass, ismodule, signature
|
||||
from typing import Any, Iterable, Optional, Tuple
|
||||
|
||||
from .console import RenderableType, Group
|
||||
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
|
||||
|
||||
|
||||
def _reformat_doc(doc: str) -> str:
|
||||
"""Reformat docstring."""
|
||||
doc = cleandoc(doc).strip()
|
||||
return doc
|
||||
|
||||
|
||||
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 TypeError:
|
||||
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)
|
||||
qual_signature = Text.assemble(
|
||||
("def ", "inspect.def"), (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 = getdoc(obj)
|
||||
if _doc is not None:
|
||||
if not self.help:
|
||||
_doc = _first_paragraph(_doc)
|
||||
doc_text = Text(_reformat_doc(_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 = getdoc(value)
|
||||
if docs is not None:
|
||||
_doc = _reformat_doc(str(docs))
|
||||
if not self.help:
|
||||
_doc = _first_paragraph(_doc)
|
||||
_signature_text.append("\n" if "\n" in _doc else " ")
|
||||
doc = highlighter(_doc)
|
||||
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
|
||||
else:
|
||||
yield Text.from_markup(
|
||||
f"[b cyan]{not_shown_count}[/][i] attribute(s) not shown.[/i] Run [b][magenta]inspect[/]([not b]inspect[/])[/b] for options."
|
||||
)
|
||||
|
|
@ -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.8/site-packages/pip/_vendor/rich/_loop.py
Normal file
43
.venv/lib/python3.8/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,34 @@
|
|||
from collections import OrderedDict
|
||||
from typing import Dict, Generic, TypeVar
|
||||
|
||||
|
||||
CacheKey = TypeVar("CacheKey")
|
||||
CacheValue = TypeVar("CacheValue")
|
||||
|
||||
|
||||
class LRUCache(Generic[CacheKey, CacheValue], OrderedDict): # type: ignore # https://github.com/python/mypy/issues/6904
|
||||
"""
|
||||
A dictionary-like container that stores a given maximum items.
|
||||
|
||||
If an additional item is added when the LRUCache is full, the least
|
||||
recently used key is discarded to make room for the new item.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, cache_size: int) -> None:
|
||||
self.cache_size = cache_size
|
||||
super(LRUCache, self).__init__()
|
||||
|
||||
def __setitem__(self, key: CacheKey, value: CacheValue) -> None:
|
||||
"""Store a new views, potentially discarding an old value."""
|
||||
if key not in self:
|
||||
if len(self) >= self.cache_size:
|
||||
self.popitem(last=False)
|
||||
OrderedDict.__setitem__(self, key, value)
|
||||
|
||||
def __getitem__(self: Dict[CacheKey, CacheValue], key: CacheKey) -> CacheValue:
|
||||
"""Gets the item, but also makes it most recent."""
|
||||
value: CacheValue = OrderedDict.__getitem__(self, key)
|
||||
OrderedDict.__delitem__(self, key)
|
||||
OrderedDict.__setitem__(self, key, value)
|
||||
return value
|
||||
309
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_palettes.py
Normal file
309
.venv/lib/python3.8/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.8/site-packages/pip/_vendor/rich/_pick.py
Normal file
17
.venv/lib/python3.8/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.8/site-packages/pip/_vendor/rich/_ratio.py
Normal file
160
.venv/lib/python3.8/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))
|
||||
848
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_spinners.py
Normal file
848
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_spinners.py
Normal file
|
|
@ -0,0 +1,848 @@
|
|||
"""
|
||||
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": [" ", ".", "o", "O", "@", "*", " "]},
|
||||
"balloon2": {"interval": 120, "frames": [".", "o", "O", "°", "O", "o", "."]},
|
||||
"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": ["d", "q", "p", "b"]},
|
||||
"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.8/site-packages/pip/_vendor/rich/_stack.py
Normal file
16
.venv/lib/python3.8/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.8/site-packages/pip/_vendor/rich/_timer.py
Normal file
19
.venv/lib/python3.8/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,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, wintypes
|
||||
|
||||
if sys.platform == "win32":
|
||||
windll = LibraryLoader(ctypes.WinDLL)
|
||||
else:
|
||||
windll = None
|
||||
raise ImportError("Not windows")
|
||||
except (AttributeError, ImportError, ValueError):
|
||||
|
||||
# Fallback if we can't load the Windows DLL
|
||||
def get_windows_console_features() -> WindowsConsoleFeatures:
|
||||
features = WindowsConsoleFeatures()
|
||||
return features
|
||||
|
||||
else:
|
||||
|
||||
STDOUT = -11
|
||||
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
|
||||
_GetConsoleMode = windll.kernel32.GetConsoleMode
|
||||
_GetConsoleMode.argtypes = [wintypes.HANDLE, wintypes.LPDWORD]
|
||||
_GetConsoleMode.restype = wintypes.BOOL
|
||||
|
||||
_GetStdHandle = windll.kernel32.GetStdHandle
|
||||
_GetStdHandle.argtypes = [
|
||||
wintypes.DWORD,
|
||||
]
|
||||
_GetStdHandle.restype = wintypes.HANDLE
|
||||
|
||||
def get_windows_console_features() -> WindowsConsoleFeatures:
|
||||
"""Get windows console features.
|
||||
|
||||
Returns:
|
||||
WindowsConsoleFeatures: An instance of WindowsConsoleFeatures.
|
||||
"""
|
||||
handle = _GetStdHandle(STDOUT)
|
||||
console_mode = wintypes.DWORD()
|
||||
result = _GetConsoleMode(handle, console_mode)
|
||||
vt = bool(result and console_mode.value & 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))
|
||||
55
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_wrap.py
Normal file
55
.venv/lib/python3.8/site-packages/pip/_vendor/rich/_wrap.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import re
|
||||
from typing import Iterable, List, Tuple
|
||||
|
||||
from .cells import cell_len, chop_cells
|
||||
from ._loop import loop_last
|
||||
|
||||
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:
|
||||
for last, line in loop_last(
|
||||
chop_cells(word, width, position=line_position)
|
||||
):
|
||||
if last:
|
||||
line_position = _cell_len(line)
|
||||
else:
|
||||
start += len(line)
|
||||
append(start)
|
||||
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.8/site-packages/pip/_vendor/rich/abc.py
Normal file
33
.venv/lib/python3.8/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))
|
||||
312
.venv/lib/python3.8/site-packages/pip/_vendor/rich/align.py
Normal file
312
.venv/lib/python3.8/site-packages/pip/_vendor/rich/align.py
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
import sys
|
||||
from itertools import chain
|
||||
from typing import TYPE_CHECKING, Iterable, Optional
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
from typing import Literal
|
||||
else:
|
||||
from pip._vendor.typing_extensions import Literal # pragma: no cover
|
||||
|
||||
from .constrain import Constrain
|
||||
from .jupyter import JupyterMixin
|
||||
from .measure import Measurement
|
||||
from .segment import Segment
|
||||
from .style import StyleType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .console import Console, ConsoleOptions, RenderableType, RenderResult
|
||||
|
||||
AlignMethod = Literal["left", "center", "right"]
|
||||
VerticalAlignMethod = Literal["top", "middle", "bottom"]
|
||||
AlignValues = AlignMethod # TODO: deprecate AlignValues
|
||||
|
||||
|
||||
class Align(JupyterMixin):
|
||||
"""Align a renderable by adding spaces if necessary.
|
||||
|
||||
Args:
|
||||
renderable (RenderableType): A console renderable.
|
||||
align (AlignMethod): One of "left", "center", or "right""
|
||||
style (StyleType, optional): An optional style to apply to the background.
|
||||
vertical (Optional[VerticalAlginMethod], optional): Optional vertical align, one of "top", "middle", or "bottom". Defaults to None.
|
||||
pad (bool, optional): Pad the right with spaces. Defaults to True.
|
||||
width (int, optional): Restrict contents to given width, or None to use default width. Defaults to None.
|
||||
height (int, optional): Set height of align renderable, or None to fit to contents. Defaults to None.
|
||||
|
||||
Raises:
|
||||
ValueError: if ``align`` is not one of the expected values.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
renderable: "RenderableType",
|
||||
align: AlignMethod = "left",
|
||||
style: Optional[StyleType] = None,
|
||||
*,
|
||||
vertical: Optional[VerticalAlignMethod] = None,
|
||||
pad: bool = True,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
) -> None:
|
||||
if align not in ("left", "center", "right"):
|
||||
raise ValueError(
|
||||
f'invalid value for align, expected "left", "center", or "right" (not {align!r})'
|
||||
)
|
||||
if vertical is not None and vertical not in ("top", "middle", "bottom"):
|
||||
raise ValueError(
|
||||
f'invalid value for vertical, expected "top", "middle", or "bottom" (not {vertical!r})'
|
||||
)
|
||||
self.renderable = renderable
|
||||
self.align = align
|
||||
self.style = style
|
||||
self.vertical = vertical
|
||||
self.pad = pad
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Align({self.renderable!r}, {self.align!r})"
|
||||
|
||||
@classmethod
|
||||
def left(
|
||||
cls,
|
||||
renderable: "RenderableType",
|
||||
style: Optional[StyleType] = None,
|
||||
*,
|
||||
vertical: Optional[VerticalAlignMethod] = None,
|
||||
pad: bool = True,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
) -> "Align":
|
||||
"""Align a renderable to the left."""
|
||||
return cls(
|
||||
renderable,
|
||||
"left",
|
||||
style=style,
|
||||
vertical=vertical,
|
||||
pad=pad,
|
||||
width=width,
|
||||
height=height,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def center(
|
||||
cls,
|
||||
renderable: "RenderableType",
|
||||
style: Optional[StyleType] = None,
|
||||
*,
|
||||
vertical: Optional[VerticalAlignMethod] = None,
|
||||
pad: bool = True,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
) -> "Align":
|
||||
"""Align a renderable to the center."""
|
||||
return cls(
|
||||
renderable,
|
||||
"center",
|
||||
style=style,
|
||||
vertical=vertical,
|
||||
pad=pad,
|
||||
width=width,
|
||||
height=height,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def right(
|
||||
cls,
|
||||
renderable: "RenderableType",
|
||||
style: Optional[StyleType] = None,
|
||||
*,
|
||||
vertical: Optional[VerticalAlignMethod] = None,
|
||||
pad: bool = True,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
) -> "Align":
|
||||
"""Align a renderable to the right."""
|
||||
return cls(
|
||||
renderable,
|
||||
"right",
|
||||
style=style,
|
||||
vertical=vertical,
|
||||
pad=pad,
|
||||
width=width,
|
||||
height=height,
|
||||
)
|
||||
|
||||
def __rich_console__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> "RenderResult":
|
||||
align = self.align
|
||||
width = console.measure(self.renderable, options=options).maximum
|
||||
rendered = console.render(
|
||||
Constrain(
|
||||
self.renderable, width if self.width is None else min(width, self.width)
|
||||
),
|
||||
options.update(height=None),
|
||||
)
|
||||
lines = list(Segment.split_lines(rendered))
|
||||
width, height = Segment.get_shape(lines)
|
||||
lines = Segment.set_shape(lines, width, height)
|
||||
new_line = Segment.line()
|
||||
excess_space = options.max_width - width
|
||||
style = console.get_style(self.style) if self.style is not None else None
|
||||
|
||||
def generate_segments() -> Iterable[Segment]:
|
||||
if excess_space <= 0:
|
||||
# Exact fit
|
||||
for line in lines:
|
||||
yield from line
|
||||
yield new_line
|
||||
|
||||
elif align == "left":
|
||||
# Pad on the right
|
||||
pad = Segment(" " * excess_space, style) if self.pad else None
|
||||
for line in lines:
|
||||
yield from line
|
||||
if pad:
|
||||
yield pad
|
||||
yield new_line
|
||||
|
||||
elif align == "center":
|
||||
# Pad left and right
|
||||
left = excess_space // 2
|
||||
pad = Segment(" " * left, style)
|
||||
pad_right = (
|
||||
Segment(" " * (excess_space - left), style) if self.pad else None
|
||||
)
|
||||
for line in lines:
|
||||
if left:
|
||||
yield pad
|
||||
yield from line
|
||||
if pad_right:
|
||||
yield pad_right
|
||||
yield new_line
|
||||
|
||||
elif align == "right":
|
||||
# Padding on left
|
||||
pad = Segment(" " * excess_space, style)
|
||||
for line in lines:
|
||||
yield pad
|
||||
yield from line
|
||||
yield new_line
|
||||
|
||||
blank_line = (
|
||||
Segment(f"{' ' * (self.width or options.max_width)}\n", style)
|
||||
if self.pad
|
||||
else Segment("\n")
|
||||
)
|
||||
|
||||
def blank_lines(count: int) -> Iterable[Segment]:
|
||||
if count > 0:
|
||||
for _ in range(count):
|
||||
yield blank_line
|
||||
|
||||
vertical_height = self.height or options.height
|
||||
iter_segments: Iterable[Segment]
|
||||
if self.vertical and vertical_height is not None:
|
||||
if self.vertical == "top":
|
||||
bottom_space = vertical_height - height
|
||||
iter_segments = chain(generate_segments(), blank_lines(bottom_space))
|
||||
elif self.vertical == "middle":
|
||||
top_space = (vertical_height - height) // 2
|
||||
bottom_space = vertical_height - top_space - height
|
||||
iter_segments = chain(
|
||||
blank_lines(top_space),
|
||||
generate_segments(),
|
||||
blank_lines(bottom_space),
|
||||
)
|
||||
else: # self.vertical == "bottom":
|
||||
top_space = vertical_height - height
|
||||
iter_segments = chain(blank_lines(top_space), generate_segments())
|
||||
else:
|
||||
iter_segments = generate_segments()
|
||||
if self.style:
|
||||
style = console.get_style(self.style)
|
||||
iter_segments = Segment.apply_style(iter_segments, style)
|
||||
yield from iter_segments
|
||||
|
||||
def __rich_measure__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> Measurement:
|
||||
measurement = Measurement.get(console, options, self.renderable)
|
||||
return measurement
|
||||
|
||||
|
||||
class VerticalCenter(JupyterMixin):
|
||||
"""Vertically aligns a renderable.
|
||||
|
||||
Warn:
|
||||
This class is deprecated and may be removed in a future version. Use Align class with
|
||||
`vertical="middle"`.
|
||||
|
||||
Args:
|
||||
renderable (RenderableType): A renderable object.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
renderable: "RenderableType",
|
||||
style: Optional[StyleType] = None,
|
||||
) -> None:
|
||||
self.renderable = renderable
|
||||
self.style = style
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"VerticalCenter({self.renderable!r})"
|
||||
|
||||
def __rich_console__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> "RenderResult":
|
||||
style = console.get_style(self.style) if self.style is not None else None
|
||||
lines = console.render_lines(
|
||||
self.renderable, options.update(height=None), pad=False
|
||||
)
|
||||
width, _height = Segment.get_shape(lines)
|
||||
new_line = Segment.line()
|
||||
height = options.height or options.size.height
|
||||
top_space = (height - len(lines)) // 2
|
||||
bottom_space = height - top_space - len(lines)
|
||||
blank_line = Segment(f"{' ' * width}", style)
|
||||
|
||||
def blank_lines(count: int) -> Iterable[Segment]:
|
||||
for _ in range(count):
|
||||
yield blank_line
|
||||
yield new_line
|
||||
|
||||
if top_space > 0:
|
||||
yield from blank_lines(top_space)
|
||||
for line in lines:
|
||||
yield from line
|
||||
yield new_line
|
||||
if bottom_space > 0:
|
||||
yield from blank_lines(bottom_space)
|
||||
|
||||
def __rich_measure__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> Measurement:
|
||||
measurement = Measurement.get(console, options, self.renderable)
|
||||
return measurement
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from pip._vendor.rich.console import Console, Group
|
||||
from pip._vendor.rich.highlighter import ReprHighlighter
|
||||
from pip._vendor.rich.panel import Panel
|
||||
|
||||
highlighter = ReprHighlighter()
|
||||
console = Console()
|
||||
|
||||
panel = Panel(
|
||||
Group(
|
||||
Align.left(highlighter("align='left'")),
|
||||
Align.center(highlighter("align='center'")),
|
||||
Align.right(highlighter("align='right'")),
|
||||
),
|
||||
width=60,
|
||||
style="on dark_blue",
|
||||
title="Algin",
|
||||
)
|
||||
|
||||
console.print(
|
||||
Align.center(panel, vertical="middle", style="on red", height=console.height)
|
||||
)
|
||||
228
.venv/lib/python3.8/site-packages/pip/_vendor/rich/ansi.py
Normal file
228
.venv/lib/python3.8/site-packages/pip/_vendor/rich/ansi.py
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
from contextlib import suppress
|
||||
import re
|
||||
from typing import Iterable, NamedTuple
|
||||
|
||||
from .color import Color
|
||||
from .style import Style
|
||||
from .text import Text
|
||||
|
||||
re_ansi = re.compile(r"(?:\x1b\[(.*?)m)|(?:\x1b\](.*?)\x1b\\)")
|
||||
re_csi = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
||||
|
||||
|
||||
class _AnsiToken(NamedTuple):
|
||||
"""Result of ansi tokenized string."""
|
||||
|
||||
plain: str = ""
|
||||
sgr: str = ""
|
||||
osc: str = ""
|
||||
|
||||
|
||||
def _ansi_tokenize(ansi_text: str) -> Iterable[_AnsiToken]:
|
||||
"""Tokenize a string in to plain text and ANSI codes.
|
||||
|
||||
Args:
|
||||
ansi_text (str): A String containing ANSI codes.
|
||||
|
||||
Yields:
|
||||
AnsiToken: A named tuple of (plain, sgr, osc)
|
||||
"""
|
||||
|
||||
def remove_csi(ansi_text: str) -> str:
|
||||
"""Remove unknown CSI sequences."""
|
||||
return re_csi.sub("", ansi_text)
|
||||
|
||||
position = 0
|
||||
for match in re_ansi.finditer(ansi_text):
|
||||
start, end = match.span(0)
|
||||
sgr, osc = match.groups()
|
||||
if start > position:
|
||||
yield _AnsiToken(remove_csi(ansi_text[position:start]))
|
||||
yield _AnsiToken("", sgr, osc)
|
||||
position = end
|
||||
if position < len(ansi_text):
|
||||
yield _AnsiToken(remove_csi(ansi_text[position:]))
|
||||
|
||||
|
||||
SGR_STYLE_MAP = {
|
||||
1: "bold",
|
||||
2: "dim",
|
||||
3: "italic",
|
||||
4: "underline",
|
||||
5: "blink",
|
||||
6: "blink2",
|
||||
7: "reverse",
|
||||
8: "conceal",
|
||||
9: "strike",
|
||||
21: "underline2",
|
||||
22: "not dim not bold",
|
||||
23: "not italic",
|
||||
24: "not underline",
|
||||
25: "not blink",
|
||||
26: "not blink2",
|
||||
27: "not reverse",
|
||||
28: "not conceal",
|
||||
29: "not strike",
|
||||
30: "color(0)",
|
||||
31: "color(1)",
|
||||
32: "color(2)",
|
||||
33: "color(3)",
|
||||
34: "color(4)",
|
||||
35: "color(5)",
|
||||
36: "color(6)",
|
||||
37: "color(7)",
|
||||
39: "default",
|
||||
40: "on color(0)",
|
||||
41: "on color(1)",
|
||||
42: "on color(2)",
|
||||
43: "on color(3)",
|
||||
44: "on color(4)",
|
||||
45: "on color(5)",
|
||||
46: "on color(6)",
|
||||
47: "on color(7)",
|
||||
49: "on default",
|
||||
51: "frame",
|
||||
52: "encircle",
|
||||
53: "overline",
|
||||
54: "not frame not encircle",
|
||||
55: "not overline",
|
||||
90: "color(8)",
|
||||
91: "color(9)",
|
||||
92: "color(10)",
|
||||
93: "color(11)",
|
||||
94: "color(12)",
|
||||
95: "color(13)",
|
||||
96: "color(14)",
|
||||
97: "color(15)",
|
||||
100: "on color(8)",
|
||||
101: "on color(9)",
|
||||
102: "on color(10)",
|
||||
103: "on color(11)",
|
||||
104: "on color(12)",
|
||||
105: "on color(13)",
|
||||
106: "on color(14)",
|
||||
107: "on color(15)",
|
||||
}
|
||||
|
||||
|
||||
class AnsiDecoder:
|
||||
"""Translate ANSI code in to styled Text."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.style = Style.null()
|
||||
|
||||
def decode(self, terminal_text: str) -> Iterable[Text]:
|
||||
"""Decode ANSI codes in an interable of lines.
|
||||
|
||||
Args:
|
||||
lines (Iterable[str]): An iterable of lines of terminal output.
|
||||
|
||||
Yields:
|
||||
Text: Marked up Text.
|
||||
"""
|
||||
for line in terminal_text.splitlines():
|
||||
yield self.decode_line(line)
|
||||
|
||||
def decode_line(self, line: str) -> Text:
|
||||
"""Decode a line containing ansi codes.
|
||||
|
||||
Args:
|
||||
line (str): A line of terminal output.
|
||||
|
||||
Returns:
|
||||
Text: A Text instance marked up according to ansi codes.
|
||||
"""
|
||||
from_ansi = Color.from_ansi
|
||||
from_rgb = Color.from_rgb
|
||||
_Style = Style
|
||||
text = Text()
|
||||
append = text.append
|
||||
line = line.rsplit("\r", 1)[-1]
|
||||
for token in _ansi_tokenize(line):
|
||||
plain_text, sgr, osc = token
|
||||
if plain_text:
|
||||
append(plain_text, self.style or None)
|
||||
elif osc:
|
||||
if osc.startswith("8;"):
|
||||
_params, semicolon, link = osc[2:].partition(";")
|
||||
if semicolon:
|
||||
self.style = self.style.update_link(link or None)
|
||||
elif sgr:
|
||||
# Translate in to semi-colon separated codes
|
||||
# Ignore invalid codes, because we want to be lenient
|
||||
codes = [
|
||||
min(255, int(_code)) for _code in sgr.split(";") if _code.isdigit()
|
||||
]
|
||||
iter_codes = iter(codes)
|
||||
for code in iter_codes:
|
||||
if code == 0:
|
||||
# reset
|
||||
self.style = _Style.null()
|
||||
elif code in SGR_STYLE_MAP:
|
||||
# styles
|
||||
self.style += _Style.parse(SGR_STYLE_MAP[code])
|
||||
elif code == 38:
|
||||
# Foreground
|
||||
with suppress(StopIteration):
|
||||
color_type = next(iter_codes)
|
||||
if color_type == 5:
|
||||
self.style += _Style.from_color(
|
||||
from_ansi(next(iter_codes))
|
||||
)
|
||||
elif color_type == 2:
|
||||
self.style += _Style.from_color(
|
||||
from_rgb(
|
||||
next(iter_codes),
|
||||
next(iter_codes),
|
||||
next(iter_codes),
|
||||
)
|
||||
)
|
||||
elif code == 48:
|
||||
# Background
|
||||
with suppress(StopIteration):
|
||||
color_type = next(iter_codes)
|
||||
if color_type == 5:
|
||||
self.style += _Style.from_color(
|
||||
None, from_ansi(next(iter_codes))
|
||||
)
|
||||
elif color_type == 2:
|
||||
self.style += _Style.from_color(
|
||||
None,
|
||||
from_rgb(
|
||||
next(iter_codes),
|
||||
next(iter_codes),
|
||||
next(iter_codes),
|
||||
),
|
||||
)
|
||||
|
||||
return text
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
import pty
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
|
||||
decoder = AnsiDecoder()
|
||||
|
||||
stdout = io.BytesIO()
|
||||
|
||||
def read(fd: int) -> bytes:
|
||||
data = os.read(fd, 1024)
|
||||
stdout.write(data)
|
||||
return data
|
||||
|
||||
pty.spawn(sys.argv[1:], read)
|
||||
|
||||
from .console import Console
|
||||
|
||||
console = Console(record=True)
|
||||
|
||||
stdout_result = stdout.getvalue().decode("utf-8")
|
||||
print(stdout_result)
|
||||
|
||||
for line in decoder.decode(stdout_result):
|
||||
console.print(line)
|
||||
|
||||
console.save_html("stdout.html")
|
||||
94
.venv/lib/python3.8/site-packages/pip/_vendor/rich/bar.py
Normal file
94
.venv/lib/python3.8/site-packages/pip/_vendor/rich/bar.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
from typing import Optional, Union
|
||||
|
||||
from .color import Color
|
||||
from .console import Console, ConsoleOptions, RenderResult
|
||||
from .jupyter import JupyterMixin
|
||||
from .measure import Measurement
|
||||
from .segment import Segment
|
||||
from .style import Style
|
||||
|
||||
# There are left-aligned characters for 1/8 to 7/8, but
|
||||
# the right-aligned characters exist only for 1/8 and 4/8.
|
||||
BEGIN_BLOCK_ELEMENTS = ["█", "█", "█", "▐", "▐", "▐", "▕", "▕"]
|
||||
END_BLOCK_ELEMENTS = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉"]
|
||||
FULL_BLOCK = "█"
|
||||
|
||||
|
||||
class Bar(JupyterMixin):
|
||||
"""Renders a solid block bar.
|
||||
|
||||
Args:
|
||||
size (float): Value for the end of the bar.
|
||||
begin (float): Begin point (between 0 and size, inclusive).
|
||||
end (float): End point (between 0 and size, inclusive).
|
||||
width (int, optional): Width of the bar, or ``None`` for maximum width. Defaults to None.
|
||||
color (Union[Color, str], optional): Color of the bar. Defaults to "default".
|
||||
bgcolor (Union[Color, str], optional): Color of bar background. Defaults to "default".
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
size: float,
|
||||
begin: float,
|
||||
end: float,
|
||||
*,
|
||||
width: Optional[int] = None,
|
||||
color: Union[Color, str] = "default",
|
||||
bgcolor: Union[Color, str] = "default",
|
||||
):
|
||||
self.size = size
|
||||
self.begin = max(begin, 0)
|
||||
self.end = min(end, size)
|
||||
self.width = width
|
||||
self.style = Style(color=color, bgcolor=bgcolor)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Bar({self.size}, {self.begin}, {self.end})"
|
||||
|
||||
def __rich_console__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
|
||||
width = min(
|
||||
self.width if self.width is not None else options.max_width,
|
||||
options.max_width,
|
||||
)
|
||||
|
||||
if self.begin >= self.end:
|
||||
yield Segment(" " * width, self.style)
|
||||
yield Segment.line()
|
||||
return
|
||||
|
||||
prefix_complete_eights = int(width * 8 * self.begin / self.size)
|
||||
prefix_bar_count = prefix_complete_eights // 8
|
||||
prefix_eights_count = prefix_complete_eights % 8
|
||||
|
||||
body_complete_eights = int(width * 8 * self.end / self.size)
|
||||
body_bar_count = body_complete_eights // 8
|
||||
body_eights_count = body_complete_eights % 8
|
||||
|
||||
# When start and end fall into the same cell, we ideally should render
|
||||
# a symbol that's "center-aligned", but there is no good symbol in Unicode.
|
||||
# In this case, we fall back to right-aligned block symbol for simplicity.
|
||||
|
||||
prefix = " " * prefix_bar_count
|
||||
if prefix_eights_count:
|
||||
prefix += BEGIN_BLOCK_ELEMENTS[prefix_eights_count]
|
||||
|
||||
body = FULL_BLOCK * body_bar_count
|
||||
if body_eights_count:
|
||||
body += END_BLOCK_ELEMENTS[body_eights_count]
|
||||
|
||||
suffix = " " * (width - len(body))
|
||||
|
||||
yield Segment(prefix + body[len(prefix) :] + suffix, self.style)
|
||||
yield Segment.line()
|
||||
|
||||
def __rich_measure__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> Measurement:
|
||||
return (
|
||||
Measurement(self.width, self.width)
|
||||
if self.width is not None
|
||||
else Measurement(4, options.max_width)
|
||||
)
|
||||
483
.venv/lib/python3.8/site-packages/pip/_vendor/rich/box.py
Normal file
483
.venv/lib/python3.8/site-packages/pip/_vendor/rich/box.py
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
import sys
|
||||
from typing import TYPE_CHECKING, Iterable, List
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
from typing import Literal
|
||||
else:
|
||||
from pip._vendor.typing_extensions import Literal # pragma: no cover
|
||||
|
||||
|
||||
from ._loop import loop_last
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pip._vendor.rich.console import ConsoleOptions
|
||||
|
||||
|
||||
class Box:
|
||||
"""Defines characters to render boxes.
|
||||
|
||||
┌─┬┐ top
|
||||
│ ││ head
|
||||
├─┼┤ head_row
|
||||
│ ││ mid
|
||||
├─┼┤ row
|
||||
├─┼┤ foot_row
|
||||
│ ││ foot
|
||||
└─┴┘ bottom
|
||||
|
||||
Args:
|
||||
box (str): Characters making up box.
|
||||
ascii (bool, optional): True if this box uses ascii characters only. Default is False.
|
||||
"""
|
||||
|
||||
def __init__(self, box: str, *, ascii: bool = False) -> None:
|
||||
self._box = box
|
||||
self.ascii = ascii
|
||||
line1, line2, line3, line4, line5, line6, line7, line8 = box.splitlines()
|
||||
# top
|
||||
self.top_left, self.top, self.top_divider, self.top_right = iter(line1)
|
||||
# head
|
||||
self.head_left, _, self.head_vertical, self.head_right = iter(line2)
|
||||
# head_row
|
||||
(
|
||||
self.head_row_left,
|
||||
self.head_row_horizontal,
|
||||
self.head_row_cross,
|
||||
self.head_row_right,
|
||||
) = iter(line3)
|
||||
|
||||
# mid
|
||||
self.mid_left, _, self.mid_vertical, self.mid_right = iter(line4)
|
||||
# row
|
||||
self.row_left, self.row_horizontal, self.row_cross, self.row_right = iter(line5)
|
||||
# foot_row
|
||||
(
|
||||
self.foot_row_left,
|
||||
self.foot_row_horizontal,
|
||||
self.foot_row_cross,
|
||||
self.foot_row_right,
|
||||
) = iter(line6)
|
||||
# foot
|
||||
self.foot_left, _, self.foot_vertical, self.foot_right = iter(line7)
|
||||
# bottom
|
||||
self.bottom_left, self.bottom, self.bottom_divider, self.bottom_right = iter(
|
||||
line8
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "Box(...)"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._box
|
||||
|
||||
def substitute(self, options: "ConsoleOptions", safe: bool = True) -> "Box":
|
||||
"""Substitute this box for another if it won't render due to platform issues.
|
||||
|
||||
Args:
|
||||
options (ConsoleOptions): Console options used in rendering.
|
||||
safe (bool, optional): Substitute this for another Box if there are known problems
|
||||
displaying on the platform (currently only relevant on Windows). Default is True.
|
||||
|
||||
Returns:
|
||||
Box: A different Box or the same Box.
|
||||
"""
|
||||
box = self
|
||||
if options.legacy_windows and safe:
|
||||
box = LEGACY_WINDOWS_SUBSTITUTIONS.get(box, box)
|
||||
if options.ascii_only and not box.ascii:
|
||||
box = ASCII
|
||||
return box
|
||||
|
||||
def get_top(self, widths: Iterable[int]) -> str:
|
||||
"""Get the top of a simple box.
|
||||
|
||||
Args:
|
||||
widths (List[int]): Widths of columns.
|
||||
|
||||
Returns:
|
||||
str: A string of box characters.
|
||||
"""
|
||||
|
||||
parts: List[str] = []
|
||||
append = parts.append
|
||||
append(self.top_left)
|
||||
for last, width in loop_last(widths):
|
||||
append(self.top * width)
|
||||
if not last:
|
||||
append(self.top_divider)
|
||||
append(self.top_right)
|
||||
return "".join(parts)
|
||||
|
||||
def get_row(
|
||||
self,
|
||||
widths: Iterable[int],
|
||||
level: Literal["head", "row", "foot", "mid"] = "row",
|
||||
edge: bool = True,
|
||||
) -> str:
|
||||
"""Get the top of a simple box.
|
||||
|
||||
Args:
|
||||
width (List[int]): Widths of columns.
|
||||
|
||||
Returns:
|
||||
str: A string of box characters.
|
||||
"""
|
||||
if level == "head":
|
||||
left = self.head_row_left
|
||||
horizontal = self.head_row_horizontal
|
||||
cross = self.head_row_cross
|
||||
right = self.head_row_right
|
||||
elif level == "row":
|
||||
left = self.row_left
|
||||
horizontal = self.row_horizontal
|
||||
cross = self.row_cross
|
||||
right = self.row_right
|
||||
elif level == "mid":
|
||||
left = self.mid_left
|
||||
horizontal = " "
|
||||
cross = self.mid_vertical
|
||||
right = self.mid_right
|
||||
elif level == "foot":
|
||||
left = self.foot_row_left
|
||||
horizontal = self.foot_row_horizontal
|
||||
cross = self.foot_row_cross
|
||||
right = self.foot_row_right
|
||||
else:
|
||||
raise ValueError("level must be 'head', 'row' or 'foot'")
|
||||
|
||||
parts: List[str] = []
|
||||
append = parts.append
|
||||
if edge:
|
||||
append(left)
|
||||
for last, width in loop_last(widths):
|
||||
append(horizontal * width)
|
||||
if not last:
|
||||
append(cross)
|
||||
if edge:
|
||||
append(right)
|
||||
return "".join(parts)
|
||||
|
||||
def get_bottom(self, widths: Iterable[int]) -> str:
|
||||
"""Get the bottom of a simple box.
|
||||
|
||||
Args:
|
||||
widths (List[int]): Widths of columns.
|
||||
|
||||
Returns:
|
||||
str: A string of box characters.
|
||||
"""
|
||||
|
||||
parts: List[str] = []
|
||||
append = parts.append
|
||||
append(self.bottom_left)
|
||||
for last, width in loop_last(widths):
|
||||
append(self.bottom * width)
|
||||
if not last:
|
||||
append(self.bottom_divider)
|
||||
append(self.bottom_right)
|
||||
return "".join(parts)
|
||||
|
||||
|
||||
ASCII: Box = Box(
|
||||
"""\
|
||||
+--+
|
||||
| ||
|
||||
|-+|
|
||||
| ||
|
||||
|-+|
|
||||
|-+|
|
||||
| ||
|
||||
+--+
|
||||
""",
|
||||
ascii=True,
|
||||
)
|
||||
|
||||
ASCII2: Box = Box(
|
||||
"""\
|
||||
+-++
|
||||
| ||
|
||||
+-++
|
||||
| ||
|
||||
+-++
|
||||
+-++
|
||||
| ||
|
||||
+-++
|
||||
""",
|
||||
ascii=True,
|
||||
)
|
||||
|
||||
ASCII_DOUBLE_HEAD: Box = Box(
|
||||
"""\
|
||||
+-++
|
||||
| ||
|
||||
+=++
|
||||
| ||
|
||||
+-++
|
||||
+-++
|
||||
| ||
|
||||
+-++
|
||||
""",
|
||||
ascii=True,
|
||||
)
|
||||
|
||||
SQUARE: Box = Box(
|
||||
"""\
|
||||
┌─┬┐
|
||||
│ ││
|
||||
├─┼┤
|
||||
│ ││
|
||||
├─┼┤
|
||||
├─┼┤
|
||||
│ ││
|
||||
└─┴┘
|
||||
"""
|
||||
)
|
||||
|
||||
SQUARE_DOUBLE_HEAD: Box = Box(
|
||||
"""\
|
||||
┌─┬┐
|
||||
│ ││
|
||||
╞═╪╡
|
||||
│ ││
|
||||
├─┼┤
|
||||
├─┼┤
|
||||
│ ││
|
||||
└─┴┘
|
||||
"""
|
||||
)
|
||||
|
||||
MINIMAL: Box = Box(
|
||||
"""\
|
||||
╷
|
||||
│
|
||||
╶─┼╴
|
||||
│
|
||||
╶─┼╴
|
||||
╶─┼╴
|
||||
│
|
||||
╵
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_HEAVY_HEAD: Box = Box(
|
||||
"""\
|
||||
╷
|
||||
│
|
||||
╺━┿╸
|
||||
│
|
||||
╶─┼╴
|
||||
╶─┼╴
|
||||
│
|
||||
╵
|
||||
"""
|
||||
)
|
||||
|
||||
MINIMAL_DOUBLE_HEAD: Box = Box(
|
||||
"""\
|
||||
╷
|
||||
│
|
||||
═╪
|
||||
│
|
||||
─┼
|
||||
─┼
|
||||
│
|
||||
╵
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
SIMPLE: Box = Box(
|
||||
"""\
|
||||
|
||||
|
||||
──
|
||||
|
||||
|
||||
──
|
||||
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
SIMPLE_HEAD: Box = Box(
|
||||
"""\
|
||||
|
||||
|
||||
──
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
SIMPLE_HEAVY: Box = Box(
|
||||
"""\
|
||||
|
||||
|
||||
━━
|
||||
|
||||
|
||||
━━
|
||||
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
HORIZONTALS: Box = Box(
|
||||
"""\
|
||||
──
|
||||
|
||||
──
|
||||
|
||||
──
|
||||
──
|
||||
|
||||
──
|
||||
"""
|
||||
)
|
||||
|
||||
ROUNDED: Box = Box(
|
||||
"""\
|
||||
╭─┬╮
|
||||
│ ││
|
||||
├─┼┤
|
||||
│ ││
|
||||
├─┼┤
|
||||
├─┼┤
|
||||
│ ││
|
||||
╰─┴╯
|
||||
"""
|
||||
)
|
||||
|
||||
HEAVY: Box = Box(
|
||||
"""\
|
||||
┏━┳┓
|
||||
┃ ┃┃
|
||||
┣━╋┫
|
||||
┃ ┃┃
|
||||
┣━╋┫
|
||||
┣━╋┫
|
||||
┃ ┃┃
|
||||
┗━┻┛
|
||||
"""
|
||||
)
|
||||
|
||||
HEAVY_EDGE: Box = Box(
|
||||
"""\
|
||||
┏━┯┓
|
||||
┃ │┃
|
||||
┠─┼┨
|
||||
┃ │┃
|
||||
┠─┼┨
|
||||
┠─┼┨
|
||||
┃ │┃
|
||||
┗━┷┛
|
||||
"""
|
||||
)
|
||||
|
||||
HEAVY_HEAD: Box = Box(
|
||||
"""\
|
||||
┏━┳┓
|
||||
┃ ┃┃
|
||||
┡━╇┩
|
||||
│ ││
|
||||
├─┼┤
|
||||
├─┼┤
|
||||
│ ││
|
||||
└─┴┘
|
||||
"""
|
||||
)
|
||||
|
||||
DOUBLE: Box = Box(
|
||||
"""\
|
||||
╔═╦╗
|
||||
║ ║║
|
||||
╠═╬╣
|
||||
║ ║║
|
||||
╠═╬╣
|
||||
╠═╬╣
|
||||
║ ║║
|
||||
╚═╩╝
|
||||
"""
|
||||
)
|
||||
|
||||
DOUBLE_EDGE: Box = Box(
|
||||
"""\
|
||||
╔═╤╗
|
||||
║ │║
|
||||
╟─┼╢
|
||||
║ │║
|
||||
╟─┼╢
|
||||
╟─┼╢
|
||||
║ │║
|
||||
╚═╧╝
|
||||
"""
|
||||
)
|
||||
|
||||
# Map Boxes that don't render with raster fonts on to equivalent that do
|
||||
LEGACY_WINDOWS_SUBSTITUTIONS = {
|
||||
ROUNDED: SQUARE,
|
||||
MINIMAL_HEAVY_HEAD: MINIMAL,
|
||||
SIMPLE_HEAVY: SIMPLE,
|
||||
HEAVY: SQUARE,
|
||||
HEAVY_EDGE: SQUARE,
|
||||
HEAVY_HEAD: SQUARE,
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
|
||||
from pip._vendor.rich.columns import Columns
|
||||
from pip._vendor.rich.panel import Panel
|
||||
|
||||
from . import box as box
|
||||
from .console import Console
|
||||
from .table import Table
|
||||
from .text import Text
|
||||
|
||||
console = Console(record=True)
|
||||
|
||||
BOXES = [
|
||||
"ASCII",
|
||||
"ASCII2",
|
||||
"ASCII_DOUBLE_HEAD",
|
||||
"SQUARE",
|
||||
"SQUARE_DOUBLE_HEAD",
|
||||
"MINIMAL",
|
||||
"MINIMAL_HEAVY_HEAD",
|
||||
"MINIMAL_DOUBLE_HEAD",
|
||||
"SIMPLE",
|
||||
"SIMPLE_HEAD",
|
||||
"SIMPLE_HEAVY",
|
||||
"HORIZONTALS",
|
||||
"ROUNDED",
|
||||
"HEAVY",
|
||||
"HEAVY_EDGE",
|
||||
"HEAVY_HEAD",
|
||||
"DOUBLE",
|
||||
"DOUBLE_EDGE",
|
||||
]
|
||||
|
||||
console.print(Panel("[bold green]Box Constants", style="green"), justify="center")
|
||||
console.print()
|
||||
|
||||
columns = Columns(expand=True, padding=2)
|
||||
for box_name in sorted(BOXES):
|
||||
table = Table(
|
||||
show_footer=True, style="dim", border_style="not dim", expand=True
|
||||
)
|
||||
table.add_column("Header 1", "Footer 1")
|
||||
table.add_column("Header 2", "Footer 2")
|
||||
table.add_row("Cell", "Cell")
|
||||
table.add_row("Cell", "Cell")
|
||||
table.box = getattr(box, box_name)
|
||||
table.title = Text(f"box.{box_name}", style="magenta")
|
||||
columns.add_renderable(table)
|
||||
console.print(columns)
|
||||
|
||||
# console.save_html("box.html", inline_styles=True)
|
||||
147
.venv/lib/python3.8/site-packages/pip/_vendor/rich/cells.py
Normal file
147
.venv/lib/python3.8/site-packages/pip/_vendor/rich/cells.py
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
from functools import lru_cache
|
||||
import re
|
||||
from typing import Dict, List
|
||||
|
||||
from ._cell_widths import CELL_WIDTHS
|
||||
from ._lru_cache import LRUCache
|
||||
|
||||
# Regex to match sequence of the most common character ranges
|
||||
_is_single_cell_widths = re.compile("^[\u0020-\u006f\u00a0\u02ff\u0370-\u0482]*$").match
|
||||
|
||||
|
||||
def cell_len(text: str, _cache: Dict[str, int] = LRUCache(1024 * 4)) -> int:
|
||||
"""Get the number of cells required to display text.
|
||||
|
||||
Args:
|
||||
text (str): Text to display.
|
||||
|
||||
Returns:
|
||||
int: Get the number of cells required to display text.
|
||||
"""
|
||||
|
||||
if _is_single_cell_widths(text):
|
||||
return len(text)
|
||||
else:
|
||||
cached_result = _cache.get(text, None)
|
||||
if cached_result is not None:
|
||||
return cached_result
|
||||
_get_size = get_character_cell_size
|
||||
total_size = sum(_get_size(character) for character in text)
|
||||
if len(text) <= 64:
|
||||
_cache[text] = total_size
|
||||
return total_size
|
||||
|
||||
|
||||
@lru_cache(maxsize=4096)
|
||||
def get_character_cell_size(character: str) -> int:
|
||||
"""Get the cell size of a character.
|
||||
|
||||
Args:
|
||||
character (str): A single character.
|
||||
|
||||
Returns:
|
||||
int: Number of cells (0, 1 or 2) occupied by that character.
|
||||
"""
|
||||
if _is_single_cell_widths(character):
|
||||
return 1
|
||||
|
||||
return _get_codepoint_cell_size(ord(character))
|
||||
|
||||
|
||||
@lru_cache(maxsize=4096)
|
||||
def _get_codepoint_cell_size(codepoint: int) -> int:
|
||||
"""Get the cell size of a character.
|
||||
|
||||
Args:
|
||||
character (str): A single character.
|
||||
|
||||
Returns:
|
||||
int: Number of cells (0, 1 or 2) occupied by that character.
|
||||
"""
|
||||
|
||||
_table = CELL_WIDTHS
|
||||
lower_bound = 0
|
||||
upper_bound = len(_table) - 1
|
||||
index = (lower_bound + upper_bound) // 2
|
||||
while True:
|
||||
start, end, width = _table[index]
|
||||
if codepoint < start:
|
||||
upper_bound = index - 1
|
||||
elif codepoint > end:
|
||||
lower_bound = index + 1
|
||||
else:
|
||||
return 0 if width == -1 else width
|
||||
if upper_bound < lower_bound:
|
||||
break
|
||||
index = (lower_bound + upper_bound) // 2
|
||||
return 1
|
||||
|
||||
|
||||
def set_cell_size(text: str, total: int) -> str:
|
||||
"""Set the length of a string to fit within given number of cells."""
|
||||
|
||||
if _is_single_cell_widths(text):
|
||||
size = len(text)
|
||||
if size < total:
|
||||
return text + " " * (total - size)
|
||||
return text[:total]
|
||||
|
||||
if not total:
|
||||
return ""
|
||||
cell_size = cell_len(text)
|
||||
if cell_size == total:
|
||||
return text
|
||||
if cell_size < total:
|
||||
return text + " " * (total - cell_size)
|
||||
|
||||
start = 0
|
||||
end = len(text)
|
||||
|
||||
# Binary search until we find the right size
|
||||
while True:
|
||||
pos = (start + end) // 2
|
||||
before = text[: pos + 1]
|
||||
before_len = cell_len(before)
|
||||
if before_len == total + 1 and cell_len(before[-1]) == 2:
|
||||
return before[:-1] + " "
|
||||
if before_len == total:
|
||||
return before
|
||||
if before_len > total:
|
||||
end = pos
|
||||
else:
|
||||
start = pos
|
||||
|
||||
|
||||
# TODO: This is inefficient
|
||||
# TODO: This might not work with CWJ type characters
|
||||
def chop_cells(text: str, max_size: int, position: int = 0) -> List[str]:
|
||||
"""Break text in to equal (cell) length strings."""
|
||||
_get_character_cell_size = get_character_cell_size
|
||||
characters = [
|
||||
(character, _get_character_cell_size(character)) for character in text
|
||||
][::-1]
|
||||
total_size = position
|
||||
lines: List[List[str]] = [[]]
|
||||
append = lines[-1].append
|
||||
|
||||
pop = characters.pop
|
||||
while characters:
|
||||
character, size = pop()
|
||||
if total_size + size > max_size:
|
||||
lines.append([character])
|
||||
append = lines[-1].append
|
||||
total_size = size
|
||||
else:
|
||||
total_size += size
|
||||
append(character)
|
||||
return ["".join(line) for line in lines]
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
|
||||
print(get_character_cell_size("😽"))
|
||||
for line in chop_cells("""这是对亚洲语言支持的测试。面对模棱两可的想法,拒绝猜测的诱惑。""", 8):
|
||||
print(line)
|
||||
for n in range(80, 1, -1):
|
||||
print(set_cell_size("""这是对亚洲语言支持的测试。面对模棱两可的想法,拒绝猜测的诱惑。""", n) + "|")
|
||||
print("x" * n)
|
||||
581
.venv/lib/python3.8/site-packages/pip/_vendor/rich/color.py
Normal file
581
.venv/lib/python3.8/site-packages/pip/_vendor/rich/color.py
Normal file
|
|
@ -0,0 +1,581 @@
|
|||
import platform
|
||||
import re
|
||||
from colorsys import rgb_to_hls
|
||||
from enum import IntEnum
|
||||
from functools import lru_cache
|
||||
from typing import TYPE_CHECKING, NamedTuple, Optional, Tuple
|
||||
|
||||
from ._palettes import EIGHT_BIT_PALETTE, STANDARD_PALETTE, WINDOWS_PALETTE
|
||||
from .color_triplet import ColorTriplet
|
||||
from .repr import rich_repr, Result
|
||||
from .terminal_theme import DEFAULT_TERMINAL_THEME
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .terminal_theme import TerminalTheme
|
||||
from .text import Text
|
||||
|
||||
|
||||
WINDOWS = platform.system() == "Windows"
|
||||
|
||||
|
||||
class ColorSystem(IntEnum):
|
||||
"""One of the 3 color system supported by terminals."""
|
||||
|
||||
STANDARD = 1
|
||||
EIGHT_BIT = 2
|
||||
TRUECOLOR = 3
|
||||
WINDOWS = 4
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ColorSystem.{self.name}"
|
||||
|
||||
|
||||
class ColorType(IntEnum):
|
||||
"""Type of color stored in Color class."""
|
||||
|
||||
DEFAULT = 0
|
||||
STANDARD = 1
|
||||
EIGHT_BIT = 2
|
||||
TRUECOLOR = 3
|
||||
WINDOWS = 4
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ColorType.{self.name}"
|
||||
|
||||
|
||||
ANSI_COLOR_NAMES = {
|
||||
"black": 0,
|
||||
"red": 1,
|
||||
"green": 2,
|
||||
"yellow": 3,
|
||||
"blue": 4,
|
||||
"magenta": 5,
|
||||
"cyan": 6,
|
||||
"white": 7,
|
||||
"bright_black": 8,
|
||||
"bright_red": 9,
|
||||
"bright_green": 10,
|
||||
"bright_yellow": 11,
|
||||
"bright_blue": 12,
|
||||
"bright_magenta": 13,
|
||||
"bright_cyan": 14,
|
||||
"bright_white": 15,
|
||||
"grey0": 16,
|
||||
"navy_blue": 17,
|
||||
"dark_blue": 18,
|
||||
"blue3": 20,
|
||||
"blue1": 21,
|
||||
"dark_green": 22,
|
||||
"deep_sky_blue4": 25,
|
||||
"dodger_blue3": 26,
|
||||
"dodger_blue2": 27,
|
||||
"green4": 28,
|
||||
"spring_green4": 29,
|
||||
"turquoise4": 30,
|
||||
"deep_sky_blue3": 32,
|
||||
"dodger_blue1": 33,
|
||||
"green3": 40,
|
||||
"spring_green3": 41,
|
||||
"dark_cyan": 36,
|
||||
"light_sea_green": 37,
|
||||
"deep_sky_blue2": 38,
|
||||
"deep_sky_blue1": 39,
|
||||
"spring_green2": 47,
|
||||
"cyan3": 43,
|
||||
"dark_turquoise": 44,
|
||||
"turquoise2": 45,
|
||||
"green1": 46,
|
||||
"spring_green1": 48,
|
||||
"medium_spring_green": 49,
|
||||
"cyan2": 50,
|
||||
"cyan1": 51,
|
||||
"dark_red": 88,
|
||||
"deep_pink4": 125,
|
||||
"purple4": 55,
|
||||
"purple3": 56,
|
||||
"blue_violet": 57,
|
||||
"orange4": 94,
|
||||
"grey37": 59,
|
||||
"medium_purple4": 60,
|
||||
"slate_blue3": 62,
|
||||
"royal_blue1": 63,
|
||||
"chartreuse4": 64,
|
||||
"dark_sea_green4": 71,
|
||||
"pale_turquoise4": 66,
|
||||
"steel_blue": 67,
|
||||
"steel_blue3": 68,
|
||||
"cornflower_blue": 69,
|
||||
"chartreuse3": 76,
|
||||
"cadet_blue": 73,
|
||||
"sky_blue3": 74,
|
||||
"steel_blue1": 81,
|
||||
"pale_green3": 114,
|
||||
"sea_green3": 78,
|
||||
"aquamarine3": 79,
|
||||
"medium_turquoise": 80,
|
||||
"chartreuse2": 112,
|
||||
"sea_green2": 83,
|
||||
"sea_green1": 85,
|
||||
"aquamarine1": 122,
|
||||
"dark_slate_gray2": 87,
|
||||
"dark_magenta": 91,
|
||||
"dark_violet": 128,
|
||||
"purple": 129,
|
||||
"light_pink4": 95,
|
||||
"plum4": 96,
|
||||
"medium_purple3": 98,
|
||||
"slate_blue1": 99,
|
||||
"yellow4": 106,
|
||||
"wheat4": 101,
|
||||
"grey53": 102,
|
||||
"light_slate_grey": 103,
|
||||
"medium_purple": 104,
|
||||
"light_slate_blue": 105,
|
||||
"dark_olive_green3": 149,
|
||||
"dark_sea_green": 108,
|
||||
"light_sky_blue3": 110,
|
||||
"sky_blue2": 111,
|
||||
"dark_sea_green3": 150,
|
||||
"dark_slate_gray3": 116,
|
||||
"sky_blue1": 117,
|
||||
"chartreuse1": 118,
|
||||
"light_green": 120,
|
||||
"pale_green1": 156,
|
||||
"dark_slate_gray1": 123,
|
||||
"red3": 160,
|
||||
"medium_violet_red": 126,
|
||||
"magenta3": 164,
|
||||
"dark_orange3": 166,
|
||||
"indian_red": 167,
|
||||
"hot_pink3": 168,
|
||||
"medium_orchid3": 133,
|
||||
"medium_orchid": 134,
|
||||
"medium_purple2": 140,
|
||||
"dark_goldenrod": 136,
|
||||
"light_salmon3": 173,
|
||||
"rosy_brown": 138,
|
||||
"grey63": 139,
|
||||
"medium_purple1": 141,
|
||||
"gold3": 178,
|
||||
"dark_khaki": 143,
|
||||
"navajo_white3": 144,
|
||||
"grey69": 145,
|
||||
"light_steel_blue3": 146,
|
||||
"light_steel_blue": 147,
|
||||
"yellow3": 184,
|
||||
"dark_sea_green2": 157,
|
||||
"light_cyan3": 152,
|
||||
"light_sky_blue1": 153,
|
||||
"green_yellow": 154,
|
||||
"dark_olive_green2": 155,
|
||||
"dark_sea_green1": 193,
|
||||
"pale_turquoise1": 159,
|
||||
"deep_pink3": 162,
|
||||
"magenta2": 200,
|
||||
"hot_pink2": 169,
|
||||
"orchid": 170,
|
||||
"medium_orchid1": 207,
|
||||
"orange3": 172,
|
||||
"light_pink3": 174,
|
||||
"pink3": 175,
|
||||
"plum3": 176,
|
||||
"violet": 177,
|
||||
"light_goldenrod3": 179,
|
||||
"tan": 180,
|
||||
"misty_rose3": 181,
|
||||
"thistle3": 182,
|
||||
"plum2": 183,
|
||||
"khaki3": 185,
|
||||
"light_goldenrod2": 222,
|
||||
"light_yellow3": 187,
|
||||
"grey84": 188,
|
||||
"light_steel_blue1": 189,
|
||||
"yellow2": 190,
|
||||
"dark_olive_green1": 192,
|
||||
"honeydew2": 194,
|
||||
"light_cyan1": 195,
|
||||
"red1": 196,
|
||||
"deep_pink2": 197,
|
||||
"deep_pink1": 199,
|
||||
"magenta1": 201,
|
||||
"orange_red1": 202,
|
||||
"indian_red1": 204,
|
||||
"hot_pink": 206,
|
||||
"dark_orange": 208,
|
||||
"salmon1": 209,
|
||||
"light_coral": 210,
|
||||
"pale_violet_red1": 211,
|
||||
"orchid2": 212,
|
||||
"orchid1": 213,
|
||||
"orange1": 214,
|
||||
"sandy_brown": 215,
|
||||
"light_salmon1": 216,
|
||||
"light_pink1": 217,
|
||||
"pink1": 218,
|
||||
"plum1": 219,
|
||||
"gold1": 220,
|
||||
"navajo_white1": 223,
|
||||
"misty_rose1": 224,
|
||||
"thistle1": 225,
|
||||
"yellow1": 226,
|
||||
"light_goldenrod1": 227,
|
||||
"khaki1": 228,
|
||||
"wheat1": 229,
|
||||
"cornsilk1": 230,
|
||||
"grey100": 231,
|
||||
"grey3": 232,
|
||||
"grey7": 233,
|
||||
"grey11": 234,
|
||||
"grey15": 235,
|
||||
"grey19": 236,
|
||||
"grey23": 237,
|
||||
"grey27": 238,
|
||||
"grey30": 239,
|
||||
"grey35": 240,
|
||||
"grey39": 241,
|
||||
"grey42": 242,
|
||||
"grey46": 243,
|
||||
"grey50": 244,
|
||||
"grey54": 245,
|
||||
"grey58": 246,
|
||||
"grey62": 247,
|
||||
"grey66": 248,
|
||||
"grey70": 249,
|
||||
"grey74": 250,
|
||||
"grey78": 251,
|
||||
"grey82": 252,
|
||||
"grey85": 253,
|
||||
"grey89": 254,
|
||||
"grey93": 255,
|
||||
}
|
||||
|
||||
|
||||
class ColorParseError(Exception):
|
||||
"""The color could not be parsed."""
|
||||
|
||||
|
||||
RE_COLOR = re.compile(
|
||||
r"""^
|
||||
\#([0-9a-f]{6})$|
|
||||
color\(([0-9]{1,3})\)$|
|
||||
rgb\(([\d\s,]+)\)$
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
@rich_repr
|
||||
class Color(NamedTuple):
|
||||
"""Terminal color definition."""
|
||||
|
||||
name: str
|
||||
"""The name of the color (typically the input to Color.parse)."""
|
||||
type: ColorType
|
||||
"""The type of the color."""
|
||||
number: Optional[int] = None
|
||||
"""The color number, if a standard color, or None."""
|
||||
triplet: Optional[ColorTriplet] = None
|
||||
"""A triplet of color components, if an RGB color."""
|
||||
|
||||
def __rich__(self) -> "Text":
|
||||
"""Dispays the actual color if Rich printed."""
|
||||
from .text import Text
|
||||
from .style import Style
|
||||
|
||||
return Text.assemble(
|
||||
f"<color {self.name!r} ({self.type.name.lower()})",
|
||||
("⬤", Style(color=self)),
|
||||
" >",
|
||||
)
|
||||
|
||||
def __rich_repr__(self) -> Result:
|
||||
yield self.name
|
||||
yield self.type
|
||||
yield "number", self.number, None
|
||||
yield "triplet", self.triplet, None
|
||||
|
||||
@property
|
||||
def system(self) -> ColorSystem:
|
||||
"""Get the native color system for this color."""
|
||||
if self.type == ColorType.DEFAULT:
|
||||
return ColorSystem.STANDARD
|
||||
return ColorSystem(int(self.type))
|
||||
|
||||
@property
|
||||
def is_system_defined(self) -> bool:
|
||||
"""Check if the color is ultimately defined by the system."""
|
||||
return self.system not in (ColorSystem.EIGHT_BIT, ColorSystem.TRUECOLOR)
|
||||
|
||||
@property
|
||||
def is_default(self) -> bool:
|
||||
"""Check if the color is a default color."""
|
||||
return self.type == ColorType.DEFAULT
|
||||
|
||||
def get_truecolor(
|
||||
self, theme: Optional["TerminalTheme"] = None, foreground: bool = True
|
||||
) -> ColorTriplet:
|
||||
"""Get an equivalent color triplet for this color.
|
||||
|
||||
Args:
|
||||
theme (TerminalTheme, optional): Optional terminal theme, or None to use default. Defaults to None.
|
||||
foreground (bool, optional): True for a foreground color, or False for background. Defaults to True.
|
||||
|
||||
Returns:
|
||||
ColorTriplet: A color triplet containing RGB components.
|
||||
"""
|
||||
|
||||
if theme is None:
|
||||
theme = DEFAULT_TERMINAL_THEME
|
||||
if self.type == ColorType.TRUECOLOR:
|
||||
assert self.triplet is not None
|
||||
return self.triplet
|
||||
elif self.type == ColorType.EIGHT_BIT:
|
||||
assert self.number is not None
|
||||
return EIGHT_BIT_PALETTE[self.number]
|
||||
elif self.type == ColorType.STANDARD:
|
||||
assert self.number is not None
|
||||
return theme.ansi_colors[self.number]
|
||||
elif self.type == ColorType.WINDOWS:
|
||||
assert self.number is not None
|
||||
return WINDOWS_PALETTE[self.number]
|
||||
else: # self.type == ColorType.DEFAULT:
|
||||
assert self.number is None
|
||||
return theme.foreground_color if foreground else theme.background_color
|
||||
|
||||
@classmethod
|
||||
def from_ansi(cls, number: int) -> "Color":
|
||||
"""Create a Color number from it's 8-bit ansi number.
|
||||
|
||||
Args:
|
||||
number (int): A number between 0-255 inclusive.
|
||||
|
||||
Returns:
|
||||
Color: A new Color instance.
|
||||
"""
|
||||
return cls(
|
||||
name=f"color({number})",
|
||||
type=(ColorType.STANDARD if number < 16 else ColorType.EIGHT_BIT),
|
||||
number=number,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_triplet(cls, triplet: "ColorTriplet") -> "Color":
|
||||
"""Create a truecolor RGB color from a triplet of values.
|
||||
|
||||
Args:
|
||||
triplet (ColorTriplet): A color triplet containing red, green and blue components.
|
||||
|
||||
Returns:
|
||||
Color: A new color object.
|
||||
"""
|
||||
return cls(name=triplet.hex, type=ColorType.TRUECOLOR, triplet=triplet)
|
||||
|
||||
@classmethod
|
||||
def from_rgb(cls, red: float, green: float, blue: float) -> "Color":
|
||||
"""Create a truecolor from three color components in the range(0->255).
|
||||
|
||||
Args:
|
||||
red (float): Red component in range 0-255.
|
||||
green (float): Green component in range 0-255.
|
||||
blue (float): Blue component in range 0-255.
|
||||
|
||||
Returns:
|
||||
Color: A new color object.
|
||||
"""
|
||||
return cls.from_triplet(ColorTriplet(int(red), int(green), int(blue)))
|
||||
|
||||
@classmethod
|
||||
def default(cls) -> "Color":
|
||||
"""Get a Color instance representing the default color.
|
||||
|
||||
Returns:
|
||||
Color: Default color.
|
||||
"""
|
||||
return cls(name="default", type=ColorType.DEFAULT)
|
||||
|
||||
@classmethod
|
||||
@lru_cache(maxsize=1024)
|
||||
def parse(cls, color: str) -> "Color":
|
||||
"""Parse a color definition."""
|
||||
original_color = color
|
||||
color = color.lower().strip()
|
||||
|
||||
if color == "default":
|
||||
return cls(color, type=ColorType.DEFAULT)
|
||||
|
||||
color_number = ANSI_COLOR_NAMES.get(color)
|
||||
if color_number is not None:
|
||||
return cls(
|
||||
color,
|
||||
type=(ColorType.STANDARD if color_number < 16 else ColorType.EIGHT_BIT),
|
||||
number=color_number,
|
||||
)
|
||||
|
||||
color_match = RE_COLOR.match(color)
|
||||
if color_match is None:
|
||||
raise ColorParseError(f"{original_color!r} is not a valid color")
|
||||
|
||||
color_24, color_8, color_rgb = color_match.groups()
|
||||
if color_24:
|
||||
triplet = ColorTriplet(
|
||||
int(color_24[0:2], 16), int(color_24[2:4], 16), int(color_24[4:6], 16)
|
||||
)
|
||||
return cls(color, ColorType.TRUECOLOR, triplet=triplet)
|
||||
|
||||
elif color_8:
|
||||
number = int(color_8)
|
||||
if number > 255:
|
||||
raise ColorParseError(f"color number must be <= 255 in {color!r}")
|
||||
return cls(
|
||||
color,
|
||||
type=(ColorType.STANDARD if number < 16 else ColorType.EIGHT_BIT),
|
||||
number=number,
|
||||
)
|
||||
|
||||
else: # color_rgb:
|
||||
components = color_rgb.split(",")
|
||||
if len(components) != 3:
|
||||
raise ColorParseError(
|
||||
f"expected three components in {original_color!r}"
|
||||
)
|
||||
red, green, blue = components
|
||||
triplet = ColorTriplet(int(red), int(green), int(blue))
|
||||
if not all(component <= 255 for component in triplet):
|
||||
raise ColorParseError(
|
||||
f"color components must be <= 255 in {original_color!r}"
|
||||
)
|
||||
return cls(color, ColorType.TRUECOLOR, triplet=triplet)
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def get_ansi_codes(self, foreground: bool = True) -> Tuple[str, ...]:
|
||||
"""Get the ANSI escape codes for this color."""
|
||||
_type = self.type
|
||||
if _type == ColorType.DEFAULT:
|
||||
return ("39" if foreground else "49",)
|
||||
|
||||
elif _type == ColorType.WINDOWS:
|
||||
number = self.number
|
||||
assert number is not None
|
||||
fore, back = (30, 40) if number < 8 else (82, 92)
|
||||
return (str(fore + number if foreground else back + number),)
|
||||
|
||||
elif _type == ColorType.STANDARD:
|
||||
number = self.number
|
||||
assert number is not None
|
||||
fore, back = (30, 40) if number < 8 else (82, 92)
|
||||
return (str(fore + number if foreground else back + number),)
|
||||
|
||||
elif _type == ColorType.EIGHT_BIT:
|
||||
assert self.number is not None
|
||||
return ("38" if foreground else "48", "5", str(self.number))
|
||||
|
||||
else: # self.standard == ColorStandard.TRUECOLOR:
|
||||
assert self.triplet is not None
|
||||
red, green, blue = self.triplet
|
||||
return ("38" if foreground else "48", "2", str(red), str(green), str(blue))
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def downgrade(self, system: ColorSystem) -> "Color":
|
||||
"""Downgrade a color system to a system with fewer colors."""
|
||||
|
||||
if self.type in [ColorType.DEFAULT, system]:
|
||||
return self
|
||||
# Convert to 8-bit color from truecolor color
|
||||
if system == ColorSystem.EIGHT_BIT and self.system == ColorSystem.TRUECOLOR:
|
||||
assert self.triplet is not None
|
||||
red, green, blue = self.triplet.normalized
|
||||
_h, l, s = rgb_to_hls(red, green, blue)
|
||||
# If saturation is under 10% assume it is grayscale
|
||||
if s < 0.1:
|
||||
gray = round(l * 25.0)
|
||||
if gray == 0:
|
||||
color_number = 16
|
||||
elif gray == 25:
|
||||
color_number = 231
|
||||
else:
|
||||
color_number = 231 + gray
|
||||
return Color(self.name, ColorType.EIGHT_BIT, number=color_number)
|
||||
|
||||
color_number = (
|
||||
16 + 36 * round(red * 5.0) + 6 * round(green * 5.0) + round(blue * 5.0)
|
||||
)
|
||||
return Color(self.name, ColorType.EIGHT_BIT, number=color_number)
|
||||
|
||||
# Convert to standard from truecolor or 8-bit
|
||||
elif system == ColorSystem.STANDARD:
|
||||
if self.system == ColorSystem.TRUECOLOR:
|
||||
assert self.triplet is not None
|
||||
triplet = self.triplet
|
||||
else: # self.system == ColorSystem.EIGHT_BIT
|
||||
assert self.number is not None
|
||||
triplet = ColorTriplet(*EIGHT_BIT_PALETTE[self.number])
|
||||
|
||||
color_number = STANDARD_PALETTE.match(triplet)
|
||||
return Color(self.name, ColorType.STANDARD, number=color_number)
|
||||
|
||||
elif system == ColorSystem.WINDOWS:
|
||||
if self.system == ColorSystem.TRUECOLOR:
|
||||
assert self.triplet is not None
|
||||
triplet = self.triplet
|
||||
else: # self.system == ColorSystem.EIGHT_BIT
|
||||
assert self.number is not None
|
||||
if self.number < 16:
|
||||
return Color(self.name, ColorType.WINDOWS, number=self.number)
|
||||
triplet = ColorTriplet(*EIGHT_BIT_PALETTE[self.number])
|
||||
|
||||
color_number = WINDOWS_PALETTE.match(triplet)
|
||||
return Color(self.name, ColorType.WINDOWS, number=color_number)
|
||||
|
||||
return self
|
||||
|
||||
|
||||
def parse_rgb_hex(hex_color: str) -> ColorTriplet:
|
||||
"""Parse six hex characters in to RGB triplet."""
|
||||
assert len(hex_color) == 6, "must be 6 characters"
|
||||
color = ColorTriplet(
|
||||
int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16)
|
||||
)
|
||||
return color
|
||||
|
||||
|
||||
def blend_rgb(
|
||||
color1: ColorTriplet, color2: ColorTriplet, cross_fade: float = 0.5
|
||||
) -> ColorTriplet:
|
||||
"""Blend one RGB color in to another."""
|
||||
r1, g1, b1 = color1
|
||||
r2, g2, b2 = color2
|
||||
new_color = ColorTriplet(
|
||||
int(r1 + (r2 - r1) * cross_fade),
|
||||
int(g1 + (g2 - g1) * cross_fade),
|
||||
int(b1 + (b2 - b1) * cross_fade),
|
||||
)
|
||||
return new_color
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
|
||||
from .console import Console
|
||||
from .table import Table
|
||||
from .text import Text
|
||||
|
||||
console = Console()
|
||||
|
||||
table = Table(show_footer=False, show_edge=True)
|
||||
table.add_column("Color", width=10, overflow="ellipsis")
|
||||
table.add_column("Number", justify="right", style="yellow")
|
||||
table.add_column("Name", style="green")
|
||||
table.add_column("Hex", style="blue")
|
||||
table.add_column("RGB", style="magenta")
|
||||
|
||||
colors = sorted((v, k) for k, v in ANSI_COLOR_NAMES.items())
|
||||
for color_number, name in colors:
|
||||
color_cell = Text(" " * 10, style=f"on {name}")
|
||||
if color_number < 16:
|
||||
table.add_row(color_cell, f"{color_number}", Text(f'"{name}"'))
|
||||
else:
|
||||
color = EIGHT_BIT_PALETTE[color_number] # type: ignore
|
||||
table.add_row(
|
||||
color_cell, str(color_number), Text(f'"{name}"'), color.hex, color.rgb
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
from typing import NamedTuple, Tuple
|
||||
|
||||
|
||||
class ColorTriplet(NamedTuple):
|
||||
"""The red, green, and blue components of a color."""
|
||||
|
||||
red: int
|
||||
"""Red component in 0 to 255 range."""
|
||||
green: int
|
||||
"""Green component in 0 to 255 range."""
|
||||
blue: int
|
||||
"""Blue component in 0 to 255 range."""
|
||||
|
||||
@property
|
||||
def hex(self) -> str:
|
||||
"""get the color triplet in CSS style."""
|
||||
red, green, blue = self
|
||||
return f"#{red:02x}{green:02x}{blue:02x}"
|
||||
|
||||
@property
|
||||
def rgb(self) -> str:
|
||||
"""The color in RGB format.
|
||||
|
||||
Returns:
|
||||
str: An rgb color, e.g. ``"rgb(100,23,255)"``.
|
||||
"""
|
||||
red, green, blue = self
|
||||
return f"rgb({red},{green},{blue})"
|
||||
|
||||
@property
|
||||
def normalized(self) -> Tuple[float, float, float]:
|
||||
"""Convert components into floats between 0 and 1.
|
||||
|
||||
Returns:
|
||||
Tuple[float, float, float]: A tuple of three normalized colour components.
|
||||
"""
|
||||
red, green, blue = self
|
||||
return red / 255.0, green / 255.0, blue / 255.0
|
||||
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