Update documentation and code snippets

This commit is contained in:
2026-01-22 22:02:19 +03:00
parent f9a85da430
commit f27f7b135b
26 changed files with 301 additions and 160 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
from argenta import Command, Response, Router
from argenta.command.flag import InputFlag, InputFlags, ValidationStatus
from argenta.command.flag import InputFlag, ValidationStatus
from argenta.command import InputFlags
router = Router(title="Add Flag Example")
+2 -1
View File
@@ -1,4 +1,5 @@
from argenta.command.flag import InputFlag, InputFlags, ValidationStatus
from argenta.command.flag import InputFlag, ValidationStatus
from argenta.command import InputFlags
# Create InputFlags collection
flags = InputFlags()
+1 -1
View File
@@ -1,5 +1,5 @@
from argenta.command.flag import InputFlag, ValidationStatus
from argenta.command.flag.flags.models import InputFlags
from argenta.command import InputFlags
# Create first collection
flags1 = InputFlags(
@@ -1,7 +1,8 @@
from typing import cast
from argenta import Command, Response, Router
from argenta.command.flag import Flag, Flags, ValidationStatus
from argenta.command.flag import Flag, ValidationStatus
from argenta.command import Flags
from argenta.di import FromDishka
from .repository import Priority, Task, TaskRepository
+2 -3
View File
@@ -1,9 +1,8 @@
from argenta import App, Orchestrator
from argenta.app import StaticDividingLine
from .handlers import router
app = App(initial_message="metrics", prompt=">>> ", dividing_line=None)
app = App(initial_message="metrics")
orchestrator = Orchestrator()
+2 -1
View File
@@ -1,4 +1,5 @@
from .pre_cycle_setup import *
from .most_similar_command import *
from .finds_appropriate_handler import *
from .validate_routers_for_collisions import *
from .validate_routers_for_collisions import *
from .input_command_parse import *
+3
View File
@@ -160,3 +160,6 @@ class Benchmarks:
def get_benchmark_by_name(self, name: str) -> Benchmark | None:
return self._benchmarks_paired_by_name.get(name)
def get_types(self) -> set[str]:
return set(self._benchmarks_grouped_by_type.keys())
+51
View File
@@ -0,0 +1,51 @@
__all__ = [
"benchmark_parse_simple_command",
"benchmark_command_with_few_flags",
"benchmark_command_with_flags_and_values",
"benchmark_command_with_mixed_prefixes",
"benchmark_command_with_long_values",
"benchmark_command_with_quoted_values",
"benchmark_extreme_many_flags"
]
from argenta.command.models import InputCommand
from .entity import benchmarks
@benchmarks.register(type_="input_command_parse", description="Simple command (no flags)")
def benchmark_parse_simple_command() -> None:
InputCommand.parse("start")
@benchmarks.register(type_="input_command_parse", description="Command with few flags (3 flags)")
def benchmark_command_with_few_flags() -> None:
InputCommand.parse("start -a -b -c")
@benchmarks.register(type_="input_command_parse", description="Command with flags and values (5 flags)")
def benchmark_command_with_flags_and_values() -> None:
InputCommand.parse("start --host localhost --port 8080 --debug --verbose -c config.json")
@benchmarks.register(type_="input_command_parse", description="Command with mixed prefixes (-, --, ---)")
def benchmark_command_with_mixed_prefixes() -> None:
InputCommand.parse("cmd -a --bb ---ccc -d value --ee value2 ---fff value3")
@benchmarks.register(type_="input_command_parse", description="Command with long values (10 flags)")
def benchmark_command_with_long_values() -> None:
long_value = "a" * 100
cmd = f"process --data {long_value} --config {long_value} --output {long_value}"
InputCommand.parse(cmd)
@benchmarks.register(type_="input_command_parse", description="Command with quoted values (5 flags)")
def benchmark_command_with_quoted_values() -> None:
InputCommand.parse("cmd --text 'hello world' --path '/usr/local/bin' --msg \"test message\"")
@benchmarks.register(type_="input_command_parse", description="Extreme (50 flags with values)")
def benchmark_extreme_many_flags() -> None:
flags = " ".join(f"--flag{i} value{i}" for i in range(50))
InputCommand.parse(f"command {flags}")
+60 -4
View File
@@ -1,6 +1,7 @@
from rich.console import Console
from argenta.command import Flag, PossibleValues
from argenta.command import Flag, PossibleValues, Flags
from argenta.command.flag import ValidationStatus
from argenta.command.models import Command
from argenta.response import Response
from argenta.router import Router
@@ -15,22 +16,77 @@ router = Router(title="Metrics commands:")
@router.command(
Command(
"all-print",
"run-all",
description="Print all benchmarks results",
flags=Flag('without-gc', possible_values=PossibleValues.NEITHER)
)
)
def all_print_handler(_: Response) -> None:
def all_print_handler(response: Response) -> None:
report_generator = ReportGenerator(get_system_info())
console.print(report_generator.generate_system_info_header())
console.print(report_generator.generate_system_info_table())
is_gc_disabled = _.input_flags.get_flag_by_name("without-gc")
is_gc_disabled = response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID)
type_grouped_benchmarks: list[BenchmarkGroupResult] = registered_benchmarks.run_benchmarks_grouped_by_type(is_gc_disabled=is_gc_disabled)
for benchmark_group_result in type_grouped_benchmarks:
console.print(report_generator.generate_benchmark_table_header(benchmark_group_result))
console.print(report_generator.generate_benchmark_report_table(benchmark_group_result))
@router.command(Command("list-types", description="List all benchmark types"))
def list_types_handler(_: Response) -> None:
types = registered_benchmarks.get_types()
if not types:
console.print("[yellow]No benchmark types found[/yellow]")
return
console.print("[bold cyan]Available benchmark types:[/bold cyan]\n")
for type_ in types:
benchmarks_count = len(registered_benchmarks.get_benchmarks_by_type(type_))
console.print(f" [green]•[/green] [bold]{type_}[/bold] ({benchmarks_count} benchmarks)")
@router.command(
Command(
"run-type",
description="Run benchmarks by specific type",
flags=Flags([
Flag('type', possible_values=registered_benchmarks.get_types()),
Flag('without-gc', possible_values=PossibleValues.NEITHER)
])
)
)
def run_type_handler(response: Response) -> None:
type_flag = response.input_flags.get_flag_by_name("type")
if not type_flag:
console.print("[red]Error: --type flag is required[/red]")
console.print("[yellow]Usage: run-type --type <type_name>[/yellow]")
return
benchmark_type = type_flag.input_value
if not type_flag.status == ValidationStatus.VALID:
console.print(f"[red]Error: No benchmarks found for type '{benchmark_type}'[/red]")
console.print("\n[yellow]Available types:[/yellow]")
types = registered_benchmarks.get_types()
for t in types:
console.print(f"{t}")
return
report_generator = ReportGenerator(get_system_info())
console.print(report_generator.generate_system_info_header())
console.print(report_generator.generate_system_info_table())
is_gc_disabled = response.input_flags.get_flag_by_name("without-gc", with_status=ValidationStatus.VALID)
benchmark_group_result = registered_benchmarks.run_benchmarks_by_type(benchmark_type, is_gc_disabled=is_gc_disabled)
console.print(report_generator.generate_benchmark_table_header(benchmark_group_result))
console.print(report_generator.generate_benchmark_report_table(benchmark_group_result))
@router.command(Command("release-generate", description="Generate release report"))
def release_generate_handler(_: Response) -> None:
console.print("[yellow]Release report generation not implemented yet[/yellow]")
+1 -1
View File
@@ -6,7 +6,7 @@ work_router: Router = Router(title="Base points:", disable_redirect_stdout=True)
@work_router.command(
Command(
"hello",
"hello",
flags=Flags([
Flag("test")
]),
+4 -18
View File
@@ -187,7 +187,7 @@ class BaseApp:
)
)
elif isinstance(self._dividing_line, StaticDividingLine): # pyright: ignore[reportUnnecessaryIsInstance]
elif isinstance(self._dividing_line, StaticDividingLine):
self._print_func(
self._dividing_line.get_full_static_line(
is_override=self._override_system_messages
@@ -374,18 +374,7 @@ class BaseApp:
raise RuntimeError(f"Router for '{input_command.trigger}' not found. Panic!")
if processing_router.disable_redirect_stdout:
dividing_line_unit_part: str = self._dividing_line.get_unit_part()
self._print_func(
StaticDividingLine(dividing_line_unit_part).get_full_static_line(
is_override=self._override_system_messages
)
)
processing_router.finds_appropriate_handler(input_command)
self._print_func(
StaticDividingLine(dividing_line_unit_part).get_full_static_line(
is_override=self._override_system_messages
)
)
else:
stdout_result = self._capture_stdout(
lambda: processing_router.finds_appropriate_handler(input_command)
@@ -394,10 +383,7 @@ class BaseApp:
AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine
DEFAULT_DIVIDING_LINE: StaticDividingLine = StaticDividingLine()
DEFAULT_PRINT_FUNC: Printer = Console().print
DEFAULT_AUTOCOMPLETER: AutoCompleter = AutoCompleter()
DEFAULT_EXIT_COMMAND: Command = Command("q", description="Exit command")
@@ -410,10 +396,10 @@ class App(BaseApp):
farewell_message: str = "\nSee you\n",
exit_command: Command = DEFAULT_EXIT_COMMAND,
system_router_title: str = "System points:",
dividing_line: AVAILABLE_DIVIDING_LINES | None = DEFAULT_DIVIDING_LINE,
dividing_line: AVAILABLE_DIVIDING_LINES | None = None,
repeat_command_groups_printing: bool = False,
override_system_messages: bool = False,
autocompleter: AutoCompleter = DEFAULT_AUTOCOMPLETER,
autocompleter: AutoCompleter | None = None,
print_func: Printer = DEFAULT_PRINT_FUNC,
) -> None:
"""
@@ -440,7 +426,7 @@ class App(BaseApp):
dividing_line=dividing_line,
repeat_command_groups_printing=repeat_command_groups_printing,
override_system_messages=override_system_messages,
autocompleter=autocompleter,
autocompleter=autocompleter or AutoCompleter(),
print_func=print_func,
)
if not self._override_system_messages:
+1 -2
View File
@@ -1,7 +1,6 @@
from argenta.command.flag import Flag as Flag
from argenta.command.flag import Flags as Flags
from argenta.command.flag.models import Flags as Flags, InputFlags as InputFlags
from argenta.command.flag import InputFlag as InputFlag
from argenta.command.flag import InputFlags as InputFlags
from argenta.command.flag import PossibleValues as PossibleValues
from argenta.command.flag.defaults import PredefinedFlags as PredefinedFlags
from argenta.command.models import Command as Command
+1 -2
View File
@@ -1,5 +1,4 @@
from argenta.command.flag.flags.models import Flags as Flags
from argenta.command.flag.flags.models import InputFlags as InputFlags
from argenta.command.flag.models import Flags as Flags, InputFlags as InputFlags
from argenta.command.flag.models import Flag as Flag
from argenta.command.flag.models import InputFlag as InputFlag
from argenta.command.flag.models import PossibleValues as PossibleValues
@@ -1,2 +0,0 @@
from argenta.command.flag.flags.models import Flags as Flags
from argenta.command.flag.flags.models import InputFlags as InputFlags
-107
View File
@@ -1,107 +0,0 @@
__all__ = ["Flags", "InputFlags"]
from collections.abc import Iterator
from typing import Generic, TypeVar, override
from argenta.command.flag.models import Flag, InputFlag
FlagType = TypeVar("FlagType")
class BaseFlags(Generic[FlagType]):
def __init__(self, flags: list[FlagType] | None = None) -> None:
"""
Public. A model that combines the registered flags
:param flags: the flags that will be registered
:return: None
"""
self.flags: list[FlagType] = flags if flags else []
def add_flag(self, flag: FlagType) -> None:
"""
Public. Adds a flag to the list of flags
:param flag: flag to add
:return: None
"""
self.flags.append(flag)
def add_flags(self, flags: list[FlagType]) -> None:
"""
Public. Adds a list of flags to the list of flags
:param flags: list of flags to add
:return: None
"""
self.flags.extend(flags)
def __len__(self) -> int:
return len(self.flags)
def __iter__(self) -> Iterator[FlagType]:
return iter(self.flags)
def __getitem__(self, flag_index: int) -> FlagType:
return self.flags[flag_index]
def __bool__(self) -> bool:
return bool(self.flags)
class Flags(BaseFlags[Flag]):
def get_flag_by_name(self, name: str) -> Flag | None:
"""
Public. Returns the flag entity by its name or None if not found
:param name: the name of the flag to get
:return: entity of the flag or None
"""
return next((flag for flag in self.flags if flag.name == name), None)
@override
def __eq__(self, other: object) -> bool:
if not isinstance(other, Flags):
return False
if len(self.flags) != len(other.flags):
return False
flag_pairs: zip[tuple[Flag, Flag]] = zip(self.flags, other.flags)
return all(s_flag == o_flag for s_flag, o_flag in flag_pairs)
def __contains__(self, flag_to_check: object) -> bool:
if isinstance(flag_to_check, Flag):
for flag in self.flags:
if flag == flag_to_check:
return True
return False
else:
raise TypeError
class InputFlags(BaseFlags[InputFlag]):
def get_flag_by_name(self, name: str) -> InputFlag | None:
"""
Public. Returns the flag entity by its name or None if not found
:param name: the name of the flag to get
:return: entity of the flag or None
"""
return next((flag for flag in self.flags if flag.name == name), None)
@override
def __eq__(self, other: object) -> bool:
if not isinstance(other, InputFlags):
return False
if len(self.flags) != len(other.flags):
return False
paired_flags: zip[tuple[InputFlag, InputFlag]] = zip(self.flags, other.flags)
return all(my_flag == other_flag for my_flag, other_flag in paired_flags)
def __contains__(self, ingressable_item: object) -> bool:
if isinstance(ingressable_item, InputFlag):
for flag in self.flags:
if flag == ingressable_item:
return True
return False
else:
raise TypeError
+115 -3
View File
@@ -1,8 +1,8 @@
__all__ = ["PossibleValues", "ValidationStatus", "Flag", "InputFlag"]
__all__ = ["PossibleValues", "ValidationStatus", "Flag", "InputFlag", "InputFlags", "Flags"]
from enum import Enum
from re import Pattern
from typing import Literal, override
from typing import Literal, override, TypeVar, Generic, Iterator, Any
PREFIX_TYPE = Literal["-", "--", "---"]
@@ -91,7 +91,7 @@ class InputFlag:
Public. The entity of the flag of the entered command
:param name: the name of the input flag
:param prefix: the prefix of the input flag
:param value: the value of the input flag
:param input_value: the value of the input flag
:return: None
"""
self.name: str = name
@@ -122,3 +122,115 @@ class InputFlag:
return self.name == other.name
else:
raise NotImplementedError
FlagType = TypeVar("FlagType")
class BaseFlags(Generic[FlagType]):
def __init__(self, flags: list[FlagType] | None = None) -> None:
"""
Public. A model that combines the registered flags
:param flags: the flags that will be registered
:return: None
"""
self.flags: list[FlagType] = flags if flags else []
def add_flag(self, flag: FlagType) -> None:
"""
Public. Adds a flag to the list of flags
:param flag: flag to add
:return: None
"""
self.flags.append(flag)
def add_flags(self, flags: list[FlagType]) -> None:
"""
Public. Adds a list of flags to the list of flags
:param flags: list of flags to add
:return: None
"""
self.flags.extend(flags)
def __len__(self) -> int:
return len(self.flags)
def __iter__(self) -> Iterator[FlagType]:
return iter(self.flags)
def __getitem__(self, flag_index: int) -> FlagType:
return self.flags[flag_index]
def __bool__(self) -> bool:
return bool(self.flags)
class Flags(BaseFlags[Flag]):
def get_flag_by_name(self, name: str) -> Flag | None:
"""
Public. Returns the flag entity by its name or None if not found
:param name: the name of the flag to get
:return: entity of the flag or None
"""
return next((flag for flag in self.flags if flag.name == name), None)
@override
def __eq__(self, other: object) -> bool:
if not isinstance(other, Flags):
return False
if len(self.flags) != len(other.flags):
return False
flag_pairs: Iterator[tuple[Flag, Flag]] = zip(self.flags, other.flags)
return all(s_flag == o_flag for s_flag, o_flag in flag_pairs)
def __contains__(self, flag_to_check: object) -> bool:
if isinstance(flag_to_check, Flag):
for flag in self.flags:
if flag == flag_to_check:
return True
return False
else:
raise TypeError
class InputFlags(BaseFlags[InputFlag]):
def get_flag_by_name(
self,
name: str,
with_status: ValidationStatus | None = None,
default: Any = None
) -> InputFlag | None:
"""
Public. Returns the flag entity by its name or None if not found
:param default:
:param with_status:
:param name: the name of the flag to get
:return: entity of the flag or None
"""
if with_status is None:
return next((flag for flag in self.flags if flag.name == name), default)
else:
return next((flag for flag in self.flags if flag.name == name and flag.status == with_status), default)
@override
def __eq__(self, other: object) -> bool:
if not isinstance(other, InputFlags):
return False
if len(self.flags) != len(other.flags):
return False
paired_flags: Iterator[tuple[InputFlag, InputFlag]] = zip(self.flags, other.flags)
return all(my_flag == other_flag for my_flag, other_flag in paired_flags)
def __contains__(self, ingressable_item: object) -> bool:
if isinstance(ingressable_item, InputFlag):
for flag in self.flags:
if flag == ingressable_item:
return True
return False
else:
raise TypeError
+1 -1
View File
@@ -8,7 +8,7 @@ from argenta.command.exceptions import (
RepeatedInputFlagsException,
UnprocessedInputFlagException,
)
from argenta.command.flag.flags.models import Flags, InputFlags
from argenta.command import Flags, InputFlags
from argenta.command.flag.models import Flag, InputFlag, ValidationStatus
ParseFlagsResult = tuple[InputFlags, str | None, str | None]
+1 -1
View File
@@ -2,7 +2,7 @@ __all__ = ["Response"]
from dishka import Container
from argenta.command.flag.flags.models import InputFlags
from argenta.command import InputFlags
from argenta.response.status import ResponseStatus
EMPTY_INPUT_FLAGS: InputFlags = InputFlags()
+1 -2
View File
@@ -6,9 +6,8 @@ from typing import Callable
from rich.console import Console
from argenta.app.protocols import HandlerFunc
from argenta.command import Command, InputCommand
from argenta.command import Command, InputCommand, InputFlags
from argenta.command.flag import ValidationStatus
from argenta.command.flag.flags import InputFlags
from argenta.response import Response, ResponseStatus
from argenta.router.command_handler.entity import CommandHandler, CommandHandlers
from argenta.router.exceptions import (RepeatedAliasNameException,
@@ -5,8 +5,7 @@ from collections.abc import Iterator
import pytest
from argenta import App, Orchestrator, Router
from argenta.command import Command, PredefinedFlags
from argenta.command.flag.flags.models import Flags
from argenta.command import Command, PredefinedFlags, Flags
from argenta.command.flag.models import ValidationStatus
from argenta.response import Response
@@ -5,9 +5,8 @@ from collections.abc import Iterator
import pytest
from argenta import App, Orchestrator, Router
from argenta.command import Command, PredefinedFlags
from argenta.command import Command, PredefinedFlags, Flags
from argenta.command.flag import Flag
from argenta.command.flag.flags import Flags
from argenta.command.flag.models import PossibleValues, ValidationStatus
from argenta.response import Response
+1 -1
View File
@@ -8,7 +8,7 @@ from argenta.command.exceptions import (
UnprocessedInputFlagException,
)
from argenta.command.flag import Flag, InputFlag
from argenta.command.flag.flags import Flags
from argenta.command import Flags
from argenta.command.flag.models import PossibleValues, ValidationStatus
from argenta.command.models import Command, InputCommand
+1 -1
View File
@@ -3,7 +3,7 @@ import re
import pytest
from argenta.command.flag import Flag, InputFlag, PossibleValues
from argenta.command.flag.flags import Flags, InputFlags
from argenta.command import Flags, InputFlags
# ============================================================================
+1 -1
View File
@@ -2,7 +2,7 @@ from datetime import date, datetime
import pytest
from argenta.command.flag.flags.models import InputFlags
from argenta.command import InputFlags
from argenta.command.flag.models import InputFlag
from argenta.data_bridge import DataBridge
from argenta.response.entity import EMPTY_INPUT_FLAGS, Response
+1 -2
View File
@@ -3,9 +3,8 @@ import re
import pytest
from pytest import CaptureFixture
from argenta.command import Command, InputCommand
from argenta.command import Command, InputCommand, Flags, InputFlags
from argenta.command.flag import Flag, InputFlag
from argenta.command.flag.flags import Flags, InputFlags
from argenta.command.flag.models import PossibleValues, ValidationStatus
from argenta.response.entity import Response
from argenta.router import Router
Generated
+45
View File
@@ -61,6 +61,10 @@ linters = [
{ name = "ruff" },
{ name = "wemake-python-styleguide" },
]
metrics = [
{ name = "psutil" },
{ name = "py-cpuinfo" },
]
tests = [
{ name = "pyfakefs" },
{ name = "pytest" },
@@ -92,6 +96,10 @@ linters = [
{ name = "ruff", specifier = ">=0.12.12" },
{ name = "wemake-python-styleguide", specifier = ">=0.17.0" },
]
metrics = [
{ name = "psutil", specifier = ">=7.2.1" },
{ name = "py-cpuinfo", specifier = ">=9.0.0" },
]
tests = [
{ name = "pyfakefs", specifier = ">=5.5.0" },
{ name = "pytest", specifier = ">=8.3.2" },
@@ -601,6 +609,43 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" },
]
[[package]]
name = "psutil"
version = "7.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/73/cb/09e5184fb5fc0358d110fc3ca7f6b1d033800734d34cac10f4136cfac10e/psutil-7.2.1.tar.gz", hash = "sha256:f7583aec590485b43ca601dd9cea0dcd65bd7bb21d30ef4ddbf4ea6b5ed1bdd3", size = 490253, upload-time = "2025-12-29T08:26:00.169Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/8e/f0c242053a368c2aa89584ecd1b054a18683f13d6e5a318fc9ec36582c94/psutil-7.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9f33bb525b14c3ea563b2fd521a84d2fa214ec59e3e6a2858f78d0844dd60d", size = 129624, upload-time = "2025-12-29T08:26:04.255Z" },
{ url = "https://files.pythonhosted.org/packages/26/97/a58a4968f8990617decee234258a2b4fc7cd9e35668387646c1963e69f26/psutil-7.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:81442dac7abfc2f4f4385ea9e12ddf5a796721c0f6133260687fec5c3780fa49", size = 130132, upload-time = "2025-12-29T08:26:06.228Z" },
{ url = "https://files.pythonhosted.org/packages/db/6d/ed44901e830739af5f72a85fa7ec5ff1edea7f81bfbf4875e409007149bd/psutil-7.2.1-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea46c0d060491051d39f0d2cff4f98d5c72b288289f57a21556cc7d504db37fc", size = 180612, upload-time = "2025-12-29T08:26:08.276Z" },
{ url = "https://files.pythonhosted.org/packages/c7/65/b628f8459bca4efbfae50d4bf3feaab803de9a160b9d5f3bd9295a33f0c2/psutil-7.2.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35630d5af80d5d0d49cfc4d64c1c13838baf6717a13effb35869a5919b854cdf", size = 183201, upload-time = "2025-12-29T08:26:10.622Z" },
{ url = "https://files.pythonhosted.org/packages/fb/23/851cadc9764edcc18f0effe7d0bf69f727d4cf2442deb4a9f78d4e4f30f2/psutil-7.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:923f8653416604e356073e6e0bccbe7c09990acef442def2f5640dd0faa9689f", size = 139081, upload-time = "2025-12-29T08:26:12.483Z" },
{ url = "https://files.pythonhosted.org/packages/59/82/d63e8494ec5758029f31c6cb06d7d161175d8281e91d011a4a441c8a43b5/psutil-7.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cfbe6b40ca48019a51827f20d830887b3107a74a79b01ceb8cc8de4ccb17b672", size = 134767, upload-time = "2025-12-29T08:26:14.528Z" },
{ url = "https://files.pythonhosted.org/packages/05/c2/5fb764bd61e40e1fe756a44bd4c21827228394c17414ade348e28f83cd79/psutil-7.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:494c513ccc53225ae23eec7fe6e1482f1b8a44674241b54561f755a898650679", size = 129716, upload-time = "2025-12-29T08:26:16.017Z" },
{ url = "https://files.pythonhosted.org/packages/c9/d2/935039c20e06f615d9ca6ca0ab756cf8408a19d298ffaa08666bc18dc805/psutil-7.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3fce5f92c22b00cdefd1645aa58ab4877a01679e901555067b1bd77039aa589f", size = 130133, upload-time = "2025-12-29T08:26:18.009Z" },
{ url = "https://files.pythonhosted.org/packages/77/69/19f1eb0e01d24c2b3eacbc2f78d3b5add8a89bf0bb69465bc8d563cc33de/psutil-7.2.1-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93f3f7b0bb07711b49626e7940d6fe52aa9940ad86e8f7e74842e73189712129", size = 181518, upload-time = "2025-12-29T08:26:20.241Z" },
{ url = "https://files.pythonhosted.org/packages/e1/6d/7e18b1b4fa13ad370787626c95887b027656ad4829c156bb6569d02f3262/psutil-7.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d34d2ca888208eea2b5c68186841336a7f5e0b990edec929be909353a202768a", size = 184348, upload-time = "2025-12-29T08:26:22.215Z" },
{ url = "https://files.pythonhosted.org/packages/98/60/1672114392dd879586d60dd97896325df47d9a130ac7401318005aab28ec/psutil-7.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2ceae842a78d1603753561132d5ad1b2f8a7979cb0c283f5b52fb4e6e14b1a79", size = 140400, upload-time = "2025-12-29T08:26:23.993Z" },
{ url = "https://files.pythonhosted.org/packages/fb/7b/d0e9d4513c46e46897b46bcfc410d51fc65735837ea57a25170f298326e6/psutil-7.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:08a2f175e48a898c8eb8eace45ce01777f4785bc744c90aa2cc7f2fa5462a266", size = 135430, upload-time = "2025-12-29T08:26:25.999Z" },
{ url = "https://files.pythonhosted.org/packages/c5/cf/5180eb8c8bdf6a503c6919f1da28328bd1e6b3b1b5b9d5b01ae64f019616/psutil-7.2.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b2e953fcfaedcfbc952b44744f22d16575d3aa78eb4f51ae74165b4e96e55f42", size = 128137, upload-time = "2025-12-29T08:26:27.759Z" },
{ url = "https://files.pythonhosted.org/packages/c5/2c/78e4a789306a92ade5000da4f5de3255202c534acdadc3aac7b5458fadef/psutil-7.2.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:05cc68dbb8c174828624062e73078e7e35406f4ca2d0866c272c2410d8ef06d1", size = 128947, upload-time = "2025-12-29T08:26:29.548Z" },
{ url = "https://files.pythonhosted.org/packages/29/f8/40e01c350ad9a2b3cb4e6adbcc8a83b17ee50dd5792102b6142385937db5/psutil-7.2.1-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e38404ca2bb30ed7267a46c02f06ff842e92da3bb8c5bfdadbd35a5722314d8", size = 154694, upload-time = "2025-12-29T08:26:32.147Z" },
{ url = "https://files.pythonhosted.org/packages/06/e4/b751cdf839c011a9714a783f120e6a86b7494eb70044d7d81a25a5cd295f/psutil-7.2.1-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab2b98c9fc19f13f59628d94df5cc4cc4844bc572467d113a8b517d634e362c6", size = 156136, upload-time = "2025-12-29T08:26:34.079Z" },
{ url = "https://files.pythonhosted.org/packages/44/ad/bbf6595a8134ee1e94a4487af3f132cef7fce43aef4a93b49912a48c3af7/psutil-7.2.1-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f78baafb38436d5a128f837fab2d92c276dfb48af01a240b861ae02b2413ada8", size = 148108, upload-time = "2025-12-29T08:26:36.225Z" },
{ url = "https://files.pythonhosted.org/packages/1c/15/dd6fd869753ce82ff64dcbc18356093471a5a5adf4f77ed1f805d473d859/psutil-7.2.1-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:99a4cd17a5fdd1f3d014396502daa70b5ec21bf4ffe38393e152f8e449757d67", size = 147402, upload-time = "2025-12-29T08:26:39.21Z" },
{ url = "https://files.pythonhosted.org/packages/34/68/d9317542e3f2b180c4306e3f45d3c922d7e86d8ce39f941bb9e2e9d8599e/psutil-7.2.1-cp37-abi3-win_amd64.whl", hash = "sha256:b1b0671619343aa71c20ff9767eced0483e4fc9e1f489d50923738caf6a03c17", size = 136938, upload-time = "2025-12-29T08:26:41.036Z" },
{ url = "https://files.pythonhosted.org/packages/3e/73/2ce007f4198c80fcf2cb24c169884f833fe93fbc03d55d302627b094ee91/psutil-7.2.1-cp37-abi3-win_arm64.whl", hash = "sha256:0d67c1822c355aa6f7314d92018fb4268a76668a536f133599b91edd48759442", size = 133836, upload-time = "2025-12-29T08:26:43.086Z" },
]
[[package]]
name = "py-cpuinfo"
version = "9.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716, upload-time = "2022-10-25T20:38:06.303Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335, upload-time = "2022-10-25T20:38:27.636Z" },
]
[[package]]
name = "pycodestyle"
version = "2.14.0"