~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugin.py

  • Committer: Robert Collins
  • Date: 2010-07-04 06:22:11 UTC
  • mto: This revision was merged to the branch mainline in revision 5332.
  • Revision ID: robertc@robertcollins.net-20100704062211-tk9hw6bnsn5x47fm
``bzrlib.lsprof.profile`` will no longer silently generate bad threaded
profiles when concurrent profile requests are made. Instead the profile
requests will be serialised. Reentrant requests will now deadlock.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
    return path.rstrip("\\/")
82
82
 
83
83
 
 
84
def _get_specific_plugin_paths(paths):
 
85
    """Returns the plugin paths from a string describing the associations.
 
86
 
 
87
    :param paths: A string describing the paths associated with the plugins.
 
88
 
 
89
    :returns: A list of (plugin name, path) tuples.
 
90
 
 
91
    For example, if paths is my_plugin@/test/my-test:her_plugin@/production/her,
 
92
    [('my_plugin', '/test/my-test'), ('her_plugin', '/production/her')] 
 
93
    will be returned.
 
94
 
 
95
    Note that ':' in the example above depends on the os.
 
96
    """
 
97
    if not paths:
 
98
        return []
 
99
    specs = []
 
100
    for spec in paths.split(os.pathsep):
 
101
        try:
 
102
            name, path = spec.split('@')
 
103
        except ValueError:
 
104
            raise errors.BzrCommandError(
 
105
                '"%s" is not a valid <plugin_name>@<plugin_path> description '
 
106
                % spec)
 
107
        specs.append((name, path))
 
108
    return specs
 
109
 
 
110
 
84
111
def set_plugins_path(path=None):
85
112
    """Set the path for plugins to be loaded from.
86
113
 
98
125
        for name in disabled_plugins.split(os.pathsep):
99
126
            PluginImporter.blacklist.add('bzrlib.plugins.' + name)
100
127
    # Set up a the specific paths for plugins
101
 
    specific_plugins = os.environ.get('BZR_PLUGINS_AT', None)
102
 
    if specific_plugins is not None:
103
 
        for spec in specific_plugins.split(os.pathsep):
104
 
            plugin_name, plugin_path = spec.split('@')
 
128
    for plugin_name, plugin_path in _get_specific_plugin_paths(os.environ.get(
 
129
            'BZR_PLUGINS_AT', None)):
105
130
            PluginImporter.specific_paths[
106
131
                'bzrlib.plugins.%s' % plugin_name] = plugin_path
107
132
    return path
562
587
        # We are called only for specific paths
563
588
        plugin_path = self.specific_paths[fullname]
564
589
        loading_path = None
565
 
        package = False
566
590
        if os.path.isdir(plugin_path):
567
591
            for suffix, mode, kind in imp.get_suffixes():
568
592
                if kind not in (imp.PY_SOURCE, imp.PY_COMPILED):
570
594
                    continue
571
595
                init_path = osutils.pathjoin(plugin_path, '__init__' + suffix)
572
596
                if os.path.isfile(init_path):
573
 
                    loading_path = init_path
574
 
                    package = True
 
597
                    # We've got a module here and load_module needs specific
 
598
                    # parameters.
 
599
                    loading_path = plugin_path
 
600
                    suffix = ''
 
601
                    mode = ''
 
602
                    kind = imp.PKG_DIRECTORY
575
603
                    break
576
604
        else:
577
605
            for suffix, mode, kind in imp.get_suffixes():
581
609
        if loading_path is None:
582
610
            raise ImportError('%s cannot be loaded from %s'
583
611
                              % (fullname, plugin_path))
584
 
        f = open(loading_path, mode)
 
612
        if kind is imp.PKG_DIRECTORY:
 
613
            f = None
 
614
        else:
 
615
            f = open(loading_path, mode)
585
616
        try:
586
617
            mod = imp.load_module(fullname, f, loading_path,
587
618
                                  (suffix, mode, kind))
588
 
            if package:
589
 
                # The plugin can contain modules, so be ready
590
 
                mod.__path__ = [plugin_path]
591
619
            mod.__package__ = fullname
592
620
            return mod
593
621
        finally:
594
 
            f.close()
 
622
            if f is not None:
 
623
                f.close()
595
624
 
596
625
 
597
626
# Install a dedicated importer for plugins requiring special handling