@@ -157,6 +157,13 @@ def setattr_hookimpl_opts(func):
157
157
return setattr_hookimpl_opts (function )
158
158
159
159
160
+ def normalize_hookimpl_opts (opts ):
161
+ opts .setdefault ("tryfirst" , False )
162
+ opts .setdefault ("trylast" , False )
163
+ opts .setdefault ("hookwrapper" , False )
164
+ opts .setdefault ("optionalhook" , False )
165
+
166
+
160
167
class _TagTracer :
161
168
def __init__ (self ):
162
169
self ._tag2proc = {}
@@ -310,13 +317,16 @@ class PluginManager(object):
310
317
which will subsequently send debug information to the trace helper.
311
318
"""
312
319
313
- def __init__ (self , project_name ):
320
+ def __init__ (self , project_name , implprefix = None ):
321
+ """ if implprefix is given implementation functions
322
+ will be recognized if their name matches the implprefix. """
314
323
self .project_name = project_name
315
324
self ._name2plugin = {}
316
325
self ._plugin2hookcallers = {}
317
326
self ._plugin_distinfo = []
318
327
self .trace = _TagTracer ().get ("pluginmanage" )
319
328
self .hook = _HookRelay (self .trace .root .get ("hook" ))
329
+ self ._implprefix = implprefix
320
330
self ._inner_hookexec = lambda hook , methods , kwargs : \
321
331
_MultiCall (methods , kwargs , hook .spec_opts ).execute ()
322
332
@@ -380,6 +390,7 @@ def register(self, plugin, name=None):
380
390
for name in dir (plugin ):
381
391
hookimpl_opts = self .parse_hookimpl_opts (plugin , name )
382
392
if hookimpl_opts is not None :
393
+ normalize_hookimpl_opts (hookimpl_opts )
383
394
method = getattr (plugin , name )
384
395
hookimpl = _HookImpl (plugin , plugin_name , method , hookimpl_opts )
385
396
hook = getattr (self .hook , name , None )
@@ -399,6 +410,8 @@ def parse_hookimpl_opts(self, plugin, name):
399
410
if res is not None and not isinstance (res , dict ):
400
411
# false positive
401
412
res = None
413
+ elif res is None and self ._implprefix and name .startswith (self ._implprefix ):
414
+ res = {}
402
415
return res
403
416
404
417
def parse_hookspec_opts (self , module_or_class , name ):
@@ -524,9 +537,18 @@ def load_setuptools_entrypoints(self, entrypoint_name):
524
537
except DistributionNotFound :
525
538
continue
526
539
self .register (plugin , name = ep .name )
527
- self ._plugin_distinfo .append ((ep .dist , plugin ))
540
+ self ._plugin_distinfo .append ((plugin , ep .dist ))
528
541
return len (self ._plugin_distinfo )
529
542
543
+ def list_plugin_distinfo (self ):
544
+ """ return list of distinfo/plugin tuples for all setuptools registered
545
+ plugins. """
546
+ return list (self ._plugin_distinfo )
547
+
548
+ def list_name_plugin (self ):
549
+ """ return list of name/plugin pairs. """
550
+ return list (self ._name2plugin .items ())
551
+
530
552
531
553
class _MultiCall :
532
554
""" execute a call into multiple python functions/methods. """
0 commit comments