Example #1
0
def plugin_list(parser, options, args=None):
    """ List github/external/built-in plugins. """
    if args:
        print_sub_help(parser, 'list')
        return -1
    
    # Requires Internet to access github.
    if options.github:  # pragma no cover
        _list_github_plugins()
        return 0
    
    groups = []
    for group in options.groups:
        if not group.startswith('openmdao.'):
            group = 'openmdao.'+group
        groups.append(group)
        
    show_all = (options.external == options.builtin)
    if show_all:
        title_type = ''
    elif options.external:
        title_type = 'external'
    else:
        title_type = 'built-in'
        
    title_groups = ','.join([g.split('.')[1] for g in groups])
    parts = title_groups.rsplit(',', 1)
    if len(parts) > 1:
        title_groups = ' and '.join(parts)
    
    if not groups:
        groups = None
    all_types = get_available_types(groups)

    plugins = set()
    for type in all_types:
        if show_all:
            plugins.add((type[0], type[1]))
        else:
            name = type[0].split('.')[0]
            if name == 'openmdao':
                if options.builtin:
                    plugins.add((type[0], type[1]))
            else:
                if options.external:
                    plugins.add((type[0], type[1]))
            
    title = "Installed %s %s plugins" % (title_type, title_groups)
    title = title.replace('  ', ' ')
    under = '-'*len(title)
    print ""
    print title
    print under
    print ""
    for plugin in sorted(plugins):
        print plugin[0], plugin[1]
        
    print "\n"

    return 0
    def __init__(self, name='', allow_shell=False, allowed_types=None):
        self._allow_shell = allow_shell
        if allowed_types is None:
            allowed_types = [typname for typname, version
                                      in get_available_types()]
        self._allowed_types = allowed_types

        self.host = platform.node()
        self.pid = os.getpid()
        self.name = name or ('sim-%d' % self.pid)
        self.version = __version__

        self._root_dir = os.getcwd()
        self._logger = logging.getLogger(self.name)
        self._logger.info('PID: %d, allow_shell %s',
                          os.getpid(), self._allow_shell)
        print '%s %r PID: %d, allow_shell %s' \
              % (self.__class__.__name__, self.name, os.getpid(),
                 self._allow_shell)
        sys.stdout.flush()

        SimulationRoot.chroot(self._root_dir)
        self.tlo = None

        # Ensure Traits Array support is initialized. The code contains
        # globals for numpy symbols that are initialized within
        # AbstractArray.__init__() which won't be executed if we simply
        # load up egg state (or don't do a real fork, like Windows).
        try:
            import numpy
        except ImportError:
            pass
        else:
            from traits.trait_numeric import AbstractArray
            dummy = AbstractArray()
    def __init__(self, name='', allow_shell=False, allowed_types=None):
        self._allow_shell = allow_shell
        if allowed_types is None:
            allowed_types = [typname for typname, version
                                      in get_available_types()]
        self._allowed_types = allowed_types

        self.host = platform.node()
        self.pid = os.getpid()
        self.name = name or ('sim-%d' % self.pid)
        self.version = __version__

        self._root_dir = os.getcwd()
        self._logger = logging.getLogger(self.name)
        self._logger.info('PID: %d, allow_shell %s',
                          os.getpid(), self._allow_shell)
        print '%s %r PID: %d, allow_shell %s' \
              % (self.__class__.__name__, self.name, os.getpid(),
                 self._allow_shell)
        sys.stdout.flush()

        SimulationRoot.chroot(self._root_dir)
        self.tlo = None

        # Ensure Traits Array support is initialized. The code contains
        # globals for numpy symbols that are initialized within
        # AbstractArray.__init__() which won't be executed if we simply
        # load up egg state (or don't do a real fork, like Windows).
        try:
            import numpy
        except ImportError:
            pass
        else:
            from enthought.traits.trait_numeric import AbstractArray
            dummy = AbstractArray()
Example #4
0
def plugin_list(parser, options, args=None):
    """ List github/external/built-in plugins. """
    if args:
        print_sub_help(parser, 'list')
        return -1

    # Requires Internet to access github.
    if options.github:  # pragma no cover
        _list_github_plugins()
        return 0

    groups = []
    for group in options.groups:
        if not group.startswith('openmdao.'):
            group = 'openmdao.' + group
        groups.append(group)

    show_all = (options.external == options.builtin)
    if show_all:
        title_type = ''
    elif options.external:
        title_type = 'external'
    else:
        title_type = 'built-in'

    title_groups = ','.join([g.split('.')[1] for g in groups])
    parts = title_groups.rsplit(',', 1)
    if len(parts) > 1:
        title_groups = ' and '.join(parts)

    if not groups:
        groups = None
    all_types = get_available_types(groups)

    plugins = set()
    for type in all_types:
        if show_all:
            plugins.add((type[0], type[1]['version']))
        else:
            name = type[0].split('.')[0]
            if name == 'openmdao':
                if options.builtin:
                    plugins.add((type[0], type[1]['version']))
            else:
                if options.external:
                    plugins.add((type[0], type[1]['version']))

    title = "Installed %s %s plugins" % (title_type, title_groups)
    title = title.replace('  ', ' ')
    under = '-' * len(title)
    print ""
    print title
    print under
    print ""
    for plugin in sorted(plugins):
        print plugin[0], plugin[1]

    print "\n"

    return 0
Example #5
0
def plugin_list(parser, options, args=None):
    if args:
        print_sub_help(parser, "list")
        return -1

    if options.github:
        _list_github_plugins()
        return

    groups = []
    for g in options.groups:
        if not g.startswith("openmdao."):
            g = "openmdao." + g
        groups.append(g)

    show_all = options.external == options.builtin
    if show_all:
        title_type = ""
    elif options.external:
        title_type = "external"
    else:
        title_type = "built-in"

    title_groups = ",".join([g.split(".")[1] for g in groups])
    parts = title_groups.rsplit(",", 1)
    if len(parts) > 1:
        title_groups = " and ".join(parts)

    if not groups:
        groups = None
    all_types = get_available_types(groups)

    plugins = set()
    for type in all_types:
        if show_all:
            plugins.add((type[0], type[1]))
        else:
            name = type[0].split(".")[0]
            if name == "openmdao":
                if options.builtin:
                    plugins.add((type[0], type[1]))
            else:
                if options.external:
                    plugins.add((type[0], type[1]))

    title = "Installed %s %s plugins" % (title_type, title_groups)
    title = title.replace("  ", " ")
    under = "-" * len(title)
    print ""
    print title
    print under
    print ""
    for plugin in sorted(plugins):
        print plugin[0], plugin[1]

    print "\n"
Example #6
0
def test_types():
    from openmdao.main.factorymanager import get_available_types

    print 'All types:'
    t = get_available_types()
    print_list(t)

    types = [x[0] for x in get_available_types()]
    print types

    g = ['openmdao.component']
    print 'Components:'
    t = get_available_types(groups=g)
    print_list(t)

    g = ['openmdao.driver']
    print 'Drivers:'
    t = get_available_types(groups=g)
    print_list(t)
def test_types():
    from openmdao.main.factorymanager import get_available_types
    
    print 'All types:'
    t =get_available_types()
    print_list(t)

    types = [x[0] for x in get_available_types()]
    print types

    g = [ 'openmdao.component' ]
    print 'Components:'
    t =get_available_types(groups=g)
    print_list(t)

    g = [ 'openmdao.driver' ]
    print 'Drivers:'
    t =get_available_types(groups=g)
    print_list(t)
 def get_available_types(self, groups=None):
     """
     Returns a set of tuples of the form ``(typename, metadata)``,
     one for each available plugin type in the given entry point groups.
     If groups is *None,* return the set for all openmdao entry point groups.
     """
     self._logger.debug('get_available_types %s', groups)
     types = get_available_types(groups)
     for typname, version in types:
         self._logger.log(LOG_DEBUG2, '    %s %s', typname, version)
     return types
Example #9
0
 def publish_updates(self, added_set, changed_set, deleted_set):
     types = get_available_types()
     try:
         publish('types', [
             packagedict(types),
             list(added_set),
             list(changed_set),
             list(deleted_set),
         ])
     except:
         logger.error("publish of types failed")
 def get_available_types(self, groups=None):
     """
     Returns a set of tuples of the form ``(typename, metadata)``,
     one for each available plugin type in the given entry point groups.
     If groups is *None,* return the set for all openmdao entry point groups.
     """
     self._logger.debug('get_available_types %s', groups)
     types = get_available_types(groups)
     for typname, version in types:
         self._logger.log(LOG_DEBUG2, '    %s %s', typname, version)
     return types
Example #11
0
def plugin_list(options):
    if options.github:
        _list_github_plugins()
        return
    
    groups = []
    for g in options.groups:
        if not g.startswith('openmdao.'):
            g = 'openmdao.'+g
        groups.append(g)
        
    show_all = (options.external == options.builtin)
    if show_all:
        title_type = ''
    elif options.external:
        title_type = 'external'
    else:
        title_type = 'built-in'
        
    title_groups = ','.join([g.split('.')[1] for g in groups])
    parts = title_groups.rsplit(',',1)
    if len(parts) > 1:
        title_groups = ' and '.join(parts)
    
    if not groups:
        groups = None
    all_types = get_available_types(groups)
      
    plugins = set()
    for type in all_types:
        if show_all:
            plugins.add((type[0], type[1]))
        else:
            name = type[0].split('.')[0]
            if name == 'openmdao':
                if options.builtin:
                    plugins.add((type[0], type[1]))
            else:
                if options.external:
                    plugins.add((type[0], type[1]))
            
    
    title = "Installed %s %s plugins" % (title_type, title_groups)
    title = title.replace('  ', ' ')
    under = '-'*len(title)
    print ""
    print title
    print under
    print ""
    for plugin in sorted(plugins):
        print plugin[0], plugin[1]
        
    print "\n"
Example #12
0
 def publish_updates(self, added_set, changed_set, deleted_set):
     types = get_available_types()
     try:
         publish('types',
                 [
                     packagedict(types),
                     list(added_set),
                     list(changed_set),
                     list(deleted_set),
                 ])
     except:
         logger.error("publish of types failed")
Example #13
0
def plugin_list(options):
    if options.github:
        _list_github_plugins()
        return

    groups = []
    for g in options.groups:
        if not g.startswith('openmdao.'):
            g = 'openmdao.' + g
        groups.append(g)

    show_all = (options.external == options.builtin)
    if show_all:
        title_type = ''
    elif options.external:
        title_type = 'external'
    else:
        title_type = 'built-in'

    title_groups = ','.join([g.split('.')[1] for g in groups])
    parts = title_groups.rsplit(',', 1)
    if len(parts) > 1:
        title_groups = ' and '.join(parts)

    if not groups:
        groups = None
    all_types = get_available_types(groups)

    plugins = set()
    for type in all_types:
        if show_all:
            plugins.add((type[0], type[1]))
        else:
            name = type[0].split('.')[0]
            if name == 'openmdao':
                if options.builtin:
                    plugins.add((type[0], type[1]))
            else:
                if options.external:
                    plugins.add((type[0], type[1]))

    title = "Installed %s %s plugins" % (title_type, title_groups)
    title = title.replace('  ', ' ')
    under = '-' * len(title)
    print ""
    print title
    print under
    print ""
    for plugin in sorted(plugins):
        print plugin[0], plugin[1]

    print "\n"
Example #14
0
 def publish_updates(self, added_set, changed_set, deleted_set):
     publisher = Publisher.get_instance()
     if publisher:
         types = get_available_types()
         types.extend(self.get_available_types())
         publisher.publish('types', [
             packagedict(types),
             list(added_set),
             list(changed_set),
             list(deleted_set),
         ])
     else:
         logger.error("no Publisher found")
    def __init__(self, name='', allow_shell=False, allowed_types=None):
        self._allow_shell = allow_shell
        if allowed_types is None:
            allowed_types = [typname for typname, version
                                      in get_available_types()]
        self._allowed_types = allowed_types

        self.host = platform.node()
        self.pid = os.getpid()
        self.name = name or ('sim-%d' % self.pid)

        self._root_dir = os.getcwd()
        self._logger = logging.getLogger(self.name)
        self._logger.info('PID: %d, allow_shell %s',
                          os.getpid(), self._allow_shell)
        print 'ObjServer %r PID: %d, allow_shell %s' \
              % (self.name, os.getpid(), self._allow_shell)
        sys.stdout.flush()

        SimulationRoot.chroot(self._root_dir)
        self.tlo = None
 def get_available_types(self):
     return packagedict(get_available_types())
 def get_available_types(self):
     return packagedict(get_available_types())
Example #18
0
def _plugin_docs(plugin_name, browser=None):
    """This brings up the Sphinx docs for the named plugin using the
    specified browser.  The plugin must be importable in the current 
    environment.
    
    plugin_name: str
        Name of the plugin distribution, module, or class.
        
    browser: str (optional)
        Name of the browser (according to the webbrowser library) to
        use to view the plugin docs.  If none is specified, the platform
        default browser will be used.
    """
    parts = plugin_name.split(".")

    if len(parts) == 1:  # assume it's a class name and try to find unambiguous module
        modname = None
        # loop over available types to find a class name that matches
        for name, version in get_available_types():
            mname, cname = name.rsplit(".", 1)
            if cname == plugin_name:
                if modname and modname != mname:
                    raise RuntimeError(
                        "Can't determine module for class '%s' unambiguously. found in %s" % (cname, [mname, modname])
                    )
                modname = mname
                parts = modname.split(".")

        if modname is None:  # didn't find a class, so assume plugin_name is a dist name
            parts = [plugin_name, plugin_name]

    for i in range(len(parts) - 1):
        mname = ".".join(parts[: len(parts) - i])
        try:
            __import__(mname)
            mod = sys.modules[mname]
            modname = mname
            break
        except ImportError:
            pass
    else:
        # Possibly something in contrib that's a directory.
        try:
            __import__(plugin_name)
            mod = sys.modules[plugin_name]
            modname = plugin_name
        except ImportError:
            raise RuntimeError("Can't locate package/module '%s'" % plugin_name)

    if modname.startswith("openmdao."):  # lookup in builtin docs
        fparts = mod.__file__.split(os.sep)
        pkg = ".".join(modname.split(".")[:2])
        anchorpath = "/".join(["srcdocs", "packages", "%s.html#module-%s" % (pkg, modname)])
        if any([p.endswith(".egg") and p.startswith("openmdao.") for p in fparts]):
            # this is a release version, so use online docs
            url = "/".join(["http://openmdao.org/releases/%s/docs" % __version__, anchorpath])
        else:  # it's a developer version, so use locally built docs
            htmldir = os.path.join(get_ancestor_dir(sys.executable, 3), "docs", "_build", "html")
            if not os.path.isfile(os.path.join(htmldir, "index.html")):  # make sure the local docs are built
                print "local docs not found.\nbuilding them now...\n"
                check_call(["openmdao", "build_docs"])
            url = "file://" + os.path.join(htmldir, anchorpath)
            url = url.replace("\\", "/")
    else:
        url = os.path.join(os.path.dirname(os.path.abspath(mod.__file__)), "sphinx_build", "html", "index.html")

    wb = webbrowser.get(browser)
    wb.open(url)
Example #19
0
def plugin_list(parser, options, args=None):
    """ List GitHub/external/built-in plugins. """
    if args:
        print_sub_help(parser, "list")
        return -1

    # Requires Internet to access github.
    if options.owner:  # pragma no cover

        _list_github_plugins(options.owner)
        return 0

    groups = []
    for group in options.groups:
        if not group.startswith("openmdao."):
            group = "openmdao." + group
        groups.append(group)

    show_all = options.external == options.builtin
    if show_all:
        title_type = ""
    elif options.external:
        title_type = "external"
    else:
        title_type = "built-in"

    title_groups = ",".join([g.split(".")[1] for g in groups])
    parts = title_groups.rsplit(",", 1)
    if len(parts) > 1:
        title_groups = " and ".join(parts)

    if not groups:
        groups = None
    all_types = get_available_types(groups)

    plugins = set()
    for type in all_types:
        if show_all:
            plugins.add((type[0], type[1]["version"]))
        else:
            name = type[0].split(".")[0]
            if name == "openmdao":
                if options.builtin:
                    plugins.add((type[0], type[1]["version"]))
            else:
                if options.external:
                    plugins.add((type[0], type[1]["version"]))

    title = "Installed %s %s plugins" % (title_type, title_groups)
    title = title.replace("  ", " ")
    under = "-" * len(title)
    print ""
    print title
    print under
    print ""
    for plugin in sorted(plugins):
        print plugin[0], plugin[1]

    print "\n"

    return 0
Example #20
0
def _plugin_docs(plugin_name, browser=None):
    """This brings up the Sphinx docs for the named plugin using the
    specified browser.  The plugin must be importable in the current 
    environment.
    
    plugin_name: str
        Name of the plugin distribution, module, or class.
        
    browser: str (optional)
        Name of the browser (according to the webbrowser library) to
        use to view the plugin docs.  If none is specified, the platform
        default browser will be used.
    """
    parts = plugin_name.split('.')

    if len(
            parts
    ) == 1:  # assume it's a class name and try to find unambiguous module
        modname = None
        # loop over available types to find a class name that matches
        for name, version in get_available_types():
            mname, cname = name.rsplit('.', 1)
            if cname == plugin_name:
                if modname and modname != mname:
                    raise RuntimeError(
                        "Can't determine module for class '%s' unambiguously. found in %s"
                        % (cname, [mname, modname]))
                modname = mname
                parts = modname.split('.')

        if modname is None:  # didn't find a class, so assume plugin_name is a dist name
            parts = [plugin_name, plugin_name]

    for i in range(len(parts) - 1):
        mname = '.'.join(parts[:len(parts) - i])
        try:
            __import__(mname)
            mod = sys.modules[mname]
            modname = mname
            break
        except ImportError:
            pass
    else:
        raise RuntimeError("Can't locate package/module '%s'" % plugin_name)

    if modname.startswith('openmdao.'):  # lookup in builtin docs
        fparts = mod.__file__.split(os.sep)
        pkg = '.'.join(modname.split('.')[:2])
        anchorpath = '/'.join(
            ['srcdocs', 'packages',
             '%s.html#module-%s' % (pkg, modname)])
        if any(
            [p.endswith('.egg') and p.startswith('openmdao.')
             for p in fparts]):
            # this is a release version, so use online docs
            url = '/'.join([
                'http://openmdao.org/releases/%s/docs' % __version__,
                anchorpath
            ])
        else:  # it's a developer version, so use locally built docs
            htmldir = os.path.join(get_ancestor_dir(sys.executable, 3), 'docs',
                                   '_build', 'html')
            if not os.path.isfile(os.path.join(
                    htmldir,
                    'index.html')):  #make sure the local docs are built
                print "local docs not found.\nbuilding them now...\n"
                check_call(['openmdao', 'build_docs'])
            url = 'file://' + os.path.join(htmldir, anchorpath)
            url = url.replace('\\', '/')
    else:
        url = os.path.join(os.path.dirname(os.path.abspath(mod.__file__)),
                           'sphinx_build', 'html', 'index.html')

    wb = webbrowser.get(browser)
    wb.open(url)
Example #21
0
def find_docs_url(plugin_name=None, build_if_needed=True):
    """Returns a url for the Sphinx docs for the named plugin.
    The plugin must be importable in the current environment.
    
    plugin_name: str
        Name of the plugin distribution, module, or class.
    """
    parts = plugin_name.split('.')

    if len(
            parts
    ) == 1:  # assume it's a class name and try to find unambiguous module
        modname = None
        # loop over available types to find a class name that matches
        for name, version in get_available_types():
            mname, cname = name.rsplit('.', 1)
            if cname == plugin_name:
                if modname and modname != mname:
                    raise RuntimeError("Can't determine module for class '%s'"
                                       " unambiguously. found in %s" %
                                       (cname, [mname, modname]))
                modname = mname
                parts = modname.split('.')

        if modname is None:  # didn't find a class, so assume plugin_name is a dist name
            parts = [plugin_name, plugin_name]

    for i in range(len(parts) - 1):
        mname = '.'.join(parts[:len(parts) - i])
        try:
            __import__(mname)
            mod = sys.modules[mname]
            modname = mname
            break
        except ImportError:
            pass
    else:
        # Possibly something in contrib that's a directory.
        try:
            __import__(plugin_name)
            mod = sys.modules[plugin_name]
            modname = plugin_name
        except ImportError:
            raise RuntimeError("Can't locate package/module '%s'" %
                               plugin_name)

    if modname.startswith('openmdao.'):  # lookup in builtin docs
        fparts = mod.__file__.split(os.sep)
        pkg = '.'.join(modname.split('.')[:2])
        anchorpath = '/'.join(
            ['srcdocs', 'packages',
             '%s.html#module-%s' % (pkg, modname)])
        if any(
            [p.endswith('.egg') and p.startswith('openmdao.')
             for p in fparts]):
            # this is a release version, so use online docs
            url = '/'.join([
                'http://openmdao.org/releases/%s/docs' % __version__,
                anchorpath
            ])
        else:  # it's a developer version, so use locally built docs
            htmldir = os.path.join(get_ancestor_dir(sys.executable, 3), 'docs',
                                   '_build', 'html')
            if not os.path.isfile(os.path.join(
                    htmldir, 'index.html')) and build_if_needed:
                #make sure the local docs are built
                print "local docs not found.\nbuilding them now...\n"
                check_call(['openmdao', 'build_docs'])
            url = 'file://' + os.path.join(htmldir, anchorpath)
            url = url.replace('\\', '/')
    else:
        url = os.path.join(os.path.dirname(os.path.abspath(mod.__file__)),
                           'sphinx_build', 'html', 'index.html')
    return url
Example #22
0
def find_docs_url(plugin_name=None, build_if_needed=True):
    """Returns a url for the Sphinx docs for the named plugin.
    The plugin must be importable in the current environment.

    plugin_name: str
        Name of the plugin distribution, module, or class.
    """
    parts = plugin_name.split(".")

    if len(parts) == 1:
        # assume it's a class name and try to find unambiguous module
        modname = None
        # loop over available types to find a class name that matches
        for name, version in get_available_types():
            mname, cname = name.rsplit(".", 1)
            if cname == plugin_name:
                if modname and modname != mname:
                    raise RuntimeError(
                        "Can't determine module for class '%s'"
                        " unambiguously. found in %s" % (cname, [mname, modname])
                    )
                modname = mname
                parts = modname.split(".")

        if modname is None:
            # didn't find a class, so assume plugin_name is a dist name
            parts = [plugin_name, plugin_name]

    for i in range(len(parts) - 1):
        mname = ".".join(parts[: len(parts) - i])
        try:
            __import__(mname)
            mod = sys.modules[mname]
            modname = mname
            modfile = os.path.abspath(mod.__file__)
            break
        except ImportError:
            # we may be able to locate the docs even if the import fails
            modfile = find_module(mname)
            modname = mname
            if modfile:
                break
    else:
        # Possibly something in contrib that's a directory.
        try:
            __import__(plugin_name)
            mod = sys.modules[plugin_name]
            modname = plugin_name
            modfile = os.path.abspath(mod.__file__)
        except ImportError:
            raise RuntimeError("Can't locate package/module '%s'" % plugin_name)

    url = "file://"
    if modname.startswith("openmdao."):  # lookup in builtin docs
        import openmdao.main

        fparts = mod.__file__.split(os.sep)
        pkg = ".".join(modname.split(".")[:2])
        anchorpath = "/".join(["srcdocs", "packages", "%s.html#module-%s" % (pkg, modname)])
        if any([p.endswith(".egg") and p.startswith("openmdao.") for p in fparts]):
            # this is a release version, so use docs packaged with openmdao.main
            htmldir = os.path.join(os.path.dirname(openmdao.main.__file__), "docs")
        else:  # it's a developer version, so use locally built docs
            htmldir = os.path.join(get_ancestor_dir(sys.executable, 3), "docs", "_build", "html")
            if not os.path.isfile(os.path.join(htmldir, "index.html")) and build_if_needed:
                # make sure the local docs are built
                print "local docs not found.\nbuilding them now...\n"
                check_call(["openmdao", "build_docs"])
        url += os.path.join(htmldir, anchorpath)
    else:
        url += os.path.join(os.path.dirname(modfile), "sphinx_build", "html", "index.html")

    url = url.replace("\\", "/")
    return url
Example #23
0
def _plugin_docs(plugin_name):
    """Returns a url for the Sphinx docs for the named plugin.
    The plugin must be importable in the current environment.
    
    plugin_name: str
        Name of the plugin distribution, module, or class.
    """
    parts = plugin_name.split('.')
    
    if len(parts) == 1: # assume it's a class name and try to find unambiguous module
        modname = None
        # loop over available types to find a class name that matches
        for name, version in get_available_types():
            mname, cname = name.rsplit('.', 1)
            if cname == plugin_name:
                if modname and modname != mname:
                    raise RuntimeError("Can't determine module for class '%s'"
                                       " unambiguously. found in %s"
                                       % (cname, [mname, modname]))
                modname = mname
                parts = modname.split('.')
   
        if modname is None: # didn't find a class, so assume plugin_name is a dist name
            parts = [plugin_name, plugin_name]
        
    for i in range(len(parts)-1):
        mname = '.'.join(parts[:len(parts)-i])
        try:
            __import__(mname)
            mod = sys.modules[mname]
            modname = mname
            break
        except ImportError:
            pass
    else:
        # Possibly something in contrib that's a directory.
        try:
            __import__(plugin_name)
            mod = sys.modules[plugin_name]
            modname = plugin_name
        except ImportError:
            raise RuntimeError("Can't locate package/module '%s'" % plugin_name)
    
    if modname.startswith('openmdao.'): # lookup in builtin docs
        fparts = mod.__file__.split(os.sep)
        pkg = '.'.join(modname.split('.')[:2])
        anchorpath = '/'.join(['srcdocs', 'packages',
                               '%s.html#module-%s' % (pkg, modname)])
        if any([p.endswith('.egg') and p.startswith('openmdao.') for p in fparts]): 
            # this is a release version, so use online docs
            url = '/'.join(['http://openmdao.org/releases/%s/docs'
                            % __version__, anchorpath])
        else:  # it's a developer version, so use locally built docs
            htmldir = os.path.join(get_ancestor_dir(sys.executable, 3), 'docs', 
                                   '_build', 'html')
            if not os.path.isfile(os.path.join(htmldir, 'index.html')):
                #make sure the local docs are built
                print "local docs not found.\nbuilding them now...\n"
                check_call(['openmdao', 'build_docs'])
            url = 'file://'+os.path.join(htmldir, anchorpath)
            url = url.replace('\\', '/')
    else:
        url = os.path.join(os.path.dirname(os.path.abspath(mod.__file__)),
                           'sphinx_build', 'html', 'index.html')
    return url