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.

"""
import logging
import os

from nose2 import events

from nose2.plugins.loader import discovery

__unittest = True
log = logging.getLogger(__name__)

try:
    import pkg_resources
except ImportError:
    pkg_resources = None


[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) for test in dir_handler.handle_dir(event, full_path, dist.location): yield test 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): for test in self._find_tests_in_egg_dir(event, entry_path, dist): yield test else: modname = os.path.splitext(entry_path)[0].replace(os.sep, '.') for test in self._find_tests_in_file( event, path, os.path.join(dist.location, entry_path), dist.location, modname): yield test def _find_tests_in_dir(self, event, full_path, top_level): if os.path.exists(full_path): return elif 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'): for test in self._find_tests_in_egg_dir( event, modname, dist): yield test