コード例 #1
0
    def __new__(mcs, name, bases, clsdict):
        mcs_args = McsArgs(mcs, name, bases, clsdict)
        if mcs_args.is_abstract:
            return super().__new__(*mcs_args)

        cls = super().__new__(*mcs_args)
        routes = {}
        include_methods = set(cls.Meta.include_methods)
        exclude_methods = set(cls.Meta.exclude_methods)
        for method_name in ALL_METHODS:
            if (method_name in exclude_methods
                    or method_name not in include_methods):
                continue

            route = getattr(clsdict.get(method_name), FN_ROUTES_ATTR, [None])[0]
            if not route:
                route = Route(None, mcs_args.getattr(method_name))

            if method_name in INDEX_METHODS:
                rule = '/'
            else:
                rule = cls.Meta.member_param
            route.rule = rule
            routes[method_name] = [route]

        setattr(cls, CONTROLLER_ROUTES_ATTR, routes)
        return cls
コード例 #2
0
    def __new__(mcs, name, bases, clsdict):
        mcs_args = McsArgs(mcs, name, bases, clsdict)
        _set_up_class_dependency_injection(mcs_args)
        if mcs_args.is_abstract:
            return super().__new__(*mcs_args)

        meta = mcs_args.getattr('Meta', None)
        model_missing = False
        try:
            if meta.model is None:
                model_missing = True
        except AttributeError:
            model_missing = True

        if model_missing:
            raise AttributeError(f'{name} is missing the ``class Meta`` model attribute')

        model = None
        try:
            model = unchained.sqlalchemy_bundle.models[meta.model.__name__]
        except AttributeError:
            # this happens when attempting to generate documentation and the
            # sqlalchemy bundle hasn't been loaded
            pass
        except KeyError:
            pass

        meta_dict = dict(meta.__dict__)
        meta_dict.pop('model', None)
        clsdict['Meta'] = type('Meta', (_ModelSerializerMeta,), meta_dict)
        clsdict['Meta'].model = model

        return super().__new__(*mcs_args)
コード例 #3
0
ファイル: controller.py プロジェクト: gnyers/flask-unchained
    def __new__(mcs, name, bases, clsdict):
        mcs_args = McsArgs(mcs, name, bases, clsdict)
        set_up_class_dependency_injection(mcs_args)
        if clsdict.get('__abstract__',
                       getattr(clsdict.get('Meta'), 'abstract', False)):
            mcs_args.clsdict[REMOVE_SUFFIXES_ATTR] = _get_remove_suffixes(
                name, bases, CONTROLLER_REMOVE_EXTRA_SUFFIXES)
            mcs_args.clsdict[NOT_VIEWS_ATTR] = _get_not_views(clsdict, bases)

        apply_factory_meta_options(
            mcs_args, default_factory_class=ControllerMetaOptionsFactory)

        cls = super().__new__(*mcs_args)
        if mcs_args.Meta.abstract:
            return cls

        controller_routes = getattr(cls, CONTROLLER_ROUTES_ATTR, {}).copy()
        not_views = deep_getattr({}, bases, NOT_VIEWS_ATTR)

        for method_name, method in clsdict.items():
            if (method_name in not_views
                    or not _is_view_func(method_name, method)):
                controller_routes.pop(method_name, None)
                continue

            controller_routes[method_name] = getattr(method, FN_ROUTES_ATTR,
                                                     [Route(None, method)])

        setattr(cls, CONTROLLER_ROUTES_ATTR, controller_routes)
        return cls
コード例 #4
0
def set_up_class_dependency_injection(mcs_args: McsArgs):
    if '__init__' in mcs_args.clsdict:
        from .unchained import unchained
        init = unchained.inject()(mcs_args.clsdict['__init__'])
        mcs_args.clsdict['__init__'] = init
        mcs_args.clsdict['__signature__'] = init.__signature__

    for attr, fn in mcs_args.clsdict.items():
        if isinstance(fn, FunctionType) and hasattr(fn, '__signature__'):
            fn.__di_name__ = (mcs_args.name if fn.__name__ == '__init__' else
                              f'{mcs_args.name}.{fn.__name__}')
コード例 #5
0
    def get_value(self, meta, base_classes_meta, mcs_args: McsArgs):
        value = super().get_value(meta, base_classes_meta, mcs_args)
        if value is not _missing:
            return value

        return controller_name(mcs_args.name,
                               mcs_args.getattr(REMOVE_SUFFIXES_ATTR))
コード例 #6
0
    def __new__(mcs, name, bases, clsdict):
        mcs_args = McsArgs(mcs, name, bases, clsdict)
        set_up_class_dependency_injection(mcs_args)
        if ABSTRACT_ATTR in clsdict:
            return super().__new__(mcs, name, bases, clsdict)

        meta = deep_getattr(clsdict, bases, 'Meta', None)
        model_missing = False
        try:
            if meta.model is None:
                model_missing = True
        except AttributeError:
            model_missing = True

        if model_missing:
            raise AttributeError(f'{name} is missing the class '
                                 f'Meta model attribute')
        else:
            try:
                meta.model = unchained.sqlalchemy_bundle.models[
                    meta.model.__name__]
            except AttributeError:
                # this happens when attempting to generate documentation and the
                # sqlalchemy bundle hasn't been loaded
                pass
            except KeyError:
                pass

        clsdict['Meta'] = meta
        return super().__new__(mcs, name, bases, clsdict)
コード例 #7
0
    def get_value(self, meta, base_classes_meta, mcs_args: McsArgs):
        value = super().get_value(meta, base_classes_meta, mcs_args)
        if value is not _missing:
            return value

        ctrl_name = controller_name(mcs_args.name,
                                    mcs_args.getattr(REMOVE_SUFFIXES_ATTR))
        return '/' + pluralize(ctrl_name.replace('_', '-'))
コード例 #8
0
    def __new__(mcs, name, bases, clsdict):
        mcs_args = McsArgs(mcs, name, bases, clsdict)
        _set_up_class_dependency_injection(mcs_args)
        if mcs_args.is_abstract:
            return super().__new__(*mcs_args)

        meta = mcs_args.getattr('Meta', None)
        model_missing = False
        try:
            if meta.model is None:
                model_missing = True
        except AttributeError:
            model_missing = True

        if model_missing:
            raise AttributeError(
                f'{name} is missing the ``class Meta`` model attribute')

        model = meta.model
        try:
            model = unchained.sqlalchemy_bundle.models[meta.model.__name__]
        except AttributeError as e:
            # this happens when attempting to generate documentation and the
            # sqlalchemy bundle hasn't been loaded
            safe_error = "'DeferredBundleFunctions' object has no attribute 'models'"
            if safe_error not in str(e):
                raise e
        except KeyError:
            pass

        meta_dict = dict(meta.__dict__)

        additional_fields = meta_dict.pop('additional', None)
        if additional_fields:
            fields = [
                name for name, field in clsdict.items()
                if isinstance(field, Field)
            ]
            meta_dict['fields'] = fields + list(additional_fields)

        meta_dict.pop('model', None)
        clsdict['Meta'] = type('Meta', (_ModelSerializerMeta, ), meta_dict)
        clsdict['Meta'].model = model

        return super().__new__(*mcs_args)
コード例 #9
0
    def __new__(mcs, name, bases, clsdict):
        mcs_args = McsArgs(mcs, name, bases, clsdict)
        _set_up_class_dependency_injection(mcs_args)
        process_factory_meta_options(
            mcs_args, default_factory_class=_ServiceMetaOptionsFactory)

        # extended concrete services should not inherit their super's di name
        if deep_getattr({}, bases, '__di_name__', None):
            clsdict['__di_name__'] = None

        return super().__new__(*mcs_args)
コード例 #10
0
 def __new__(mcs, name, bases, clsdict):
     mcs_args = McsArgs(mcs, name, bases, clsdict)
     Meta = process_factory_meta_options(mcs_args,
                                         ModelFormMetaOptionsFactory)
     mcs_args.clsdict['Meta'] = type('Meta', (), Meta._to_clsdict())
     if not Meta.abstract and unchained._models_initialized:
         try:
             Meta.model = unchained.sqlalchemy_bundle.models[
                 Meta.model.__name__]
         except KeyError:
             pass
         new_clsdict = model_fields(Meta.model,
                                    only=Meta.only,
                                    exclude=Meta.exclude,
                                    exclude_fk=Meta.exclude_fk,
                                    exclude_pk=Meta.exclude_pk,
                                    field_args=Meta.field_args,
                                    db_session=db.session,
                                    converter=_ModelConverter())
         new_clsdict.update(mcs_args.clsdict)
         mcs_args.clsdict = new_clsdict
     return super().__new__(*mcs_args)
コード例 #11
0
    def check_value(self, value, mcs_args: McsArgs):
        if not value:
            return

        if isinstance(value, (list, tuple)):
            assert all(callable(x) for x in value), \
                f'The {self.name} meta option requires a list or tuple of callables'
        else:
            for method_name, decorators in value.items():
                assert mcs_args.getattr(method_name), \
                    f'The {method_name} was not found on {mcs_args.name}'
                assert all(callable(x) for x in decorators), \
                    f'Invalid decorator detected in the {self.name} meta option for ' \
                    f'the {method_name} key'
コード例 #12
0
def _set_up_class_dependency_injection(mcs_args: McsArgs):
    mcs_args.clsdict[_DI_AUTOMATICALLY_HANDLED] = True

    cls_attrs_to_inject = [
        k for k, v in mcs_args.clsdict.items() if v == injectable
    ]
    try:
        mcs_args.clsdict[_INJECT_CLS_ATTRS] = \
            cls_attrs_to_inject + mcs_args.getattr(_INJECT_CLS_ATTRS, [])
    except TypeError as e:
        if 'can only concatenate list (not "OptionalMetaclass") to list' not in str(
                e):
            raise e
        mcs_args.clsdict[_INJECT_CLS_ATTRS] = cls_attrs_to_inject

    if '__init__' not in mcs_args.clsdict and cls_attrs_to_inject:
        init = _inject_cls_attrs(
            _call_super_for_cls=f'{mcs_args.module}:{mcs_args.name}')
        init.__di_name__ = mcs_args.name
        init.__signature__ = inspect.signature(object)
        mcs_args.clsdict['__init__'] = init
        mcs_args.clsdict['__signature__'] = init.__signature__
    elif '__init__' in mcs_args.clsdict:
        from .unchained import unchained
        init = unchained.inject()(mcs_args.clsdict['__init__'])
        init.__di_name__ = mcs_args.name
        mcs_args.clsdict['__init__'] = (init if not cls_attrs_to_inject else
                                        _inject_cls_attrs(_wrapped_fn=init))
        mcs_args.clsdict['__signature__'] = init.__signature__

    for attr, value in mcs_args.clsdict.items():
        if isinstance(value, FunctionType):
            if not attr.startswith('__') and not hasattr(
                    value, '__signature__'):
                from .unchained import unchained
                mcs_args.clsdict[attr] = unchained.inject()(value)
            value.__di_name__ = (mcs_args.name if value.__name__ == '__init__'
                                 else f'{mcs_args.name}.{value.__name__}')