# Source code for napari_plugin_engine.dist

    import inspect
    import sys
    from functools import lru_cache
    from typing import Any, Dict, Optional, overload

    if sys.version_info >= (3, 8):
        from importlib import metadata as importlib_metadata
    else:
        import importlib_metadata

    @lru_cache(maxsize=1)
    def _top_level_module_to_dist() -> Dict[str, importlib_metadata.Distribution]:
        mapping = {}
        for dist in importlib_metadata.distributions():
            modules = dist.read_text('top_level.txt')
            if modules:
                for mod in modules.split('\n'):
                    if not mod:
                        continue
                    mapping[mod] = dist
        return mapping

    def _object_to_top_level_module(obj: Any) -> Optional[str]:
        module = inspect.getmodule(obj)
        name = getattr(module, '__name__', None)
        return name.split('.')[0] if name else None

    def get_dist(obj) -> Optional[importlib_metadata.Distribution]:
        """Return a :class:`importlib.metadata.Distribution` for any python object.

        Parameters
        ----------
        obj : Any
            A python object. If a string, will be interpreted as a dist name.

        Returns
        -------
        dist: Distribution
            The distribution object for the corresponding package, if found.
        """
        if isinstance(obj, str):
            try:
                return importlib_metadata.distribution(obj)
            except importlib_metadata.PackageNotFoundError:
                return None
        top_level = _object_to_top_level_module(obj)
        return _top_level_module_to_dist().get(top_level or '')

    def get_version(plugin) -> str:
        dist = get_dist(plugin)
        version = dist.metadata.get('version') if dist else ''
        if not version and inspect.ismodule(plugin):
            version = getattr(plugin, '__version__', '')
        if not version:
            top_module = _object_to_top_level_module(plugin)
            if top_module in sys.modules:
                version = getattr(sys.modules[top_module], '__version__', '')
        return str(version) if version else ''

    @overload
    def get_metadata(plugin, arg: str, *args: None) -> Optional[str]: ...

    @overload  # noqa: F811
    def get_metadata(  # noqa: F811
        plugin, arg: str, *args: str
    ) -> Dict[str, Optional[str]]: ...

    def get_metadata(plugin, *args):  # noqa: F811
        """Get metadata for this plugin.

        Valid arguments are any keys from the Core metadata specifications:
        https://packaging.python.org/specifications/core-metadata/

        Parameters
        ----------
        *args : str
            (Case insensitive) names of metadata entries to retrieve.

        Returns
        -------
        str or dict, optional
            If a single argument is provided, the value for that entry is
            returned (which may be ``None``).
            If multiple arguments are provided, a dict of {arg: value} is
            returned.
        """
        dist = get_dist(plugin)
        dct = {}
        if dist:
            for a in args:
                if a == 'version':
                    dct[a] = get_version(plugin)
                else:
                    dct[a] = dist.metadata.get(a)
        if len(args) == 1:
            return dct[args[0]] if dct else None
        return dct

    def standard_metadata(plugin: Any) -> Dict[str, Optional[str]]:
        """Return a standard metadata dict for ``plugin``.

        Parameters
        ----------
        plugin : Any
            A python object.  If a string, will be interpreted as a dist name.

        Returns
        -------
        metadata : dict
            A  dicts with plugin object metadata. The dict is guaranteed to have
            the following keys:

            - **package**: The name of the package
            - **version**: The version of the plugin package
            - **summary**: A one-line summary of what the distribution does
            - **author**: The author’s name
            - **email**: The author’s (or maintainer's) e-mail address.
            - **license**: The license covering the distribution
            - **url**: The home page for the package, or dowload url if N/A.

        Raises
        ------
        ValueError
            If no distribution can be found for ``plugin``.
        """
        meta = {}
        if not get_dist(plugin):
            _top_level_module_to_dist.cache_clear()
            if not get_dist(plugin):
                return {}
                # TODO: decide appropriate behavior here.
                # raise ValueError(f"could not find metadata for {plugin}")
        meta = get_metadata(
            plugin,
            'name',
            'version',
            'summary',
            'author',
            'license',
            'Author-Email',
            'Home-page',
        )
        meta['package'] = meta.pop('name')
        meta['email'] = meta.pop('Author-Email') or get_metadata(
            plugin, 'Maintainer-Email'
        )
        meta['url'] = meta.pop('Home-page') or get_metadata(plugin, 'Download-Url')
        if meta['url'] == 'UNKNOWN':
            meta['url'] = None
        return meta