grim/pyscovery

cleaned up a ton of trailing whitespace

2013-05-26, Gary Kramlich
b010082bb0ad
Parents c8415431fd50
Children c42c665e3b2b
cleaned up a ton of trailing whitespace
  • +155 -29
    pyscovery.py
  • --- a/pyscovery.py Tue Apr 16 09:14:41 2013 -0500
    +++ b/pyscovery.py Sun May 26 05:19:56 2013 -0500
    @@ -30,53 +30,176 @@
    import inspect
    import os
    -# we use a list since it is a mutable sequence type. Meaning we can add to it
    -# while iterating.
    -MODULES = []
    +from threading import Lock
    +
    +__version__ = '1.2dev'
    +
    +
    +class Loader(object):
    + def __init__(self):
    + self.modules = []
    + self.discovered = None
    + self.lock = Lock()
    +
    +
    + def _real_add_module(self, module, modules=None):
    + """
    + The method that does the real addition of of a module to the search
    + path.
    + """
    +
    + if modules is None:
    + modules = self.modules
    +
    + if not module in modules:
    + modules.append(module)
    +
    +
    + def add_module(self, module):
    + """
    + Adds module to the search path
    + """
    +
    + self.lock.acquire()
    + self._real_add_module(module)
    + self.lock.release()
    +
    +
    + def _real_remove_module(self, module, modules=None):
    + """
    + The method that does the real removal of a module from the search path.
    + """
    +
    + if modules is None:
    + modules = self.modules
    +
    + try:
    + self.modules.remove(module)
    + except ValueError:
    + pass
    +
    +
    + def remove_module(self, module):
    + """
    + Removes module from the search paths
    + """
    +
    + self.lock.acquire()
    + self._real_add_module(module)
    + self.lock.release()
    +
    +
    + def get_modules(self):
    + """
    + Gets the search paths for this Loader.
    + """
    + return self.modules
    -__version__ = '1.1'
    + def clear_modules(self):
    + """
    + Clears the module search path.
    + """
    +
    + self.lock.acquire()
    + self.modules[:] = []
    + self.lock.release()
    +
    +
    + def find(self, cls, recurse, create, *args, **kwargs):
    + """Find all plugins that are subclasses of cls.
    +
    + :param cls: The class whose subclasses to find.
    + :type cls: class
    + :param recurse: Whether or not to recurse into packages.
    + :type recurse: bool
    + :param create: return instances rather than just return their class.
    + :type create: bool
    + :param args: Additional arguments to pass to each constructor. Ignored if
    + create is False.
    + :type args: arguments
    + :param kwargs: Additional keyword arguements to pass to each constructor.
    + Ignored if create is False.
    + :type kwargs: kwargs
    + :returns: Generator of subclasses of cls
    + """
    +
    +
    + @classmethod
    + def _is_package(cls, module):
    + """
    + Returns true if the module's name is __init__, false otherwise
    + """
    +
    + filename = os.path.basename(module.__file__)
    + base, _ = os.path.splitext(filename)
    +
    + return base == '__init__'
    +
    +
    + def _recurse(self, module):
    + """
    + Adds additional modules from a package
    + """
    +
    + dirname = os.path.dirname(module.__file__)
    +
    + make_module = lambda name: '.'.join((module.__name__, name))
    +
    + for name in os.listdir(dirname):
    + base, _ = os.path.splitext(name)
    +
    + if base == '__init__':
    + continue
    +
    + filename = os.path.join(dirname, name)
    +
    + if os.path.isdir(filename):
    + add_module(make_module(base))
    + elif os.path.isfile(filename):
    + if fnmatch.fnmatch(name, '*.py') or \
    + fnmatch.fnmatch(name, '*.py[co]'):
    + add_module(make_module(base))
    +
    +
    +_DEFAULT_LOADER = Loader()
    +
    +
    def add_module(module):
    """Adds a module to search for plugins under
    -
    +
    :param module: The module to add to the search paths
    :type module: string
    """
    - global MODULES # pylint:disable-msg=W0602
    + _DEFAULT_LOADER.add_module(module)
    - if not module in MODULES:
    - MODULES.append(module)
    -
    def remove_module(module):
    """Removes a module to search for plugins under
    -
    +
    :param module: The module to remove
    :type module: string
    """
    - global MODULES # pylint:disable-msg=W0602
    + _DEFAULT_LOADER.remove_module(module)
    - if module in MODULES:
    - MODULES.remove(module)
    -
    def get_modules():
    """Returns the list of all module to search under
    -
    +
    :returns: A list of the current modules used for searching
    """
    - return MODULES
    + return _DEFAULT_LOADER.get_modules()
    def clear_modules():
    """Clears all search modules
    """
    -
    - MODULES[:] = []
    +
    + _DEFAULT_LOADER.clear_modules()
    def find(cls, recurse, create, *args, **kwargs):
    @@ -98,28 +221,31 @@
    """
    if not inspect.isclass(cls):
    - raise TypeError('{} is not a class instance')
    + raise TypeError('{} is not a class instance'.format(cls))
    cls_name = cls.__name__
    - for module in MODULES:
    + modules = []
    + modules.extend(MODULES)
    +
    + for module in modules:
    mod = importlib.import_module(module)
    -
    +
    if recurse and _is_package(mod):
    _recurse(mod)
    -
    +
    for symbol_name in dir(mod):
    if symbol_name == cls_name:
    continue
    -
    +
    symbol = getattr(mod, symbol_name, None)
    -
    +
    if not inspect.isclass(symbol):
    continue
    -
    +
    if inspect.isabstract(symbol):
    continue
    -
    +
    if not issubclass(symbol, cls):
    continue
    @@ -136,7 +262,7 @@
    filename = os.path.basename(module.__file__)
    base, _ = os.path.splitext(filename)
    -
    +
    return base == '__init__'
    @@ -151,12 +277,12 @@
    for name in os.listdir(dirname):
    base, _ = os.path.splitext(name)
    -
    +
    if base == '__init__':
    continue
    filename = os.path.join(dirname, name)
    -
    +
    if os.path.isdir(filename):
    add_module(make_module(base))
    elif os.path.isfile(filename):