Skip to content

Commit 42247ba

Browse files
authored
Enable ruff D ruleset for pydocstyle static analysis of docstring conventions (#1429)
1 parent 71d8f57 commit 42247ba

File tree

9 files changed

+62
-38
lines changed

9 files changed

+62
-38
lines changed

cmd2/argparse_custom.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ class CompletionItem(str): # noqa: SLOT000
282282
"""
283283

284284
def __new__(cls, value: object, *_args: Any, **_kwargs: Any) -> 'CompletionItem':
285+
"""Responsible for creating and returning a new instance, called before __init__ when an object is instantiated."""
285286
return super().__new__(cls, value)
286287

287288
def __init__(self, value: object, description: str = '', *args: Any) -> None:
@@ -313,14 +314,16 @@ def orig_value(self) -> Any:
313314
class ChoicesProviderFuncBase(Protocol):
314315
"""Function that returns a list of choices in support of tab completion."""
315316

316-
def __call__(self) -> list[str]: ... # pragma: no cover
317+
def __call__(self) -> list[str]: # pragma: no cover
318+
"""Enable instances to be called like functions."""
317319

318320

319321
@runtime_checkable
320322
class ChoicesProviderFuncWithTokens(Protocol):
321323
"""Function that returns a list of choices in support of tab completion and accepts a dictionary of prior arguments."""
322324

323-
def __call__(self, *, arg_tokens: dict[str, list[str]] = {}) -> list[str]: ... # pragma: no cover # noqa: B006
325+
def __call__(self, *, arg_tokens: dict[str, list[str]] = {}) -> list[str]: # pragma: no cover # noqa: B006
326+
"""Enable instances to be called like functions."""
324327

325328

326329
ChoicesProviderFunc = Union[ChoicesProviderFuncBase, ChoicesProviderFuncWithTokens]
@@ -336,7 +339,8 @@ def __call__(
336339
line: str,
337340
begidx: int,
338341
endidx: int,
339-
) -> list[str]: ... # pragma: no cover
342+
) -> list[str]: # pragma: no cover
343+
"""Enable instances to be called like functions."""
340344

341345

342346
@runtime_checkable
@@ -351,7 +355,8 @@ def __call__(
351355
endidx: int,
352356
*,
353357
arg_tokens: dict[str, list[str]] = {}, # noqa: B006
354-
) -> list[str]: ... # pragma: no cover
358+
) -> list[str]: # pragma: no cover
359+
"""Enable instances to be called like functions."""
355360

356361

357362
CompleterFunc = Union[CompleterFuncBase, CompleterFuncWithTokens]
@@ -391,13 +396,15 @@ def __init__(
391396

392397
@property
393398
def completer(self) -> CompleterFunc:
399+
"""Retreive the internal Completer function, first type checking to ensure it is the right type."""
394400
if not isinstance(self.to_call, (CompleterFuncBase, CompleterFuncWithTokens)): # pragma: no cover
395401
# this should've been caught in the constructor, just a backup check
396402
raise TypeError('Function is not a CompleterFunc')
397403
return self.to_call
398404

399405
@property
400406
def choices_provider(self) -> ChoicesProviderFunc:
407+
"""Retreive the internal ChoicesProvider function, first type checking to ensure it is the right type."""
401408
if not isinstance(self.to_call, (ChoicesProviderFuncBase, ChoicesProviderFuncWithTokens)): # pragma: no cover
402409
# this should've been caught in the constructor, just a backup check
403410
raise TypeError('Function is not a ChoicesProviderFunc')
@@ -1350,6 +1357,7 @@ class Cmd2AttributeWrapper:
13501357
"""
13511358

13521359
def __init__(self, attribute: Any) -> None:
1360+
"""Initialize Cmd2AttributeWrapper instances."""
13531361
self.__attribute = attribute
13541362

13551363
def get(self) -> Any:

cmd2/cmd2.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,8 @@ def ppaged(self, msg: Any, *, end: str = '\n', chop: bool = False) -> None:
13411341
# ----- Methods related to tab completion -----
13421342

13431343
def _reset_completion_defaults(self) -> None:
1344-
"""Resets tab completion settings
1344+
"""Reset tab completion settings.
1345+
13451346
Needs to be called each time readline runs tab completion.
13461347
"""
13471348
self.allow_appended_space = True
@@ -2406,47 +2407,43 @@ def _raise_keyboard_interrupt(self) -> None:
24062407
raise KeyboardInterrupt("Got a keyboard interrupt")
24072408

24082409
def precmd(self, statement: Union[Statement, str]) -> Statement:
2409-
"""Hook method executed just before the command is executed by
2410-
[cmd2.Cmd.onecmd][] and after adding it to history.
2410+
"""Ran just before the command is executed by [cmd2.Cmd.onecmd][] and after adding it to history (cmd Hook method).
24112411
24122412
:param statement: subclass of str which also contains the parsed input
24132413
:return: a potentially modified version of the input Statement object
24142414
2415-
See [cmd2.Cmd.register_postparsing_hook][] and
2416-
[cmd2.Cmd.register_precmd_hook][] for more robust ways
2417-
to run hooks before the command is executed. See
2418-
[Hooks](../features/hooks.md) for more information.
2415+
See [cmd2.Cmd.register_postparsing_hook][] and [cmd2.Cmd.register_precmd_hook][] for more robust ways
2416+
to run hooks before the command is executed. See [Hooks](../features/hooks.md) for more information.
24192417
"""
24202418
return Statement(statement) if not isinstance(statement, Statement) else statement
24212419

24222420
def postcmd(self, stop: bool, statement: Union[Statement, str]) -> bool: # noqa: ARG002
2423-
"""Hook method executed just after a command is executed by
2424-
[cmd2.Cmd.onecmd][].
2421+
"""Ran just after a command is executed by [cmd2.Cmd.onecmd][] (cmd inherited Hook method).
24252422
24262423
:param stop: return `True` to request the command loop terminate
24272424
:param statement: subclass of str which also contains the parsed input
24282425
24292426
See [cmd2.Cmd.register_postcmd_hook][] and [cmd2.Cmd.register_cmdfinalization_hook][] for more robust ways
2430-
to run hooks after the command is executed. See
2431-
[Hooks](../features/hooks.md) for more information.
2427+
to run hooks after the command is executed. See [Hooks](../features/hooks.md) for more information.
24322428
"""
24332429
return stop
24342430

24352431
def preloop(self) -> None:
2436-
"""Hook method executed once when the [cmd2.Cmd.cmdloop][]
2437-
method is called.
2432+
"""Ran once when the [cmd2.Cmd.cmdloop][] method is called (cmd inherited Hook method).
2433+
2434+
This method is a stub that does nothing and exists to be overridden by subclasses.
24382435
2439-
See [cmd2.Cmd.register_preloop_hook][] for a more robust way
2440-
to run hooks before the command loop begins. See
2441-
[Hooks](../features/hooks.md) for more information.
2436+
See [cmd2.Cmd.register_preloop_hook][] for a more robust wayto run hooks before the command loop begins.
2437+
See [Hooks](../features/hooks.md) for more information.
24422438
"""
24432439

24442440
def postloop(self) -> None:
2445-
"""Hook method executed once when the [cmd2.Cmd.cmdloop][] method is about to return.
2441+
"""Ran once when the [cmd2.Cmd.cmdloop][] method is about to return (cmd inherited Hook Method).
2442+
2443+
This method is a stub that does nothing and exists to be overridden by subclasses.
24462444
2447-
See [cmd2.Cmd.register_postloop_hook][] for a more robust way
2448-
to run hooks after the command loop completes. See
2449-
[Hooks](../features/hooks.md) for more information.
2445+
See [cmd2.Cmd.register_postloop_hook][] for a more robust way to run hooks after the command loop completes.
2446+
See [Hooks](../features/hooks.md) for more information.
24502447
"""
24512448

24522449
def parseline(self, line: str) -> tuple[str, str, str]:

cmd2/command_definition.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ class CommandSet:
8686
"""
8787

8888
def __init__(self) -> None:
89-
# Private reference to the CLI instance in which this CommandSet running.
90-
# This will be set when the CommandSet is registered and it should be
91-
# accessed by child classes using the self._cmd property.
89+
"""Private reference to the CLI instance in which this CommandSet running.
90+
91+
This will be set when the CommandSet is registered and it should be
92+
accessed by child classes using the self._cmd property.
93+
"""
9294
self.__cmd_internal: Optional[cmd2.Cmd] = None
9395

9496
self._settables: dict[str, Settable] = {}
@@ -147,10 +149,12 @@ def on_unregistered(self) -> None:
147149

148150
@property
149151
def settable_prefix(self) -> str:
152+
"""Read-only accessor for the underlying private settable_prefix field."""
150153
return self._settable_prefix
151154

152155
@property
153156
def settables(self) -> Mapping[str, Settable]:
157+
"""Read-only accessor for the underlying private settables field."""
154158
return self._settables
155159

156160
def add_settable(self, settable: Settable) -> None:

cmd2/decorators.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333

3434
def with_category(category: str) -> Callable[[CommandFunc], CommandFunc]:
35-
"""A decorator to apply a category to a ``do_*`` command method.
35+
"""Decorate a ``do_*`` command method to apply a category.
3636
3737
:param category: the name of the category in which this command should
3838
be grouped when displaying the list of commands.
@@ -138,7 +138,7 @@ def with_argument_list(
138138
RawCommandFuncOptionalBoolReturn[CommandParent],
139139
Callable[[ArgListCommandFunc[CommandParent]], RawCommandFuncOptionalBoolReturn[CommandParent]],
140140
]:
141-
"""A decorator to alter the arguments passed to a ``do_*`` method.
141+
"""Decorate a ``do_*`` method to alter the arguments passed to it so it is passed a list[str].
142142
143143
Default passes a string of whatever the user typed. With this decorator, the
144144
decorated method will receive a list of arguments parsed from user input.
@@ -160,7 +160,8 @@ def do_echo(self, arglist):
160160
import functools
161161

162162
def arg_decorator(func: ArgListCommandFunc[CommandParent]) -> RawCommandFuncOptionalBoolReturn[CommandParent]:
163-
"""Decorator function that ingests an Argument List function and returns a raw command function.
163+
"""Decorate function that ingests an Argument List function and returns a raw command function.
164+
164165
The returned function will process the raw input into an argument list to be passed to the wrapped function.
165166
166167
:param func: The defined argument list command function
@@ -278,8 +279,7 @@ def with_argparser(
278279
preserve_quotes: bool = False,
279280
with_unknown_args: bool = False,
280281
) -> Callable[[ArgparseCommandFunc[CommandParent]], RawCommandFuncOptionalBoolReturn[CommandParent]]:
281-
"""A decorator to alter a cmd2 method to populate its ``args`` argument by parsing arguments
282-
with the given instance of argparse.ArgumentParser.
282+
"""Decorate a ``do_*`` method to populate its ``args`` argument with the given instance of argparse.ArgumentParser.
283283
284284
:param parser: unique instance of ArgumentParser or a callable that returns an ArgumentParser
285285
:param ns_provider: An optional function that accepts a cmd2.Cmd or cmd2.CommandSet object as an argument and returns an
@@ -327,7 +327,8 @@ def do_argprint(self, args, unknown):
327327
import functools
328328

329329
def arg_decorator(func: ArgparseCommandFunc[CommandParent]) -> RawCommandFuncOptionalBoolReturn[CommandParent]:
330-
"""Decorator function that ingests an Argparse Command Function and returns a raw command function.
330+
"""Decorate function that ingests an Argparse Command Function and returns a raw command function.
331+
331332
The returned function will process the raw input into an argparse Namespace to be passed to the wrapped function.
332333
333334
:param func: The defined argparse command function

cmd2/history.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class to gain access to the historical record.
156156
_history_items_field = 'history_items'
157157

158158
def __init__(self, seq: Iterable[HistoryItem] = ()) -> None:
159+
"""Initialize History instances."""
159160
super().__init__(seq)
160161
self.session_start_index = 0
161162

cmd2/py_bridge.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class PyBridge:
8787
"""
8888

8989
def __init__(self, cmd2_app: 'cmd2.Cmd', *, add_to_history: bool = True) -> None:
90+
"""Initialize PyBridge instances."""
9091
self._cmd2_app = cmd2_app
9192
self._add_to_history = add_to_history
9293
self.cmd_echo = False

cmd2/transcript.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Cmd2TestCase(unittest.TestCase):
4242
cmdapp: Optional['Cmd'] = None
4343

4444
def setUp(self) -> None:
45+
"""Instructions that will be executed before each test method."""
4546
if self.cmdapp:
4647
self._fetch_transcripts()
4748

@@ -50,11 +51,13 @@ def setUp(self) -> None:
5051
self.cmdapp.stdout = cast(TextIO, utils.StdSim(cast(TextIO, self.cmdapp.stdout)))
5152

5253
def tearDown(self) -> None:
54+
"""Instructions that will be executed after each test method."""
5355
if self.cmdapp:
5456
# Restore stdout
5557
self.cmdapp.stdout = self._orig_stdout
5658

5759
def runTest(self) -> None: # was testall # noqa: N802
60+
"""Override of the default runTest method for the unittest.TestCase class."""
5861
if self.cmdapp:
5962
its = sorted(self.transcripts.items())
6063
for fname, transcript in its:

cmd2/utils.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ def line_buffering(self) -> bool:
528528
return False
529529

530530
def __getattr__(self, item: str) -> Any:
531+
"""When an attribute lookup fails to find the attribute in the usual places, this special method is called."""
531532
if item in self.__dict__:
532533
return self.__dict__[item]
533534
return getattr(self.inner_stream, item)
@@ -540,6 +541,7 @@ class ByteBuf:
540541
NEWLINES = (b'\n', b'\r')
541542

542543
def __init__(self, std_sim_instance: StdSim) -> None:
544+
"""Initialize the ByteBuf instance."""
543545
self.byte_buf = bytearray()
544546
self.std_sim_instance = std_sim_instance
545547

@@ -671,17 +673,22 @@ class ContextFlag:
671673
"""
672674

673675
def __init__(self) -> None:
674-
# When this flag has a positive value, it is considered set.
675-
# When it is 0, it is not set. It should never go below 0.
676+
"""When this flag has a positive value, it is considered set. When it is 0, it is not set.
677+
678+
It should never go below 0.
679+
"""
676680
self.__count = 0
677681

678682
def __bool__(self) -> bool:
683+
"""Define the truth value of an object when it is used in a boolean context."""
679684
return self.__count > 0
680685

681686
def __enter__(self) -> None:
687+
"""When a with block is entered, the __enter__ method of the context manager is called."""
682688
self.__count += 1
683689

684690
def __exit__(self, *args: object) -> None:
691+
"""When the execution flow exits a with statement block this is called, regardless of whether an exception occurred."""
685692
self.__count -= 1
686693
if self.__count < 0:
687694
raise ValueError("count has gone below 0")
@@ -1224,8 +1231,10 @@ def strip_doc_annotations(doc: str) -> str:
12241231

12251232

12261233
def similarity_function(s1: str, s2: str) -> float:
1227-
# The ratio from s1,s2 may be different to s2,s1. We keep the max.
1228-
# See https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.ratio
1234+
"""Ratio from s1,s2 may be different to s2,s1. We keep the max.
1235+
1236+
See https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.ratio
1237+
"""
12291238
return max(SequenceMatcher(None, s1, s2).ratio(), SequenceMatcher(None, s2, s1).ratio())
12301239

12311240

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ select = [
168168
"C90", # McCabe cyclomatic complexity (warn about functions that are too complex)
169169
"COM", # flake8-commas (forces commas at the end of every type of iterable/container
170170
# "CPY", # flake8-copyright (warn about missing copyright notice at top of file - currently in preview)
171-
# "D", # pydocstyle (warn about things like missing docstrings)
171+
"D", # pydocstyle (warn about things like missing docstrings)
172172
# "DOC", # pydoclint (docstring warnings - currently in preview)
173173
# "DJ", # flake8-django (Django-specific warnings)
174174
"DTZ", # flake8-datetimez (warn about datetime calls where no timezone is specified)

0 commit comments

Comments
 (0)