def _get_opt(self, name='', default=None, opts='_opts'): attr = '{}.{}'.format(opts, name) if default is not None: if callable(default): return rgetattr(self, attr, default()) return rgetattr(self, attr, default) return rgetattr(self, attr)
def _combine_attr_dct(self, attr, typ=None): values = self._class_data.dct.get(attr, {}) if typ is not None: values = typ(values) for base in self._class_data.bases: vals = rgetattr(base, '_class_data.dct', {}).get(attr, {}) if typ is not None: vals = typ(vals) values = combine(vals, values) setattr(self, attr, values)
def test_rgetattr(): from syn.base_utils import rgetattr, AttrDict obj = AttrDict(a=AttrDict(b=AttrDict(c=1, d=2), e=AttrDict(f=3)), g=4) assert rgetattr(obj, 'a.b.c') == 1 assert rgetattr(obj, 'a.b.d') == 2 assert rgetattr(obj, 'a.e.f') == 3 assert rgetattr(obj, 'a.b.f', 7) == 7 assert rgetattr(obj, 'g') == 4 assert rgetattr(obj, 'g', 5) == 4 assert rgetattr(obj, 'h', 5) == 5 assert_raises(TypeError, rgetattr, obj, 'a', 3, 4) assert_raises(AttributeError, rgetattr, obj, 'h')
def _populate_data(self): self._data = Data() opt = Meta._get_opt # Generate attr display order self._data.attr_display_order = sorted(self._attrs.keys()) # Gather persistent pre-create hooks self._data.pre_create_hooks = \ {getfunc(f) for f in callables(self).values() if getattr(f, 'is_pre_create_hook', None) is _PreCreateHook and getattr(f, 'persist', False)} # Generate attr documentation order tmp = [] attrs = list(self._data.attr_display_order) for attr in opt(self, 'args', default=()): tmp.append(attr) attrs.remove(attr) tmp += attrs self._data.kw_attrs = attrs self._data.attr_documentation_order = tmp # Process metaclass_lookup sopt = partial(opt, opts='_seq_opts', default=list) for attr in sopt(self, 'metaclass_lookup'): attrs = sopt(self, attr) values = [getattr(self, attr_) for attr_ in attrs] values = type(attrs)(values) setattr(self._data, attr, values) # Register subclasses reg = partial(opt, name='register_subclasses', default=False) if reg(self): for c in self.mro(): if hasmethod(c, '_get_opt'): if reg(c): if issubclass(self, c): lst = rgetattr(c, '_data.subclasses') if self not in lst: lst.append(self) c._data.subclasses = lst
def test_rgetattr(): from syn.base_utils import rgetattr, AttrDict obj = AttrDict(a = AttrDict(b = AttrDict(c = 1, d = 2), e = AttrDict(f = 3)), g = 4) assert rgetattr(obj, 'a.b.c') == 1 assert rgetattr(obj, 'a.b.d') == 2 assert rgetattr(obj, 'a.e.f') == 3 assert rgetattr(obj, 'a.b.f', 7) == 7 assert rgetattr(obj, 'g') == 4 assert rgetattr(obj, 'g', 5) == 4 assert rgetattr(obj, 'h', 5) == 5 assert_raises(TypeError, rgetattr, obj, 'a', 3, 4) assert_raises(AttributeError, rgetattr, obj, 'h')
def _generate_documentation(cls): if not cls._get_opt('autodoc', default=True): return if rgetattr(cls, '__init__.__func__', False) is False: return args = cls._get_opt('args', default=()) kw_attrs = cls._data.kw_attrs data = {} data['signature'] = cls._generate_documentation_signature(args) data['doc'] = cls.__doc__ if cls.__doc__ else '' if cls.__init__.__func__.__doc__: data['doc'] += '\n\n' + cls.__init__.__func__.__doc__ data['attrspec'] = cls._generate_documentation_attrspec(args) data['kwattrspec'] = cls._generate_documentation_attrspec(kw_attrs) data['optspec'] = cls._generate_documentation_optspec() data['aliasspec'] = cls._generate_documentation_aliasspec() data['groupspec'] = cls._generate_documentation_groupspec() doc = CLASS_TEMPLATE.render(data) cls.__doc__ = doc
def _process_pre_create_hooks(cls, clsdata): hooks = {f for f in clsdata['dct'].values() if getattr(f, 'is_pre_create_hook', None) is _PreCreateHook} names = {f.__name__: f for f in hooks} for base in clsdata['bases']: hooks_ = rgetattr(base, '_data.pre_create_hooks', set()) for hook in hooks_: if hook.__name__ not in names: hooks.add(hook) names[hook.__name__] = hook relations = [copy(hook.hook_order) for hook in hooks if isinstance(hook.hook_order, Precedes)] # The preferred method of specifying order relations is by name; # Resolve names if present for rel in relations: rel.A = names[rel.A] if isinstance(rel.A, STR) else rel.A rel.B = names[rel.B] if isinstance(rel.B, STR) else rel.B hook_list = topological_sorting(hooks, relations) for hook in hook_list: hook(clsdata)