Skip to content

Commit

Permalink
chore: Run pycodestyle fixes, add some docstrings (#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
pederhan authored Jan 20, 2025
1 parent 2b2aadb commit 3b09b66
Show file tree
Hide file tree
Showing 27 changed files with 224 additions and 61 deletions.
3 changes: 2 additions & 1 deletion tests/pyzabbix/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ def test_login_fails(zabbix_client_mock_version: ZabbixAPI) -> None:

def test_logout_fails(zabbix_client_mock_version: ZabbixAPI) -> None:
"""Test that we get the correct exception type when login fails
due to a connection error."""
due to a connection error.
"""
client = zabbix_client_mock_version
client.set_url("http://some-url-that-will-fail.gg")
assert client.url == snapshot("http://some-url-that-will-fail.gg/api_jsonrpc.php")
Expand Down
3 changes: 2 additions & 1 deletion tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ def test_get_auth_token_file_paths_override(tmp_path: Path, config: Config) -> N
@pytest.fixture
def table_renderable_mock(monkeypatch) -> type[TableRenderable]:
"""Replace TableRenderable class in zabbix_cli.models with mock class
so that tests can mutate it without affecting other tests."""
so that tests can mutate it without affecting other tests.
"""
from zabbix_cli.models import TableRenderable

class MockTableRenderable(TableRenderable):
Expand Down
6 changes: 4 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def remove_path_options(config_path: Path, tmp_path: Path) -> None:
"""Remove all path options from a TOML config file.
Some config options require a directory or file to exist, which is not always
possible or desirable in a test environment."""
possible or desirable in a test environment.
"""
contents = config_path.read_text()
new_contents = "\n".join(
line for line in contents.splitlines() if "/path/to" not in line
Expand Down Expand Up @@ -531,7 +532,8 @@ def test_load_deprecated_config_with_new_and_old_options(tmp_path: Path) -> None
"""Test loading a config file where both new and deprecated options are present.
The deprecated options should _not_ be assigned to the new options, as the new options
are already set"""
are already set
"""
conf = tmp_path / "zabbix-cli.toml"
conf.write_text(
"""
Expand Down
3 changes: 2 additions & 1 deletion tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class TestTableRenderable(TableRenderable):

def test_rows_with_unknown_base_model(caplog: LogCaptureFixture) -> None:
"""Test that we log when we try to render a BaseModel
instance that does not inherit from TableRenderable."""
instance that does not inherit from TableRenderable.
"""

class FooModel(BaseModel):
foo: str
Expand Down
4 changes: 2 additions & 2 deletions zabbix_cli/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ def login_with_any(self) -> tuple[ZabbixAPI, LoginInfo]:
7. Session ID in legacy auth token file (if `use_session_file=true`)
8. Username and password from prompt
"""

for credentials in self._iter_all_credentials():
if not credentials.is_valid():
logger.debug("No valid credentials found with %s", credentials)
Expand Down Expand Up @@ -562,7 +561,8 @@ def _get_session_file(self) -> Optional[Credentials]:
def _get_auth_token_file_legacy(self) -> Optional[Credentials]:
"""Get auth token (session ID) from a legacy auth token file.
From Zabbix-CLI 3.5.0 onwards, we use a new session file."""
From Zabbix-CLI 3.5.0 onwards, we use a new session file.
"""
if not self.config.app.use_session_file:
logger.debug("Not configured to use auth token file.")
return
Expand Down
1 change: 0 additions & 1 deletion zabbix_cli/bulk.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ def run_bulk(self) -> Counter[CommandResult]:
CommandFileError: If command file cannot be parsed or a command fails (in STRICT mode)
Example:
```bash
$ cat /tmp/commands.txt
Expand Down
6 changes: 4 additions & 2 deletions zabbix_cli/commands/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ def update_config(
) -> None:
"""Update the config file with the current application state.
Adds missing fields and updates deprecated fields to their new values."""
Adds missing fields and updates deprecated fields to their new values.
"""
from zabbix_cli.output.prompts import bool_prompt

config_file = config_file or app.state.config.config_path
Expand All @@ -385,7 +386,8 @@ def update_application(ctx: typer.Context) -> None:
"""Update the application to the latest version.
Primarily intended for use with PyInstaller builds, but can also be
used for updating other installations (except Homebrew)."""
used for updating other installations (except Homebrew).
"""
from zabbix_cli.__about__ import __version__
from zabbix_cli.update import update

Expand Down
3 changes: 2 additions & 1 deletion zabbix_cli/commands/hostgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,8 @@ def show_hostgroups(
) -> None:
"""Show details for host groups.
Limits results to 20 by default. Fetching all host groups with hosts can be extremely slow."""
Limits results to 20 by default. Fetching all host groups with hosts can be extremely slow.
"""
from zabbix_cli.commands.results.hostgroup import HostGroupResult
from zabbix_cli.models import AggregateResult

Expand Down
3 changes: 2 additions & 1 deletion zabbix_cli/commands/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ def show_users(
) -> None:
"""Show all users.
Users can be filtered by name, ID, or role."""
Users can be filtered by name, ID, or role.
"""
from zabbix_cli.models import AggregateResult
from zabbix_cli.pyzabbix.compat import user_name

Expand Down
6 changes: 4 additions & 2 deletions zabbix_cli/commands/usergroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def sort_ugroups(
I.e. we have some custom types that all share the samse attributes
`name` and `usrgrpid`. This function sorts them based on the given
sorting method."""
sorting method.
"""
if sort == UsergroupSorting.NAME:
return sorted(ugroups, key=lambda ug: ug.name)
elif sort == UsergroupSorting.ID:
Expand Down Expand Up @@ -330,7 +331,8 @@ def show_usergroups(
) -> None:
"""Show all suser groups.
Can be filtered by name or ID."""
Can be filtered by name or ID.
"""
_do_show_usergroups(usergroup, sort=sort, limit=limit)


Expand Down
1 change: 0 additions & 1 deletion zabbix_cli/config/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ def init_config(
"""Creates required directories and boostraps config with
options required to connect to the Zabbix API.
"""

from zabbix_cli import auth
from zabbix_cli.config.model import Config
from zabbix_cli.dirs import init_directories
Expand Down
3 changes: 2 additions & 1 deletion zabbix_cli/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ def add_log_context(field: str, value: Any) -> None:
def get_file_handler_safe(filename: Path) -> logging.Handler:
"""Return a FileHandler that does not fail if the file cannot be opened.
Returns a stderr StreamHandler if the file cannot be opened."""
Returns a stderr StreamHandler if the file cannot be opened.
"""
from zabbix_cli.utils.fs import mkdir_if_not_exists

try:
Expand Down
5 changes: 2 additions & 3 deletions zabbix_cli/pyzabbix/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,8 @@ def add_common_params(
Based on https://www.zabbix.com/documentation/7.0/en/manual/api/reference_commentary#common-get-method-parameters
NOTE
----
`parse_name_or_id_arg` handles the `search*` parameters
Note:
`parse_name_or_id_arg` handles the `search*` parameters
"""
if sort_field:
params["sortfield"] = sort_field
Expand Down
28 changes: 22 additions & 6 deletions zabbix_cli/pyzabbix/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ def serialize_host_list_json(
Most of the time we don't want to serialize _all_ fields of a host.
This serializer assumes that we want to serialize the minimal representation
of hosts unless the context specifies otherwise."""
of hosts unless the context specifies otherwise.
"""
if isinstance(info.context, dict):
if info.context.get("full_host"): # pyright: ignore[reportUnknownMemberType]
return [host.model_dump(mode="json") for host in hosts]
Expand All @@ -146,7 +147,8 @@ def serialize_host_list_json(

def age_from_datetime(dt: Optional[datetime]) -> Optional[str]:
"""Returns the age of a datetime object as a human-readable
string, or None if the datetime is None."""
string, or None if the datetime is None.
"""
if not dt:
return None
n = datetime.now(tz=dt.tzinfo)
Expand All @@ -157,7 +159,8 @@ def age_from_datetime(dt: Optional[datetime]) -> Optional[str]:

def format_datetime(dt: Optional[datetime]) -> str:
"""Returns a formatted datetime string, or empty string if the
datetime is None."""
datetime is None.
"""
if not dt:
return ""
return dt.strftime("%Y-%m-%d %H:%M:%S")
Expand Down Expand Up @@ -234,7 +237,8 @@ class ZabbixAPIBaseModel(TableRenderable):
def model_dump_api(self) -> dict[str, Any]:
"""Dump the model as a JSON-serializable dict used in API calls.
Excludes computed fields by default."""
Excludes computed fields by default.
"""
return self.model_dump(
mode="json",
exclude=set(self.model_computed_fields),
Expand Down Expand Up @@ -609,6 +613,8 @@ def __cols_rows__(self) -> ColsRowsType:


class CreateHostInterfaceDetails(ZabbixAPIBaseModel):
"""Parameters for creating a host interface."""

version: int
bulk: Optional[int] = None
community: Optional[str] = None
Expand All @@ -623,6 +629,8 @@ class CreateHostInterfaceDetails(ZabbixAPIBaseModel):


class UpdateHostInterfaceDetails(ZabbixAPIBaseModel):
"""Parameters for updating a host interface."""

version: Optional[int] = None
bulk: Optional[int] = None
community: Optional[str] = None
Expand All @@ -637,6 +645,8 @@ class UpdateHostInterfaceDetails(ZabbixAPIBaseModel):


class Proxy(ZabbixAPIBaseModel):
"""Zabbix Proxy object."""

proxyid: str
name: str = Field(..., validation_alias=AliasChoices("host", "name"))
hosts: HostList = Field(default_factory=list)
Expand Down Expand Up @@ -689,6 +699,8 @@ def compatibility_rich(self) -> str:


class ProxyGroup(ZabbixAPIBaseModel):
"""Zabbix Proxy Group object."""

proxy_groupid: str
name: str
description: str
Expand Down Expand Up @@ -759,10 +771,14 @@ class Macro(MacroBase):


class GlobalMacro(MacroBase):
"""Global macro object."""

globalmacroid: str


class Item(ZabbixAPIBaseModel):
"""Zabbix Item."""

itemid: str
delay: Optional[str] = None
hostid: Optional[str] = None
Expand Down Expand Up @@ -795,7 +811,7 @@ def value_type_str(self) -> str:
def _LEGACY_type_serializer(
self, v: Optional[int], _info: FieldSerializationInfo
) -> Union[str, int, None]:
"""Serializes the item type as a formatted string in legacy JSON mode"""
"""Serializes the item type as a formatted string in legacy JSON mode."""
if self.legacy_json_format:
return self.type_str
return v
Expand All @@ -804,7 +820,7 @@ def _LEGACY_type_serializer(
def _LEGACY_value_type_serializer(
self, v: Optional[int], _info: FieldSerializationInfo
) -> Union[str, int, None]:
"""Serializes the item type as a formatted string in legacy JSON mode"""
"""Serializes the item type as a formatted string in legacy JSON mode."""
if self.legacy_json_format:
return self.type_str
return v
Expand Down
47 changes: 35 additions & 12 deletions zabbix_cli/repl/completer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Completer functionality for Click commands in the REPL."""

from __future__ import annotations

import os
Expand All @@ -24,17 +26,21 @@


def split_arg_string(string: str, posix: bool = True) -> list[str]:
"""Split an argument string as with :func:`shlex.split`, but don't
fail if the string is incomplete. Ignores a missing closing quote or
incomplete escape sequence and uses the partial token as-is.
.. code-block:: python
split_arg_string("example 'my file")
r"""Split an argument in a shlex-like way, but don't fail if the string is incomplete.
Args:
string (str): String to split
posix (bool, optional): Posix-like parsing. Defaults to True.
Returns:
list[str]: String split into tokens.
Examples:
>>> split_arg_string("example 'my file")
["example", "my file"]
split_arg_string("example my\\")
>>> split_arg_string("example my\\")
["example", "my"]
:param string: String to split.
"""

lex = shlex.shlex(string, posix=posix)
lex.whitespace_split = True
lex.commenters = ""
Expand All @@ -53,14 +59,20 @@ def split_arg_string(string: str, posix: bool = True) -> list[str]:


def _resolve_context(args: list[Any], ctx: click.Context) -> click.Context:
"""Produce the context hierarchy starting with the command and
"""Resolve context and return the last context in the chain.
Produce the context hierarchy starting with the command and
traversing the complete arguments. This only follows the commands,
it doesn't trigger input prompts or callbacks.
:param args: List of complete args before the incomplete value.
:param cli_ctx: `click.Context` object of the CLI group
"""
Args:
args (list[Any]): List of complete args before the incomplete value.
ctx (click.Context): `click.Context` object of the CLI group
Returns:
click.Context: Resolved context.
"""
while args:
command = ctx.command

Expand Down Expand Up @@ -99,6 +111,8 @@ def _resolve_context(args: list[Any], ctx: click.Context) -> click.Context:


class ClickCompleter(Completer):
"""Completer for Click commands."""

__slots__ = ("cli", "ctx", "parsed_args", "parsed_ctx", "ctx_command")

def __init__(
Expand Down Expand Up @@ -284,6 +298,15 @@ def _get_completion_for_cmd_args(
def get_completions(
self, document: Document, complete_event: Optional[CompleteEvent] = None
) -> Generator[Completion, Any, None]:
"""Generator of completions for the current input.
Args:
document (Document): Current prompt_toolkit document.
complete_event (Optional[CompleteEvent], optional): Event that triggered the completion. Defaults to None.
Yields:
Generator[Completion, Any, None]: Completions for the current input.
"""
# Code analogous to click._bashcomplete.do_complete

args = split_arg_string(document.text_before_cursor, posix=False)
Expand Down
3 changes: 1 addition & 2 deletions zabbix_cli/repl/repl.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ def bootstrap_prompt(
show_only_unused: bool = False,
shortest_only: bool = False,
) -> dict[str, Any]:
"""
Bootstrap prompt_toolkit kwargs or use user defined values.
"""Bootstrap prompt_toolkit kwargs or use user defined values.
:param prompt_kwargs: The user specified prompt kwargs.
"""
Expand Down
6 changes: 6 additions & 0 deletions zabbix_cli/scripts/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
"""DEPRECATED: Zabbix CLI scripts.
These scripts are now baked directly into the CLI. The current scripts
are just shims to call the CLI with the appropriate arguments.
"""

from __future__ import annotations
2 changes: 2 additions & 0 deletions zabbix_cli/scripts/bulk_execution.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""DEPRECATED: Bulk execution of Zabbix commands."""

from __future__ import annotations

import subprocess
Expand Down
3 changes: 3 additions & 0 deletions zabbix_cli/scripts/init.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""DEPRECATED: Set up Zabbix-CLI configuration."""

from __future__ import annotations

import subprocess
Expand Down Expand Up @@ -58,6 +60,7 @@ def main_callback(


def main() -> None:
"""Run the CLI."""
app()


Expand Down
Loading

0 comments on commit 3b09b66

Please sign in to comment.