Source code for nose2.plugins.loader.eggdiscovery

"""
Egg-based discovery test loader.

This plugin implements nose2's automatic test module discovery inside Egg Files.
It looks for test modules in packages whose names start
with ``test``, then fires the :func:`loadTestsFromModule` hook for each
one to allow other plugins to load the actual tests.

It also fires :func:`handleFile` for every file that it sees, and
:func:`matchPath` for every Python module, to allow other plugins to
load tests from other kinds of files and to influence which modules
are examined for tests.

"""

from __future__ import annotations

import logging
import os

from nose2 import events
from nose2.plugins.loader import discovery

__unittest = True
log = logging.getLogger(__name__)

try:
    import pkg_resources

    _has_pkg_resources = True
except ImportError:
    _has_pkg_resources = False


[docs] class EggDiscoveryLoader(events.Plugin, discovery.Discoverer): """Loader plugin that can discover tests inside Egg Files""" alwaysOn = True configSection = "discovery" def registerInSubprocess(self, event): event.pluginClasses.append(self.__class__)
[docs] def loadTestsFromName(self, event): """Load tests from module named by event.name""" return discovery.Discoverer.loadTestsFromName(self, event)
[docs] def loadTestsFromNames(self, event): """Discover tests if no test names specified""" return discovery.Discoverer.loadTestsFromNames(self, event)
def _checkIfPathIsOK(self, start_dir): if not os.path.exists(os.path.abspath(start_dir)): raise OSError("%s does not exist" % os.path.abspath(start_dir)) def _find_tests_in_egg_dir(self, event, rel_path, dist): log.debug( "find in egg dir %s %s (%s)", dist.location, rel_path, dist.project_name ) full_path = os.path.join(dist.location, rel_path) dir_handler = discovery.DirectoryHandler(self.session) yield from dir_handler.handle_dir(event, full_path, dist.location) if dir_handler.event_handled: return for path in dist.resource_listdir(rel_path): # on setuptools==38.2.5 , resource_listdir() can yield "" # if that happens, skip processing it to avoid infinite recursion if path == "": continue entry_path = os.path.join(rel_path, path) if dist.resource_isdir(entry_path): yield from self._find_tests_in_egg_dir(event, entry_path, dist) else: modname = os.path.splitext(entry_path)[0].replace(os.sep, ".") yield from self._find_tests_in_file( event, path, os.path.join(dist.location, entry_path), dist.location, modname, ) def _find_tests_in_dir(self, event, full_path, top_level): if os.path.exists(full_path): return elif _has_pkg_resources and full_path.find(".egg") != -1: egg_path = full_path.split(".egg")[0] + ".egg" for dist in pkg_resources.find_distributions(egg_path): for modname in dist._get_metadata("top_level.txt"): yield from self._find_tests_in_egg_dir(event, modname, dist)