Source code for tri_declarative

from .declarative import (
    declarative,
    get_declared,
    get_members,
)
from .dispatch import dispatch
from .evaluate import (
    evaluate,
    evaluate_recursive,
    evaluate_recursive_strict,
    evaluate_strict,
    get_callable_description,
    matches,
)
from .namespace import (
    EMPTY,
    flatten,
    flatten_items,
    getattr_path,
    Namespace,
    setattr_path,
    setdefaults_path,
)
from .refinable import (
    refinable,
    Refinable,
    RefinableObject,
)
from .shortcut import (
    class_shortcut,
    get_shortcuts_by_name,
    is_shortcut,
    shortcut,
    Shortcut,
)
from .sort_after import (
    LAST,
    sort_after,
)
from .with_meta import with_meta

__version__ = '5.7.0'

__all__ = [
    'assert_kwargs_empty',
    'class_shortcut',
    'declarative',
    'dispatch',
    'EMPTY',
    'evaluate',
    'evaluate_strict',
    'evaluate_recursive',
    'evaluate_recursive_strict',
    'filter_show_recursive',
    'flatten',
    'flatten_items',
    'full_function_name',
    'get_shortcuts_by_name',
    'getattr_path',
    'get_members',
    'is_shortcut',
    'LAST',
    'matches',
    'Namespace',
    'remove_show_recursive',
    'refinable',
    'Refinable',
    'RefinableObject',
    'setattr_path',
    'setdefaults_path',
    'shortcut',
    'Shortcut',
    'should_show',
    'sort_after',
    'with_meta',
]


[docs]def should_show(item): try: r = item.show except AttributeError: try: r = item['show'] except (TypeError, KeyError): return True if callable(r): assert False, "`show` was a callable. You probably forgot to evaluate it. The callable was: {}".format(get_callable_description(r)) return r
[docs]def filter_show_recursive(item): if isinstance(item, list): return [filter_show_recursive(v) for v in item if should_show(v)] if isinstance(item, dict): # The type(item)(** stuff is to preserve the original type return type(item)(**{k: filter_show_recursive(v) for k, v in dict.items(item) if should_show(v)}) if isinstance(item, set): return {filter_show_recursive(v) for v in item if should_show(v)} return item
def remove_keys_recursive(item, keys_to_remove): if isinstance(item, list): return [remove_keys_recursive(v, keys_to_remove) for v in item] if isinstance(item, set): return {remove_keys_recursive(v, keys_to_remove) for v in item} if isinstance(item, dict): return {k: remove_keys_recursive(v, keys_to_remove) for k, v in dict.items(item) if k not in keys_to_remove} return item
[docs]def remove_show_recursive(item): return remove_keys_recursive(item, {'show'})
[docs]def assert_kwargs_empty(kwargs): if kwargs: import traceback function_name = traceback.extract_stack()[-2][2] raise TypeError('%s() got unexpected keyword arguments %s' % (function_name, ', '.join(["'%s'" % x for x in sorted(kwargs.keys())])))
[docs]def full_function_name(f): return '%s.%s' % (f.__module__, f.__name__)
def generate_rst_docs(directory, classes, missing_objects=None): # pragma: no coverage """ Generate documentation for tri.declarative APIs :param directory: directory to write the .rst files into :param classes: list of classes to generate documentation for :param missing_objects: tuple of objects to count as missing markers, if applicable """ doc_by_filename = _generate_rst_docs(classes=classes, missing_objects=missing_objects) # pragma: no mutate for filename, doc in doc_by_filename: # pragma: no mutate with open(directory + filename, 'w') as f2: # pragma: no mutate f2.write(doc) # pragma: no mutate # noinspection PyShadowingNames def _generate_rst_docs(classes, missing_objects=None): if missing_objects is None: missing_objects = tuple() import re def docstring_param_dict(obj): # noinspection PyShadowingNames doc = obj.__doc__ if doc is None: return dict(text=None, params={}) return dict( text=doc[:doc.find(':param')].strip() if ':param' in doc else doc.strip(), params=dict(re.findall(r":param (?P<name>\w+): (?P<text>.*)", doc)) ) def indent(levels, s): return (' ' * levels * 4) + s.strip() # noinspection PyShadowingNames def get_namespace(c): return Namespace( {k: c.__init__.dispatch.get(k) for k, v in get_declared(c, 'refinable_members').items()}) for c in classes: from io import StringIO f = StringIO() def w(levels, s): f.write(indent(levels, s)) f.write('\n') def section(level, title): underline = { 0: '=', 1: '-', 2: '^', }[level] * len(title) w(0, title) w(0, underline) w(0, '') section(0, c.__name__) class_doc = docstring_param_dict(c) constructor_doc = docstring_param_dict(c.__init__) if class_doc['text']: f.write(class_doc['text']) w(0, '') if constructor_doc['text']: if class_doc['text']: w(0, '') f.write(constructor_doc['text']) w(0, '') w(0, '') section(1, 'Refinable members') # noinspection PyCallByClass for refinable_, value in sorted(dict.items(get_namespace(c))): w(0, '* `' + refinable_ + '`') if constructor_doc['params'].get(refinable_): w(1, constructor_doc['params'][refinable_]) w(0, '') w(0, '') defaults = Namespace() for refinable_, value in sorted(get_namespace(c).items()): if value not in (None,) + missing_objects: defaults[refinable_] = value if defaults: section(2, 'Defaults') for k, v in sorted(flatten_items(defaults)): if v != {}: if '<lambda>' in repr(v): import inspect v = inspect.getsource(v) v = v[v.find('lambda'):] v = v.strip().strip(',') elif callable(v): v = v.__module__ + '.' + v.__name__ if v == '': v = '""' w(0, '* `%s`' % k) w(1, '* `%s`' % v) w(0, '') shortcuts = get_shortcuts_by_name(c) if shortcuts: section(1, 'Shortcuts') for name, shortcut_ in sorted(shortcuts.items()): section(2, f'`{name}`') if shortcut_.__doc__: doc = shortcut_.__doc__ f.write(doc.strip()) w(0, '') w(0, '') yield '/%s.rst' % c.__name__, f.getvalue()