comparison MoinMoin/wikiutil.py @ 53:699811601bed

merge moin--main--1.3--patch-934,935: detect correctly missing plguins and missing names in plugins Patches applied: * arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-934 detect correctly missing plguins and missing names in plugins * arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-935 updated CHANGES * nirs@freeshell.org--2005/moin--fix--1.3--patch-60 detect correctly missing plguins and missing names in plugins imported from: moin--main--1.5--patch-54
author Nir Soffer <nirs@freeshell.org>
date Thu, 29 Sep 2005 00:50:30 +0000
parents 54d5932d5a03
children 2202f548cbb0
comparison
equal deleted inserted replaced
52:80b3d4e891ff 53:699811601bed
563 563
564 ############################################################################# 564 #############################################################################
565 ### Plugins 565 ### Plugins
566 ############################################################################# 566 #############################################################################
567 567
568 class PluginError(Exception):
569 """ Base class for plugin errors """
570
571 class PluginMissingError(PluginError):
572 """ Raised when a plugin is not found """
573
574 class PluginAttributeError(PluginError):
575 """ Raised when plugin does not contain an attribtue """
576
577
568 def importPlugin(cfg, kind, name, function="execute"): 578 def importPlugin(cfg, kind, name, function="execute"):
569 """ Import wiki or builtin plugin 579 """ Import wiki or builtin plugin
570 580
571 Returns function from a plugin module. If the module can not be 581 Returns function from a plugin module name. If name can not be
572 imported, raise ImportError. If function is not there, raise 582 imported, raise PluginMissingError. If function is missing, raise
573 AttributeError. 583 PluginAttributeError.
574 584
575 kind may be one of 'action', 'formatter', 'macro', 'processor', 585 kind may be one of 'action', 'formatter', 'macro', 'processor',
576 'parser' or any other directory that exist in MoinMoin or 586 'parser' or any other directory that exist in MoinMoin or
577 data/plugin 587 data/plugin
578 588
579 Wiki plugins will always override builtin plugins. If you want 589 Wiki plugins will always override builtin plugins. If you want
580 specific plugin, use either importWikiPlugin or importName directly. 590 specific plugin, use either importWikiPlugin or importBuiltinPlugin
591 directly.
581 592
582 @param cfg: wiki config instance 593 @param cfg: wiki config instance
583 @param kind: what kind of module we want to import 594 @param kind: what kind of module we want to import
584 @param name: the name of the module 595 @param name: the name of the module
585 @param function: the function name 596 @param function: the function name
586 @rtype: callable 597 @rtype: any object
587 @return: "function" of module "name" of kind "kind", or None 598 @return: "function" of module "name" of kind "kind", or None
588 """ 599 """
589 try: 600 try:
590 plugin = importWikiPlugin(cfg, kind, name, function) 601 return importWikiPlugin(cfg, kind, name, function)
591 except ImportError: 602 except PluginMissingError:
592 modulename = 'MoinMoin.%s.%s' % (kind, name) 603 return importBuiltinPlugin(kind, name, function)
593 plugin = pysupport.importName(modulename, function) 604
594 return plugin
595 605
596 def importWikiPlugin(cfg, kind, name, function): 606 def importWikiPlugin(cfg, kind, name, function):
597 """ Import and cache plugin from the wiki data directory 607 """ Import plugin from the wiki data directory
598 608
599 Returns function from a plugin module. If the module can not be 609 See importPlugin docstring.
600 imported, raise ImportError. If function is not there, raise 610 """
601 AttributeError. 611 if not name in wikiPlugins(kind, cfg):
602 612 raise PluginMissingError
603 We try to import only ONCE - then cache the plugin, even if we got 613 moduleName = '%s.plugin.%s.%s' % (cfg.siteid, kind, name)
604 None. This way we prevent expensive import of existing plugins for 614 return importNameFromPlugin(moduleName, function)
605 each call to a plugin. 615
606 616
607 @param cfg: wiki config instance 617 def importBuiltinPlugin(kind, name, function):
608 @param kind: what kind of module we want to import 618 """ Import builtin plugin from MoinMoin package
609 @param name: the name of the module 619
610 @param function: the function name 620 See importPlugin docstring.
611 @rtype: callable 621 """
612 @return: "function" of module "name" of kind "kind" 622 if not name in builtinPlugins(kind):
613 """ 623 raise PluginMissingError
624 moduleName = 'MoinMoin.%s.%s' % (kind, name)
625 return importNameFromPlugin(moduleName, function)
626
627
628 def importNameFromPlugin(moduleName, name):
629 """ Return name from plugin module
630
631 Raise PluginAttributeError if name does not exists.
632 """
633 module = __import__(moduleName, globals(), {}, [name])
614 try: 634 try:
615 wikiPlugins = cfg._wiki_plugins 635 return getattr(module, name)
616 except AttributeError: 636 except AttributeError:
617 wikiPlugins = cfg._wiki_plugins = {} 637 raise PluginAttributeError
618
619 # Wiki plugins are located under 'wikiconfigname.plugin' module.
620 modulename = '%s.plugin.%s.%s' % (cfg.siteid, kind, name)
621 # Try cache or import once from disk
622 try:
623 module = wikiPlugins[modulename]
624 except KeyError:
625 try:
626 module = __import__(modulename, globals(), {}, ['dummy'])
627 except ImportError:
628 module = wikiPlugins[modulename] = None
629 if module is None:
630 raise ImportError
631 return getattr(module, function)
632
633 # If we use threads, make this function thread safe
634 if config.use_threads:
635 importWikiPlugin = pysupport.makeThreadSafe(importWikiPlugin)
636 638
637 639
638 def builtinPlugins(kind): 640 def builtinPlugins(kind):
639 """ Gets a list of modules in MoinMoin.'kind' 641 """ Gets a list of modules in MoinMoin.'kind'
640 642
700 import types 702 import types
701 etp, etd = {}, None 703 etp, etd = {}, None
702 for pname in getPlugins('parser', cfg): 704 for pname in getPlugins('parser', cfg):
703 try: 705 try:
704 Parser = importPlugin(cfg, 'parser', pname, 'Parser') 706 Parser = importPlugin(cfg, 'parser', pname, 'Parser')
705 except ImportError: 707 except wikiutil.PluginMissingError:
706 continue 708 continue
707 if hasattr(Parser, 'extensions'): 709 if hasattr(Parser, 'extensions'):
708 exts = Parser.extensions 710 exts = Parser.extensions
709 if type(exts) == types.ListType: 711 if type(exts) == types.ListType:
710 for ext in Parser.extensions: 712 for ext in Parser.extensions: