Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update linting with the latest ruff #1441

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions ops/_private/harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
AnyStr,
BinaryIO,
Callable,
ClassVar,
Dict,
Generic,
Iterable,
Expand Down Expand Up @@ -2225,7 +2226,7 @@ def decorator(target_cls: Any):
class _TestingConfig(Dict[str, Union[str, int, float, bool]]):
"""Represents the Juju Config."""

_supported_types = {
_supported_types: ClassVar[Dict[str, Any]] = {
IronCore864 marked this conversation as resolved.
Show resolved Hide resolved
'string': str,
'boolean': bool,
'int': int,
Expand Down Expand Up @@ -2838,9 +2839,7 @@ def _has_secret_owner_permission(self, secret: _Secret) -> bool:
unit_secret = secret.owner_name == self.unit_name
app_secret = secret.owner_name == self.app_name

if unit_secret or (app_secret and self.is_leader()):
return True
return False
return unit_secret or (app_secret and self.is_leader())

def secret_info_get(
self, *, id: Optional[str] = None, label: Optional[str] = None
Expand Down
3 changes: 2 additions & 1 deletion ops/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from typing import (
TYPE_CHECKING,
Any,
ClassVar,
Dict,
List,
Literal,
Expand Down Expand Up @@ -1678,7 +1679,7 @@ class RelationMeta:
``metadata.yaml`` and used by the charm code if appropriate.
"""

VALID_SCOPES = ['global', 'container']
VALID_SCOPES: ClassVar[List[str]] = ['global', 'container']
IronCore864 marked this conversation as resolved.
Show resolved Hide resolved

def __init__(self, role: RelationRole, relation_name: str, raw: '_RelationMetaDict'):
assert isinstance(
Expand Down
7 changes: 4 additions & 3 deletions ops/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
Any,
BinaryIO,
Callable,
ClassVar,
Dict,
Generator,
Iterable,
Expand Down Expand Up @@ -1963,7 +1964,7 @@ class StatusBase:
directly use the child class such as :class:`ActiveStatus` to indicate their status.
"""

_statuses: Dict[StatusName, Type['StatusBase']] = {}
_statuses: ClassVar[Dict[StatusName, Type['StatusBase']]] = {}

# Subclasses must provide this attribute
name: StatusName
Expand Down Expand Up @@ -2023,7 +2024,7 @@ def _register(cls, child: Type['StatusBase']) -> None:
)
cls._statuses[child.name] = child

_priorities = {
_priorities: ClassVar[Dict[str, Any]] = {
IronCore864 marked this conversation as resolved.
Show resolved Hide resolved
'error': 5,
'blocked': 4,
'maintenance': 3,
Expand Down Expand Up @@ -3715,7 +3716,7 @@ def secret_info_get(
args.extend(['--label', label])
result = self._run_for_secret('secret-info-get', *args, return_output=True, use_json=True)
info_dicts = typing.cast(Dict[str, Any], result)
id = list(info_dicts)[0] # Juju returns dict of {secret_id: {info}}
id = next(iter(info_dicts)) # Juju returns dict of {secret_id: {info}}
return SecretInfo.from_dict(
id, typing.cast(Dict[str, Any], info_dicts[id]), model_uuid=self.model_uuid
)
Expand Down
17 changes: 1 addition & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,9 @@ ignore = [
# Missing docstring in `__init__`
"D107",

# Manual list comprehension.
"PERF401",
# Manual dict comprehension.
"PERF403",

# Convert Dict[X] to dict[x], which we cannot do while we support Python 3.8
"UP006",

# Convert Union[X, Y] to X | Y, which we cannot do while we support Python 3.8
"UP007",

tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
# Convert {} from `TypedDict` functional to class syntax
# Note that since we have some `TypedDict`s that cannot use the class
# syntax, we're currently choosing to be consistent in syntax even though
Expand All @@ -167,14 +159,6 @@ ignore = [

# `subprocess` call: check for execution of untrusted input
"S603",
# Prefer `next(iter(info_dicts))` over single element slice
"RUF015",
IronCore864 marked this conversation as resolved.
Show resolved Hide resolved
# Mutable class attributes should be annotated with `typing.ClassVar`
"RUF012",
# Unnecessary `tuple` call (rewrite as a literal)
"C408",
# Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead
"C420",
]

[tool.ruff.lint.pyupgrade]
Expand Down Expand Up @@ -211,6 +195,7 @@ keep-runtime-typing = true
"E266", # Too many leading `#` before block comment
"I001", # Import block is un-sorted or un-formatted
"RUF003", # Comment contains ambiguous unicode characters (EN DASH, RIGHT SINGLE QUOTATION MARK)
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
"UP031", # Use format specifiers instead of percent format
]

Expand Down
4 changes: 2 additions & 2 deletions test/test_real_pebble.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ def test_checks_and_health(self, client: pebble.Client):
# After two retries the "bad" check should go down
for _ in range(5):
checks = client.get_checks()
bad_check = [c for c in checks if c.name == 'bad'][0]
bad_check = next(c for c in checks if c.name == 'bad')
if bad_check.status == pebble.CheckStatus.DOWN:
break
time.sleep(0.06)
else:
assert False, 'timed out waiting for "bad" check to go down'
assert bad_check.failures == 2
assert bad_check.threshold == 2
good_check = [c for c in checks if c.name == 'good'][0]
good_check = next(c for c in checks if c.name == 'good')
assert good_check.status == pebble.CheckStatus.UP

# And /v1/health should return "unhealthy" (with status HTTP 502)
Expand Down
10 changes: 5 additions & 5 deletions test/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5113,7 +5113,7 @@ def test_push_files_and_list(
}

# Let's pull the first file again and check its details
file = [f for f in files if f.path == f'{pebble_dir}/file1'][0]
file = next(f for f in files if f.path == f'{pebble_dir}/file1')
assert file.name == 'file1'
assert file.type == pebble.FileType.FILE
assert file.size == 4
Expand Down Expand Up @@ -5275,8 +5275,8 @@ def test_make_dir_with_permission_mask(
client.make_dir(f'{pebble_dir}/dir2', permissions=0o777)

files = client.list_files(f'{pebble_dir}/', pattern='dir*')
assert [f for f in files if f.path == f'{pebble_dir}/dir1'][0].permissions == 0o700
assert [f for f in files if f.path == f'{pebble_dir}/dir2'][0].permissions == 0o777
assert next(f for f in files if f.path == f'{pebble_dir}/dir1').permissions == 0o700
assert next(f for f in files if f.path == f'{pebble_dir}/dir2').permissions == 0o777

# If permissions are outside of the range 0o000 through 0o777, an exception should be
# raised.
Expand Down Expand Up @@ -5432,8 +5432,8 @@ def test_container_storage_mounts(self, request: pytest.FixtureRequest):
assert not c1.exists(c1_fpath)

def _select_testing_user_group(self):
user = [u for u in pwd.getpwall() if u.pw_uid != os.getuid()][0]
group = [g for g in grp.getgrall() if g.gr_gid != os.getgid()][0]
user = next(u for u in pwd.getpwall() if u.pw_uid != os.getuid())
group = next(g for g in grp.getgrall() if g.gr_gid != os.getgid())
return user, group

def test_push_with_ownership(
Expand Down