diff --git a/boltons/funcutils.py b/boltons/funcutils.py index af8bb32..b0cc959 100644 --- a/boltons/funcutils.py +++ b/boltons/funcutils.py @@ -4,11 +4,41 @@ utilities on top of Python's first-class function support. ``funcutils`` generally stays in the same vein, adding to and correcting Python's standard metaprogramming facilities. """ +import sys import functools from types import MethodType, FunctionType from itertools import chain +def get_module_callables(mod, ignore=None): + """Returns two maps of (*types*, *funcs*) from *mod*, optionally + ignoring based on the :class:`bool` return value of the *ignore* + callable. *mod* can be a string name of a module in + :data:`sys.modules` or the module instance itself. + """ + if isinstance(mod, basestring): + mod = sys.modules[mod] + types, funcs = {}, {} + for attr_name in dir(mod): + if ignore and ignore(attr_name): + continue + try: + attr = getattr(mod, attr_name) + except: + continue + try: + attr_mod_name = attr.__module__ + except AttributeError: + continue + if attr_mod_name != mod.__name__: + continue + if isinstance(attr, type): + types[attr_name] = attr + elif callable(attr): + funcs[attr_name] = attr + return types, funcs + + def mro_items(type_obj): """Takes a type and returns an iterator over all class variables throughout the type hierarchy (respecting the MRO). diff --git a/docs/conf.py b/docs/conf.py index 4ff919a..933025a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,11 +16,42 @@ import os import sys import sphinx + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. CUR_PATH = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, os.path.abspath(CUR_PATH + '/../')) +PROJECT_PATH = os.path.abspath(CUR_PATH + '/../') +PACKAGE_PATH = os.path.abspath(CUR_PATH + '/../boltons/') +sys.path.insert(0, PROJECT_PATH) +sys.path.insert(0, PACKAGE_PATH) + + +def get_mod_stats(): + import pkgutil + from boltons.funcutils import get_module_defs + + mod_count = 0 + tot_type_count = 0 + tot_func_count = 0 + ignore = lambda attr_name: attr_name.startswith('_') + for _, mod_name, _ in pkgutil.iter_modules([PACKAGE_PATH]): + if not mod_name.endswith('utils'): + continue + mod = __import__(mod_name) + types, funcs, others = get_module_defs(mod, ignore=ignore) + if not len(types) and not len(funcs): + continue + mod_count += 1 + tot_type_count += len(types) + tot_func_count += len(funcs) + + ret = (mod_count, tot_type_count, tot_func_count) + print ('==== %s modules ==== %s types ==== %s funcs ====' % ret) + return ret + +get_mod_stats() + # -- General configuration ------------------------------------------------