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

chore: expand ruff rule sets and make corresponding minor adjustments #1114

Merged
merged 32 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bd877cc
Move to ruff for linting.
tonyandrewmeyer Jan 26, 2024
f6e3b02
Fix docstring ignore.
tonyandrewmeyer Jan 26, 2024
bd89726
Fix bad re-import.
tonyandrewmeyer Jan 26, 2024
8e79ae7
Fix bad auto-fix.
tonyandrewmeyer Jan 26, 2024
2f52fa8
Fix bad auto-fix.
tonyandrewmeyer Jan 26, 2024
66879bb
Remove out-of-date test.
tonyandrewmeyer Jan 26, 2024
4203eb7
We are deliberately testing in this order.
tonyandrewmeyer Jan 26, 2024
2112b29
Adjust fix so that pyright is happy.
tonyandrewmeyer Jan 26, 2024
79110c0
Remove notes.
tonyandrewmeyer Jan 26, 2024
ad50df9
C was not properly enabled before, so we can leave it disabled now.
tonyandrewmeyer Feb 2, 2024
8d8da24
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
2f02ac4
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
debd5ba
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
c0f77ac
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
abc838b
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
c7c457b
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
e8d7999
Revert unnecessary formatting change.
tonyandrewmeyer Feb 2, 2024
e4517c3
Our loader is a subclass of safe loader, so safe.
tonyandrewmeyer Feb 2, 2024
5b678fd
Merge branch 'main' into ruff-linting-1102
tonyandrewmeyer Feb 2, 2024
1249d11
Merge branch 'main' into ruff-linting-1102
tonyandrewmeyer Feb 6, 2024
4e973c3
Merge branch 'main' into ruff-linting-1102
tonyandrewmeyer Feb 14, 2024
0ecd66e
Remove ANN and PT for now.
tonyandrewmeyer Feb 14, 2024
2a11df2
More fully remove ANN.
tonyandrewmeyer Feb 14, 2024
bea9853
Make it clearer what's being skipped for the tests.
tonyandrewmeyer Feb 14, 2024
f67d053
Improvement from Ben that the linter missed.
tonyandrewmeyer Feb 14, 2024
2139898
Don't use contextlib.suppress.
tonyandrewmeyer Feb 14, 2024
7050a22
Bump ruff version.
tonyandrewmeyer Feb 14, 2024
ada2255
Merge branch 'main' into ruff-linting-1102
tonyandrewmeyer Feb 15, 2024
b6921a0
Disable PERF401 and PERF403 globally.
tonyandrewmeyer Feb 15, 2024
cf5b2ab
Add comment.
tonyandrewmeyer Feb 15, 2024
0276163
Remove duplicate ignore.
tonyandrewmeyer Feb 15, 2024
d183021
Add comment.
tonyandrewmeyer Feb 15, 2024
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
10 changes: 5 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def _compute_navigation_tree(context):

# Pull in fix from https://github.com/sphinx-doc/sphinx/pull/11222/files to fix
# "invalid signature for autoattribute ('ops.pebble::ServiceDict.backoff-delay')"
import re
import sphinx.ext.autodoc
import re # noqa: E402
import sphinx.ext.autodoc # noqa: E402
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
sphinx.ext.autodoc.py_ext_sig_re = re.compile(
r'''^ ([\w.]+::)? # explicit module name
([\w.]+\.)? # module and/or class name(s)
Expand Down Expand Up @@ -150,15 +150,15 @@ def _compute_navigation_tree(context):
# Find the current builder
builder = "dirhtml"
if '-b' in sys.argv:
builder = sys.argv[sys.argv.index('-b')+1]
builder = sys.argv[sys.argv.index('-b') + 1]

html_theme = 'furo'
html_last_updated_fmt = ""
html_permalinks_icon = "¶"
html_theme_options = {
"light_css_variables": {
"color-sidebar-background-border": "none",
"font-stack": "Ubuntu, -apple-system, Segoe UI, Roboto, Oxygen, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif",
"font-stack": "Ubuntu, -apple-system, Segoe UI, Roboto, Oxygen, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif", # noqa: E501
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
"font-stack--monospace": "Ubuntu Mono, Consolas, Monaco, Courier, monospace",
"color-foreground-primary": "#111",
"color-foreground-secondary": "var(--color-foreground-primary)",
Expand All @@ -168,7 +168,7 @@ def _compute_navigation_tree(context):
"color-brand-primary": "#111",
"color-brand-content": "#06C",
# NOTE: this looks horrible -- commented out
#"color-api-background": "#cdcdcd",
# "color-api-background": "#cdcdcd",
"color-inline-code-background": "rgba(0,0,0,.03)",
"color-sidebar-link-text": "#111",
"color-sidebar-item-background--current": "#ebebeb",
Expand Down
18 changes: 9 additions & 9 deletions ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

# The "from .X import Y" imports below don't explicitly tell Pyright (or MyPy)
# that those symbols are part of the public API, so we have to add __all__.
__all__ = [
__all__ = [ # noqa: RUF022 `__all__` is not sorted
'__version__',
'main',
'pebble',
Expand Down Expand Up @@ -173,20 +173,20 @@
# isort:skip_file

# Import pebble explicitly. It's the one module we don't import names from below.
from . import pebble # type: ignore # noqa: F401
from . import pebble # type: ignore

# Also import charm explicitly. This is not strictly necessary as the
# "from .charm" import automatically does that, but be explicit since this
# import was here previously
from . import charm # type: ignore # noqa: F401
from . import charm # type: ignore # noqa: F401 `.charm` imported but unused

# Import the main module, which we've overriden in main.py to be callable.
# This allows "import ops; ops.main(Charm)" to work as expected.
from . import main # type: ignore # noqa: F401
from . import main # type: ignore

# Explicitly import names from submodules so users can just "import ops" and
# then use them as "ops.X".
from .charm import ( # noqa: F401
from .charm import (
ActionEvent,
ActionMeta,
CharmBase,
Expand Down Expand Up @@ -237,7 +237,7 @@
WorkloadEvent,
)

from .framework import ( # noqa: F401
from .framework import (
BoundEvent,
BoundStoredState,
CommitEvent,
Expand All @@ -261,9 +261,9 @@
StoredStateData,
)

from .jujuversion import JujuVersion # noqa: F401
from .jujuversion import JujuVersion

from .model import ( # noqa: F401 E402
from .model import (
ActiveStatus,
Application,
Binding,
Expand Down Expand Up @@ -312,4 +312,4 @@
# NOTE: don't import testing or Harness here, as that's a test-time concern
# rather than a runtime concern.

from .version import version as __version__ # noqa: F401 E402
from .version import version as __version__
13 changes: 13 additions & 0 deletions ops/_private/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2019-2024 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
2 changes: 1 addition & 1 deletion ops/_private/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

def safe_load(stream: Union[str, TextIO]) -> Any:
"""Same as yaml.safe_load, but use fast C loader if available."""
return yaml.load(stream, Loader=_safe_loader) # type: ignore
return yaml.load(stream, Loader=_safe_loader) # type: ignore # noqa: S506


def safe_dump(data: Any, stream: Optional[TextIO] = None) -> str:
Expand Down
27 changes: 12 additions & 15 deletions ops/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ class StartEvent(HookEvent):

This event is triggered immediately after the first
:class:`ConfigChangedEvent`. Callback methods bound to the event should be
used to ensure that the charms software is in a running state. Note that
the charms software should be configured so as to persist in this state
through reboots without further intervention on Jujus part.
used to ensure that the charm's software is in a running state. Note that
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
the charm's software should be configured so as to persist in this state
through reboots without further intervention on Juju's part.
"""


Expand All @@ -237,8 +237,8 @@ class StopEvent(HookEvent):

This event is triggered when an application's removal is requested
by the client. The event fires immediately before the end of the
units destruction sequence. Callback methods bound to this event
should be used to ensure that the charms software is not running,
unit's destruction sequence. Callback methods bound to this event
should be used to ensure that the charm's software is not running,
and that it will not start again on reboot.
"""

Expand Down Expand Up @@ -507,7 +507,7 @@ class RelationChangedEvent(RelationEvent):
are incomplete, since it can be guaranteed that when the remote unit or
application changes its settings, the event will fire again.

The settings that may be queried, or set, are determined by the relations
The settings that may be queried, or set, are determined by the relation's
interface.
"""

Expand All @@ -522,8 +522,8 @@ class RelationDepartedEvent(RelationEvent):
emitted once for each remaining unit.

Callback methods bound to this event may be used to remove all
references to the departing remote unit, because theres no
guarantee that its still part of the system; its perfectly
references to the departing remote unit, because there's no
guarantee that it's still part of the system; it's perfectly
probable (although not guaranteed) that the system running that
unit has already shut down.

Expand Down Expand Up @@ -581,7 +581,7 @@ class RelationBrokenEvent(RelationEvent):
fire to signal that the relationship has been fully terminated.

The event indicates that the current relation is no longer valid, and that
the charms software must be configured as though the relation had never
the charm's software must be configured as though the relation had never
existed. It will only be called after every callback method bound to
:class:`RelationDepartedEvent` has been run. If a callback method
bound to this event is being executed, it is guaranteed that no remote units
Expand Down Expand Up @@ -630,16 +630,15 @@ def restore(self, snapshot: Dict[str, Any]):

if storage_name and storage_index is not None:
storages = self.framework.model.storages[storage_name]
self.storage = next((s for s in storages if s.index == storage_index), None) # type: ignore # noqa
self.storage = next((s for s in storages if s.index == storage_index), None) # type: ignore
if self.storage is None:
msg = 'failed loading storage (name={!r}, index={!r}) from snapshot' \
.format(storage_name, storage_index)
raise RuntimeError(msg)
if storage_location is None:
raise RuntimeError(
'failed loading storage location from snapshot.'
'(name={!r}, index={!r}, storage_location=None)'
.format(storage_name, storage_index))
f'(name={storage_name!r}, index={storage_index!r}, storage_location=None)')

self.storage.location = storage_location

Expand Down Expand Up @@ -969,9 +968,7 @@ def _on_collect_status(self, event: ops.CollectStatusEvent):
event.add_status(ops.BlockedStatus('please set "port" config'))
return
event.add_status(ops.ActiveStatus())

.. # noqa (pydocstyle barfs on the above for unknown reasons I've spent hours on)
"""
""" # noqa: D405, D214, D411, D416 Final return confuses docstyle

def add_status(self, status: model.StatusBase):
"""Add a status for evaluation.
Expand Down
4 changes: 2 additions & 2 deletions ops/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ class Serializable(typing.Protocol):
@property
def handle(self) -> 'Handle': ... # noqa
@handle.setter
def handle(self, val: 'Handle'): ... # noqa
def handle(self, val: 'Handle'): ...
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
def snapshot(self) -> Dict[str, Any]: ... # noqa
def restore(self, snapshot: Dict[str, Any]) -> None: ... # noqa


class _StoredObject(Protocol):
_under: Any = None # noqa
_under: Any = None


StoredObject = Union['StoredList', 'StoredSet', 'StoredDict']
Expand Down
12 changes: 6 additions & 6 deletions ops/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from types import ModuleType
from typing import List

__all__ = ('use', 'autoimport')
__all__ = ('autoimport', 'use')

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -182,7 +182,7 @@ def _join_and(keys: List[str]) -> str:
class _Missing:
"""Helper to get the difference between what was found and what was needed when logging."""

def __init__(self, found):
def __init__(self, found: bool):
self._found = found

def __str__(self):
Expand All @@ -202,7 +202,7 @@ def _parse_lib(spec: ModuleSpec) -> typing.Optional["_Lib"]:
logger.debug(" Parsing %r", spec.name)

try:
with open(spec.origin, 'rt', encoding='utf-8') as f:
with open(spec.origin, encoding='utf-8') as f:
libinfo = {}
for n, line in enumerate(f):
if len(libinfo) == len(_NEEDED_KEYS):
Expand Down Expand Up @@ -255,7 +255,7 @@ def __repr__(self):
return f"<_Lib {self}>"

def __str__(self):
return "{0.name} by {0.author}, API {0.api}, patch {0.patch}".format(self)
return f"{self.name} by {self.author}, API {self.api}, patch {self.patch}"

def import_module(self) -> ModuleType:
if self._module is None:
Expand All @@ -264,14 +264,14 @@ def import_module(self) -> ModuleType:
self._module = module
return self._module

def __eq__(self, other):
def __eq__(self, other): # noqa: ANN001
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
if not isinstance(other, _Lib):
return NotImplemented
a = (self.name, self.author, self.api, self.patch)
b = (other.name, other.author, other.api, other.patch)
return a == b

def __lt__(self, other):
def __lt__(self, other): # noqa: ANN001
if not isinstance(other, _Lib):
return NotImplemented
a = (self.name, self.author, self.api, self.patch)
Expand Down
5 changes: 1 addition & 4 deletions ops/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,7 @@ def main(charm_class: Type[ops.charm.CharmBase],

metadata = (charm_dir / 'metadata.yaml').read_text()
actions_meta = charm_dir / 'actions.yaml'
if actions_meta.exists():
actions_metadata = actions_meta.read_text()
else:
actions_metadata = None
actions_metadata = actions_meta.read_text() if actions_meta.exists() else None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this a drive-by, or something the tool caught? I don't mind this change, but just wanting to reduce additional changes in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's something the tool caught, but could be skipped to make the PR minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left it in for this PR where it fits more (general minor improvements caught by a few extra linters) than in the first one (strictly migrate to ruff).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first I think we should disable this one, but looking over the PR I think it's almost always an improvement, so this seems reasonable to keep enabled.


# If we are in a RelationBroken event, we want to know which relation is
# broken within the model, not only in the event's `.relation` attribute.
Expand Down
Loading