Skip to content

Commit e735336

Browse files
committed
Some style improvements to docstrings/API Reference
1 parent 2304a0f commit e735336

File tree

4 files changed

+107
-88
lines changed

4 files changed

+107
-88
lines changed

docs/api_reference.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
:orphan:
22

3-
Api Reference
3+
API Reference
44
=============
55

66
.. automodule:: pluggy
77
:members:
88
:undoc-members:
9-
:show-inheritance:
109

1110
.. autoclass:: pluggy._callers._Result
1211
.. automethod:: pluggy._callers._Result.get_result

src/pluggy/_hooks.py

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ class _HookImplOpts(TypedDict):
5353

5454

5555
class HookspecMarker:
56-
"""Decorator helper class for marking functions as hook specifications.
56+
"""Decorator for marking functions as hook specifications.
5757
58-
You can instantiate it with a project_name to get a decorator.
59-
Calling :py:meth:`.PluginManager.add_hookspecs` later will discover all marked functions
60-
if the :py:class:`.PluginManager` uses the same project_name.
58+
Instantiate it with a project_name to get a decorator.
59+
Calling :meth:`PluginManager.add_hookspecs` later will discover all marked
60+
functions if the :class:`PluginManager` uses the same project_name.
6161
"""
6262

6363
__slots__ = ("project_name",)
@@ -92,18 +92,18 @@ def __call__( # noqa: F811
9292
historic: bool = False,
9393
warn_on_impl: Optional[Warning] = None,
9494
) -> Union[_F, Callable[[_F], _F]]:
95-
"""if passed a function, directly sets attributes on the function
96-
which will make it discoverable to :py:meth:`.PluginManager.add_hookspecs`.
97-
If passed no function, returns a decorator which can be applied to a function
98-
later using the attributes supplied.
95+
"""If passed a function, directly sets attributes on the function
96+
which will make it discoverable to :meth:`PluginManager.add_hookspecs`.
9997
100-
If ``firstresult`` is ``True`` the 1:N hook call (N being the number of registered
101-
hook implementation functions) will stop at I<=N when the I'th function
102-
returns a non-``None`` result.
98+
If passed no function, returns a decorator which can be applied to a
99+
function later using the attributes supplied.
103100
104-
If ``historic`` is ``True`` calls to a hook will be memorized and replayed
105-
on later registered plugins.
101+
If ``firstresult`` is ``True``, the 1:N hook call (N being the number of
102+
registered hook implementation functions) will stop at I<=N when the
103+
I'th function returns a non-``None`` result.
106104
105+
If ``historic`` is ``True``, every call to the hook will be memorized
106+
and replayed on plugins registered after the call was made.
107107
"""
108108

109109
def setattr_hookspec_opts(func: _F) -> _F:
@@ -124,11 +124,11 @@ def setattr_hookspec_opts(func: _F) -> _F:
124124

125125

126126
class HookimplMarker:
127-
"""Decorator helper class for marking functions as hook implementations.
127+
"""Decorator for marking functions as hook implementations.
128128
129-
You can instantiate with a ``project_name`` to get a decorator.
130-
Calling :py:meth:`.PluginManager.register` later will discover all marked functions
131-
if the :py:class:`.PluginManager` uses the same project_name.
129+
Instantiate it with a ``project_name`` to get a decorator.
130+
Calling :meth:`PluginManager.register` later will discover all marked
131+
functions if the :class:`PluginManager` uses the same project_name.
132132
"""
133133

134134
__slots__ = ("project_name",)
@@ -169,30 +169,33 @@ def __call__( # noqa: F811
169169
trylast: bool = False,
170170
specname: Optional[str] = None,
171171
) -> Union[_F, Callable[[_F], _F]]:
172-
"""if passed a function, directly sets attributes on the function
173-
which will make it discoverable to :py:meth:`.PluginManager.register`.
172+
"""If passed a function, directly sets attributes on the function
173+
which will make it discoverable to :meth:`PluginManager.register`.
174+
174175
If passed no function, returns a decorator which can be applied to a
175176
function later using the attributes supplied.
176177
177-
If ``optionalhook`` is ``True`` a missing matching hook specification will not result
178-
in an error (by default it is an error if no matching spec is found).
179-
180-
If ``tryfirst`` is ``True`` this hook implementation will run as early as possible
181-
in the chain of N hook implementations for a specification.
178+
If ``optionalhook`` is ``True``, a missing matching hook specification
179+
will not result in an error (by default it is an error if no matching
180+
spec is found).
182181
183-
If ``trylast`` is ``True`` this hook implementation will run as late as possible
184-
in the chain of N hook implementations.
182+
If ``tryfirst`` is ``True``, this hook implementation will run as early
183+
as possible in the chain of N hook implementations for a specification.
185184
186-
If ``hookwrapper`` is ``True`` the hook implementations needs to execute exactly
187-
one ``yield``. The code before the ``yield`` is run early before any non-hookwrapper
188-
function is run. The code after the ``yield`` is run after all non-hookwrapper
189-
function have run. The ``yield`` receives a :py:class:`.callers._Result` object
190-
representing the exception or result outcome of the inner calls (including other
191-
hookwrapper calls).
185+
If ``trylast`` is ``True``, this hook implementation will run as late as
186+
possible in the chain of N hook implementations.
192187
193-
If ``specname`` is provided, it will be used instead of the function name when
194-
matching this hook implementation to a hook specification during registration.
188+
If ``hookwrapper`` is ``True``, the hook implementations needs to
189+
execute exactly one ``yield``. The code before the ``yield`` is run
190+
early before any non-hookwrapper function is run. The code after the
191+
``yield`` is run after all non-hookwrapper function have run The
192+
``yield`` receives a :class:`_Result` object representing the exception
193+
or result outcome of the inner calls (including other hookwrapper
194+
calls).
195195
196+
If ``specname`` is provided, it will be used instead of the function
197+
name when matching this hook implementation to a hook specification
198+
during registration.
196199
"""
197200

198201
def setattr_hookimpl_opts(func: _F) -> _F:
@@ -268,7 +271,7 @@ def varnames(func: object) -> Tuple[Tuple[str, ...], Tuple[str, ...]]:
268271

269272

270273
class _HookRelay:
271-
"""hook holder object for performing 1:N hook calls where N is the number
274+
"""Hook holder object for performing 1:N hook calls where N is the number
272275
of registered plugins."""
273276

274277
__slots__ = ("__dict__",)
@@ -396,7 +399,7 @@ def call_historic(
396399
"""Call the hook with given ``kwargs`` for all registered plugins and
397400
for all plugins which will be registered afterwards.
398401
399-
If ``result_callback`` is not ``None`` it will be called for for each
402+
If ``result_callback`` is provided, it will be called for each
400403
non-``None`` result obtained from a hook implementation.
401404
"""
402405
assert self._call_history is not None

src/pluggy/_manager.py

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,14 @@ def _warn_for_function(warning: Warning, function: Callable[..., object]) -> Non
5858

5959

6060
class PluginValidationError(Exception):
61-
"""plugin failed validation.
61+
"""Plugin failed validation.
6262
63-
:param object plugin: the plugin which failed validation,
64-
may be a module or an arbitrary object.
63+
:param plugin: The plugin which failed validation.
6564
"""
6665

6766
def __init__(self, plugin: _Plugin, message: str) -> None:
67+
super().__init__(message)
6868
self.plugin = plugin
69-
super(Exception, self).__init__(message)
7069

7170

7271
class DistFacade:
@@ -88,17 +87,16 @@ def __dir__(self) -> List[str]:
8887

8988

9089
class PluginManager:
91-
"""Core :py:class:`.PluginManager` class which manages registration
92-
of plugin objects and 1:N hook calling.
90+
"""Core class which manages registration of plugin objects and 1:N hook
91+
calling.
9392
94-
You can register new hooks by calling :py:meth:`add_hookspecs(module_or_class)
95-
<.PluginManager.add_hookspecs>`.
96-
You can register plugin objects (which contain hooks) by calling
97-
:py:meth:`register(plugin) <.PluginManager.register>`. The :py:class:`.PluginManager`
98-
is initialized with a prefix that is searched for in the names of the dict
99-
of registered plugin objects.
93+
You can register new hooks by calling :meth:`add_hookspecs(module_or_class)
94+
<PluginManager.add_hookspecs>`.
10095
101-
For debugging purposes you can call :py:meth:`.PluginManager.enable_tracing`
96+
You can register plugin objects (which contain hook implementations) by
97+
calling :meth:`register(plugin) <PluginManager.register>`.
98+
99+
For debugging purposes you can call :meth:`PluginManager.enable_tracing`
102100
which will subsequently send debug information to the trace helper.
103101
"""
104102

@@ -132,9 +130,15 @@ def _hookexec(
132130
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
133131

134132
def register(self, plugin: _Plugin, name: Optional[str] = None) -> Optional[str]:
135-
"""Register a plugin and return its canonical name or ``None`` if the name
136-
is blocked from registering. Raise a :py:class:`ValueError` if the plugin
137-
is already registered."""
133+
"""Register a plugin and return its name.
134+
135+
If a name is not specified, a name is generated using
136+
:func:`get_canonical_name`.
137+
138+
If the name is blocked from registering, returns ``None``.
139+
140+
If the plugin is already registered, raises a :class:`ValueError`.
141+
"""
138142
plugin_name = name or self.get_canonical_name(plugin)
139143

140144
if plugin_name in self._name2plugin:
@@ -193,8 +197,11 @@ def parse_hookimpl_opts(
193197
def unregister(
194198
self, plugin: Optional[_Plugin] = None, name: Optional[str] = None
195199
) -> _Plugin:
196-
"""unregister a plugin object and all its contained hook implementations
197-
from internal data structures."""
200+
"""Unregister a plugin and all of its hook implementations.
201+
202+
The plugin can be specified either by the plugin object or the plugin
203+
name. If both are specified, they must agree.
204+
"""
198205
if name is None:
199206
assert plugin is not None, "one of name or plugin needs to be specified"
200207
name = self.get_name(plugin)
@@ -216,17 +223,20 @@ def unregister(
216223
return plugin
217224

218225
def set_blocked(self, name: str) -> None:
219-
"""block registrations of the given name, unregister if already registered."""
226+
"""Block registrations of the given name, unregister if already registered."""
220227
self.unregister(name=name)
221228
self._name2plugin[name] = None
222229

223230
def is_blocked(self, name: str) -> bool:
224-
"""return ``True`` if the given plugin name is blocked."""
231+
"""Return whether the given plugin name is blocked."""
225232
return name in self._name2plugin and self._name2plugin[name] is None
226233

227234
def add_hookspecs(self, module_or_class: _Namespace) -> None:
228-
"""add new hook specifications defined in the given ``module_or_class``.
229-
Functions are recognized if they have been decorated accordingly."""
235+
"""Add new hook specifications defined in the given ``module_or_class``.
236+
237+
Functions are recognized as hook specifications if they have been
238+
decorated with a matching :class:`HookspecMarker`.
239+
"""
230240
names = []
231241
for name in dir(module_or_class):
232242
spec_opts = self.parse_hookspec_opts(module_or_class, name)
@@ -236,7 +246,7 @@ def add_hookspecs(self, module_or_class: _Namespace) -> None:
236246
hc = _HookCaller(name, self._hookexec, module_or_class, spec_opts)
237247
setattr(self.hook, name, hc)
238248
else:
239-
# plugins registered this hook without knowing the spec
249+
# Plugins registered this hook without knowing the spec.
240250
hc.set_specification(module_or_class, spec_opts)
241251
for hookfunction in hc.get_hookimpls():
242252
self._verify_hook(hc, hookfunction)
@@ -257,32 +267,35 @@ def parse_hookspec_opts(
257267
return opts
258268

259269
def get_plugins(self) -> Set[Any]:
260-
"""return the set of registered plugins."""
270+
"""Return a set of all registered plugin objects."""
261271
return set(self._name2plugin.values())
262272

263273
def is_registered(self, plugin: _Plugin) -> bool:
264-
"""Return ``True`` if the plugin is already registered."""
274+
"""Return whether the plugin is already registered."""
265275
return any(plugin == val for val in self._name2plugin.values())
266276

267277
def get_canonical_name(self, plugin: _Plugin) -> str:
268-
"""Return canonical name for a plugin object. Note that a plugin
269-
may be registered under a different name which was specified
270-
by the caller of :py:meth:`register(plugin, name) <.PluginManager.register>`.
271-
To obtain the name of an registered plugin use :py:meth:`get_name(plugin)
272-
<.PluginManager.get_name>` instead."""
278+
"""Return a canonical name for a plugin object.
279+
280+
Note that a plugin may be registered under a different name
281+
specified by the caller of :meth:`register(plugin, name) <register>`.
282+
To obtain the name of n registered plugin use :meth:`get_name(plugin)
283+
<get_name>` instead.
284+
"""
273285
name: Optional[str] = getattr(plugin, "__name__", None)
274286
return name or str(id(plugin))
275287

276288
def get_plugin(self, name: str) -> Optional[Any]:
277-
"""Return a plugin or ``None`` for the given name."""
289+
"""Return the plugin registered under the given name, if any."""
278290
return self._name2plugin.get(name)
279291

280292
def has_plugin(self, name: str) -> bool:
281-
"""Return ``True`` if a plugin with the given name is registered."""
293+
"""Return whether a plugin with the given name is registered."""
282294
return self.get_plugin(name) is not None
283295

284296
def get_name(self, plugin: _Plugin) -> Optional[str]:
285-
"""Return name for registered plugin or ``None`` if not registered."""
297+
"""Return the name the plugin is registered under, or ``None`` if
298+
is isn't."""
286299
for name, val in self._name2plugin.items():
287300
if plugin == val:
288301
return name
@@ -325,8 +338,9 @@ def _verify_hook(self, hook: _HookCaller, hookimpl: HookImpl) -> None:
325338
)
326339

327340
def check_pending(self) -> None:
328-
"""Verify that all hooks which have not been verified against
329-
a hook specification are optional, otherwise raise :py:class:`.PluginValidationError`."""
341+
"""Verify that all hooks which have not been verified against a
342+
hook specification are optional, otherwise raise
343+
:class:`PluginValidationError`."""
330344
for name in self.hook.__dict__:
331345
if name[0] != "_":
332346
hook: _HookCaller = getattr(self.hook, name)
@@ -344,10 +358,10 @@ def load_setuptools_entrypoints(
344358
) -> int:
345359
"""Load modules from querying the specified setuptools ``group``.
346360
347-
:param str group: entry point group to load plugins
348-
:param str name: if given, loads only plugins with the given ``name``.
361+
:param str group: Entry point group to load plugins.
362+
:param str name: If given, loads only plugins with the given ``name``.
349363
:rtype: int
350-
:return: return the number of loaded plugins by this call.
364+
:return: The number of plugins loaded by this call.
351365
"""
352366
count = 0
353367
for dist in list(importlib_metadata.distributions()):
@@ -367,16 +381,16 @@ def load_setuptools_entrypoints(
367381
return count
368382

369383
def list_plugin_distinfo(self) -> List[Tuple[_Plugin, DistFacade]]:
370-
"""return list of distinfo/plugin tuples for all setuptools registered
371-
plugins."""
384+
"""Return a list of (plugin, distinfo) pairs for all
385+
setuptools-registered plugins."""
372386
return list(self._plugin_distinfo)
373387

374388
def list_name_plugin(self) -> List[Tuple[str, _Plugin]]:
375-
"""return list of name/plugin pairs."""
389+
"""Return a list of (name, plugin) pairs for all registered plugins."""
376390
return list(self._name2plugin.items())
377391

378392
def get_hookcallers(self, plugin: _Plugin) -> Optional[List[_HookCaller]]:
379-
"""get all hook callers for the specified plugin."""
393+
"""Get all hook callers for the specified plugin."""
380394
if self.get_name(plugin) is None:
381395
return None
382396
hookcallers = []
@@ -389,16 +403,16 @@ def get_hookcallers(self, plugin: _Plugin) -> Optional[List[_HookCaller]]:
389403
def add_hookcall_monitoring(
390404
self, before: _BeforeTrace, after: _AfterTrace
391405
) -> Callable[[], None]:
392-
"""add before/after tracing functions for all hooks
393-
and return an undo function which, when called,
394-
will remove the added tracers.
406+
"""Add before/after tracing functions for all hooks.
407+
408+
Returns an undo function which, when called, removes the added tracers.
395409
396410
``before(hook_name, hook_impls, kwargs)`` will be called ahead
397411
of all hook calls and receive a hookcaller instance, a list
398412
of HookImpl instances and the keyword arguments for the hook call.
399413
400414
``after(outcome, hook_name, hook_impls, kwargs)`` receives the
401-
same arguments as ``before`` but also a :py:class:`pluggy._callers._Result` object
415+
same arguments as ``before`` but also a :class:`_Result` object
402416
which represents the result of the overall hook call.
403417
"""
404418
oldcall = self._inner_hookexec
@@ -424,7 +438,10 @@ def undo() -> None:
424438
return undo
425439

426440
def enable_tracing(self) -> Callable[[], None]:
427-
"""enable tracing of hook calls and return an undo function."""
441+
"""Enable tracing of hook calls.
442+
443+
Returns an undo function which, when called, removes the added tracing.
444+
"""
428445
hooktrace = self.trace.root.get("hook")
429446

430447
def before(

0 commit comments

Comments
 (0)