@@ -58,15 +58,14 @@ def _warn_for_function(warning: Warning, function: Callable[..., object]) -> Non
58
58
59
59
60
60
class PluginValidationError (Exception ):
61
- """plugin failed validation.
61
+ """Plugin failed validation.
62
62
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.
65
64
"""
66
65
67
66
def __init__ (self , plugin : _Plugin , message : str ) -> None :
67
+ super ().__init__ (message )
68
68
self .plugin = plugin
69
- super (Exception , self ).__init__ (message )
70
69
71
70
72
71
class DistFacade :
@@ -88,17 +87,16 @@ def __dir__(self) -> List[str]:
88
87
89
88
90
89
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.
93
92
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>`.
100
95
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`
102
100
which will subsequently send debug information to the trace helper.
103
101
"""
104
102
@@ -132,9 +130,15 @@ def _hookexec(
132
130
return self ._inner_hookexec (hook_name , methods , kwargs , firstresult )
133
131
134
132
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
+ """
138
142
plugin_name = name or self .get_canonical_name (plugin )
139
143
140
144
if plugin_name in self ._name2plugin :
@@ -193,8 +197,11 @@ def parse_hookimpl_opts(
193
197
def unregister (
194
198
self , plugin : Optional [_Plugin ] = None , name : Optional [str ] = None
195
199
) -> _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
+ """
198
205
if name is None :
199
206
assert plugin is not None , "one of name or plugin needs to be specified"
200
207
name = self .get_name (plugin )
@@ -216,17 +223,20 @@ def unregister(
216
223
return plugin
217
224
218
225
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."""
220
227
self .unregister (name = name )
221
228
self ._name2plugin [name ] = None
222
229
223
230
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."""
225
232
return name in self ._name2plugin and self ._name2plugin [name ] is None
226
233
227
234
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
+ """
230
240
names = []
231
241
for name in dir (module_or_class ):
232
242
spec_opts = self .parse_hookspec_opts (module_or_class , name )
@@ -236,7 +246,7 @@ def add_hookspecs(self, module_or_class: _Namespace) -> None:
236
246
hc = _HookCaller (name , self ._hookexec , module_or_class , spec_opts )
237
247
setattr (self .hook , name , hc )
238
248
else :
239
- # plugins registered this hook without knowing the spec
249
+ # Plugins registered this hook without knowing the spec.
240
250
hc .set_specification (module_or_class , spec_opts )
241
251
for hookfunction in hc .get_hookimpls ():
242
252
self ._verify_hook (hc , hookfunction )
@@ -257,32 +267,35 @@ def parse_hookspec_opts(
257
267
return opts
258
268
259
269
def get_plugins (self ) -> Set [Any ]:
260
- """return the set of registered plugins ."""
270
+ """Return a set of all registered plugin objects ."""
261
271
return set (self ._name2plugin .values ())
262
272
263
273
def is_registered (self , plugin : _Plugin ) -> bool :
264
- """Return ``True`` if the plugin is already registered."""
274
+ """Return whether the plugin is already registered."""
265
275
return any (plugin == val for val in self ._name2plugin .values ())
266
276
267
277
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
+ """
273
285
name : Optional [str ] = getattr (plugin , "__name__" , None )
274
286
return name or str (id (plugin ))
275
287
276
288
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 ."""
278
290
return self ._name2plugin .get (name )
279
291
280
292
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."""
282
294
return self .get_plugin (name ) is not None
283
295
284
296
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."""
286
299
for name , val in self ._name2plugin .items ():
287
300
if plugin == val :
288
301
return name
@@ -325,8 +338,9 @@ def _verify_hook(self, hook: _HookCaller, hookimpl: HookImpl) -> None:
325
338
)
326
339
327
340
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`."""
330
344
for name in self .hook .__dict__ :
331
345
if name [0 ] != "_" :
332
346
hook : _HookCaller = getattr (self .hook , name )
@@ -344,10 +358,10 @@ def load_setuptools_entrypoints(
344
358
) -> int :
345
359
"""Load modules from querying the specified setuptools ``group``.
346
360
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``.
349
363
:rtype: int
350
- :return: return the number of loaded plugins by this call.
364
+ :return: The number of plugins loaded by this call.
351
365
"""
352
366
count = 0
353
367
for dist in list (importlib_metadata .distributions ()):
@@ -367,16 +381,16 @@ def load_setuptools_entrypoints(
367
381
return count
368
382
369
383
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."""
372
386
return list (self ._plugin_distinfo )
373
387
374
388
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 ."""
376
390
return list (self ._name2plugin .items ())
377
391
378
392
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."""
380
394
if self .get_name (plugin ) is None :
381
395
return None
382
396
hookcallers = []
@@ -389,16 +403,16 @@ def get_hookcallers(self, plugin: _Plugin) -> Optional[List[_HookCaller]]:
389
403
def add_hookcall_monitoring (
390
404
self , before : _BeforeTrace , after : _AfterTrace
391
405
) -> 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.
395
409
396
410
``before(hook_name, hook_impls, kwargs)`` will be called ahead
397
411
of all hook calls and receive a hookcaller instance, a list
398
412
of HookImpl instances and the keyword arguments for the hook call.
399
413
400
414
``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
402
416
which represents the result of the overall hook call.
403
417
"""
404
418
oldcall = self ._inner_hookexec
@@ -424,7 +438,10 @@ def undo() -> None:
424
438
return undo
425
439
426
440
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
+ """
428
445
hooktrace = self .trace .root .get ("hook" )
429
446
430
447
def before (
0 commit comments