Ejemplo n.º 1
0
    def __new__(cls, classname, bases, classdict):
        """I copy docstrings from base class methods to deriving classes.

        Copying of docstrings is disabled when the `PYMOR_WITH_SPHINX` environment
        variable is set to `1`.
        """
        for attr in ('_init_arguments', '_init_defaults'):
            if attr in classdict:
                raise ValueError(
                    attr +
                    ' is a reserved class attribute for subclasses of BasicInterface'
                )

        for attr, item in classdict.items():
            if isinstance(item, FunctionType):
                # first copy/fixup docs
                item.__doc__ = decorators.fixup_docstring(item.__doc__)
                base_doc = None
                for base in bases:
                    base_func = getattr(base, item.__name__, None)
                    if not DONT_COPY_DOCSTRINGS:
                        if base_func:
                            base_doc = getattr(base_func, '__doc__', None)
                        if base_doc:
                            doc = decorators.fixup_docstring(
                                getattr(item, '__doc__', ''))
                            if doc is not None:
                                base_doc = doc
                            item.__doc__ = base_doc

        c = abc.ABCMeta.__new__(cls, classname, bases, classdict)

        if PY2:
            try:
                args, varargs, keywords, defaults = inspect.getargspec(
                    c.__init__)
                assert args[0] == 'self'
                c._init_arguments = tuple(args[1:])
            except TypeError:  # happens when no one declares an __init__ method and object is reached
                c._init_arguments = ()
        else:
            # getargspec is deprecated and does not work with keyword only args
            init_sig = inspect.signature(c.__init__)
            init_args = []
            for arg, description in init_sig.parameters.items():
                if arg == 'self':
                    continue
                if description.kind == description.POSITIONAL_ONLY:
                    raise TypeError(
                        'It should not be possible that {}.__init__ has POSITIONAL_ONLY arguments'
                        .format(c))
                if description.kind in (description.POSITIONAL_OR_KEYWORD,
                                        description.KEYWORD_ONLY):
                    init_args.append(arg)
            c._init_arguments = tuple(init_args)

        return c
Ejemplo n.º 2
0
    def __new__(cls, classname, bases, classdict):
        """I copy docstrings from base class methods to deriving classes.

        Copying of docstrings is disabled when the `PYMOR_WITH_SPHINX` environment
        variable is set to `1`.
        """
        for attr in ('_init_arguments', '_init_defaults'):
            if attr in classdict:
                raise ValueError(attr + ' is a reserved class attribute for subclasses of BasicInterface')

        for attr, item in classdict.items():
            if isinstance(item, FunctionType):
                # first copy/fixup docs
                item.__doc__ = decorators.fixup_docstring(item.__doc__)
                base_doc = None
                for base in bases:
                    base_func = getattr(base, item.__name__, None)
                    if not DONT_COPY_DOCSTRINGS:
                        if base_func:
                            base_doc = getattr(base_func, '__doc__', None)
                        if base_doc:
                            doc = decorators.fixup_docstring(getattr(item, '__doc__', ''))
                            if doc is not None:
                                base_doc = doc
                            item.__doc__ = base_doc

        c = abc.ABCMeta.__new__(cls, classname, bases, classdict)

        if PY2:
            try:
                args, varargs, keywords, defaults = inspect.getargspec(c.__init__)
                assert args[0] == 'self'
                c._init_arguments = tuple(args[1:])
            except TypeError:       # happens when no one declares an __init__ method and object is reached
                c._init_arguments = ()
        else:
            # getargspec is deprecated and does not work with keyword only args
            init_sig = inspect.signature(c.__init__)
            init_args = []
            for arg, description in init_sig.parameters.items():
                if arg == 'self':
                    continue
                if description.kind == description.POSITIONAL_ONLY:
                    raise TypeError('It should not be possible that {}.__init__ has POSITIONAL_ONLY arguments'.
                                    format(c))
                if description.kind in (description.POSITIONAL_OR_KEYWORD, description.KEYWORD_ONLY):
                    init_args.append(arg)
            c._init_arguments = tuple(init_args)

        return c
Ejemplo n.º 3
0
    def __new__(cls, classname, bases, classdict):
        """I copy docstrings from base class methods to deriving classes.
        I also forward "abstract{class|static}method" decorations in the base class to "{class|static}method"
        decorations in the new subclass.

        Copying of docstrings can be prevented by setting the `PYMOR_COPY_DOCSTRINGS_DISABLE` environment
        variable to `1`.
        """
        for attr in ('_init_arguments', '_init_defaults'):
            if attr in classdict:
                raise ValueError(attr + ' is a reserved class attribute for subclasses of BasicInterface')

        for attr, item in classdict.items():
            if isinstance(item, FunctionType):
                # first copy/fixup docs
                item.__doc__ = decorators.fixup_docstring(item.__doc__)
                base_doc = None
                for base in bases:
                    base_func = getattr(base, item.__name__, None)
                    if not DONT_COPY_DOCSTRINGS:
                        if base_func:
                            base_doc = getattr(base_func, '__doc__', None)
                        if base_doc:
                            doc = decorators.fixup_docstring(getattr(item, '__doc__', ''))
                            if doc is not None:
                                base_doc = doc
                            item.__doc__ = base_doc
                    if (hasattr(base_func, "__isabstractstaticmethod__") and
                            getattr(base_func, "__isabstractstaticmethod__")):
                        classdict[attr] = staticmethod(classdict[attr])
                    if (hasattr(base_func, "__isabstractclassmethod__") and
                            getattr(base_func, "__isabstractclassmethod__")):
                        classdict[attr] = classmethod(classdict[attr])

        c = abc.ABCMeta.__new__(cls, classname, bases, classdict)

        # Beware! The following will probably break in python 3 if there are
        # keyword-only arguemnts
        try:
            args, varargs, keywords, defaults = inspect.getargspec(c.__init__)
            assert args[0] == 'self'
            c._init_arguments = tuple(args[1:])
            if defaults:
                c._init_defaults = dict(zip(args[-len(defaults):], defaults))
            else:
                c._init_defaults = dict()
        except TypeError:       # happens when no one declares an __init__ method and object is reached
            c._init_arguments = tuple()
            c._init_defaults = dict()
        return c
Ejemplo n.º 4
0
    def __new__(cls, classname, bases, classdict):
        '''I copy contract decorations and docstrings from base class methods to deriving classes.
        I also forward "abstract{class|static}method" decorations in the base class to "{class|static}method"
        decorations in the new subclass.
        '''
        for attr, item in classdict.items():
            if isinstance(item, types.FunctionType):
                # first copy/fixup docs
                item.__doc__ = decorators.fixup_docstring(item.__doc__)
                base_doc = None
                contract_kwargs = dict()
                for base in bases:
                    has_contract = False
                    base_func = getattr(base, item.__name__, None)
                    if base_func:
                        base_doc = getattr(base_func, '__doc__', None)
                        has_contract = getattr(base_func, 'decorated', None) == 'contract'
                        contract_kwargs = getattr(base_func, 'contract_kwargs', contract_kwargs)
                    if base_doc:
                        doc = decorators.fixup_docstring(getattr(item, '__doc__', ''))
                        has_base_contract_docs = decorators.contains_contract(base_doc)
                        has_contract_docs = decorators.contains_contract(doc)
                        if has_base_contract_docs and not has_contract_docs:
                            base_doc += doc
                        elif not has_base_contract_docs and doc is not None:
                            base_doc = doc
                        item.__doc__ = base_doc
                    if has_contract:
                        # TODO why is the rebind necessary?
                        classdict['_H_%s' % attr] = item
                        contract_kwargs = contract_kwargs or dict()
                        p = decorators.contracts_decorate(item, modify_docstring=True, **contract_kwargs)
                        classdict[attr] = p
                    if (hasattr(base_func, "__isabstractstaticmethod__") and
                            getattr(base_func, "__isabstractstaticmethod__")):
                        classdict[attr] = staticmethod(classdict[attr])
                    if (hasattr(base_func, "__isabstractclassmethod__") and
                            getattr(base_func, "__isabstractclassmethod__")):
                        classdict[attr] = classmethod(classdict[attr])

        return abc.ABCMeta.__new__(cls, classname, bases, classdict)
Ejemplo n.º 5
0
    def __new__(cls, classname, bases, classdict):
        """I copy contract decorations and docstrings from base class methods to deriving classes.
        I also forward "abstract{class|static}method" decorations in the base class to "{class|static}method"
        decorations in the new subclass.

        Copying of docstrings can be prevented by setting the `PYMOR_COPY_DOCSTRINGS_DISABLE` environment
        variable to `1`.
        """
        for attr in ('_init_arguments', '_init_defaults'):
            if attr in classdict:
                raise ValueError(
                    attr +
                    ' is a reserved class attribute for subclasses of BasicInterface'
                )

        for attr, item in classdict.items():
            if isinstance(item, types.FunctionType):
                # first copy/fixup docs
                item.__doc__ = decorators.fixup_docstring(item.__doc__)
                base_doc = None
                contract_kwargs = dict()
                for base in bases:
                    base_func = getattr(base, item.__name__, None)
                    if not DONT_COPY_DOCSTRINGS:
                        has_contract = False
                        if base_func:
                            base_doc = getattr(base_func, '__doc__', None)
                            if HAVE_CONTRACTS:
                                has_contract = getattr(base_func, 'decorated',
                                                       None) == 'contract'
                                contract_kwargs = getattr(
                                    base_func, 'contract_kwargs',
                                    contract_kwargs)
                        if base_doc:
                            doc = decorators.fixup_docstring(
                                getattr(item, '__doc__', ''))
                            if HAVE_CONTRACTS:
                                has_base_contract_docs = decorators.contains_contract(
                                    base_doc)
                                has_contract_docs = decorators.contains_contract(
                                    doc)
                                if has_base_contract_docs and not has_contract_docs:
                                    base_doc += doc
                                elif not has_base_contract_docs and doc is not None:
                                    base_doc = doc
                            elif doc is not None:
                                base_doc = doc
                            item.__doc__ = base_doc
                        if has_contract:
                            # TODO why is the rebind necessary?
                            classdict['_H_%s' % attr] = item
                            contract_kwargs = contract_kwargs or dict()
                            p = decorators.contracts_decorate(
                                item, modify_docstring=True, **contract_kwargs)
                            classdict[attr] = p
                    if (hasattr(base_func, "__isabstractstaticmethod__") and
                            getattr(base_func, "__isabstractstaticmethod__")):
                        classdict[attr] = staticmethod(classdict[attr])
                    if (hasattr(base_func, "__isabstractclassmethod__") and
                            getattr(base_func, "__isabstractclassmethod__")):
                        classdict[attr] = classmethod(classdict[attr])

        c = abc.ABCMeta.__new__(cls, classname, bases, classdict)

        # Beware! The following will probably break in python 3 if there are
        # keyword-only arguemnts
        try:
            args, varargs, keywords, defaults = inspect.getargspec(c.__init__)
            assert args[0] == 'self'
            c._init_arguments = tuple(args[1:])
            if defaults:
                c._init_defaults = dict(zip(args[-len(defaults):], defaults))
            else:
                c._init_defaults = dict()
        except TypeError:  # happens when no one declares an __init__ method and object is reached
            c._init_arguments = tuple()
            c._init_defaults = dict()
        return c
Ejemplo n.º 6
0
    def __new__(cls, classname, bases, classdict):
        '''I copy contract decorations and docstrings from base class methods to deriving classes.
        I also forward "abstract{class|static}method" decorations in the base class to "{class|static}method"
        decorations in the new subclass.

        Copying of docstrings can be prevented by setting the `PYMOR_COPY_DOCSTRINGS_DISABLE` environment
        variable to `1`.
        '''
        if 'init_arguments' in classdict:
            raise ValueError('init_arguments is a reserved class attribute for subclasses of BasicInterface')

        for attr, item in classdict.items():
            if isinstance(item, types.FunctionType):
                # first copy/fixup docs
                item.__doc__ = decorators.fixup_docstring(item.__doc__)
                base_doc = None
                contract_kwargs = dict()
                for base in bases:
                    base_func = getattr(base, item.__name__, None)
                    if not DONT_COPY_DOCSTRINGS:
                        has_contract = False
                        if base_func:
                            base_doc = getattr(base_func, '__doc__', None)
                            if HAVE_CONTRACTS:
                                has_contract = getattr(base_func, 'decorated', None) == 'contract'
                                contract_kwargs = getattr(base_func, 'contract_kwargs', contract_kwargs)
                        if base_doc:
                            doc = decorators.fixup_docstring(getattr(item, '__doc__', ''))
                            if HAVE_CONTRACTS:
                                has_base_contract_docs = decorators.contains_contract(base_doc)
                                has_contract_docs = decorators.contains_contract(doc)
                                if has_base_contract_docs and not has_contract_docs:
                                    base_doc += doc
                                elif not has_base_contract_docs and doc is not None:
                                    base_doc = doc
                            elif doc is not None:
                                base_doc = doc
                            item.__doc__ = base_doc
                        if has_contract:
                            # TODO why is the rebind necessary?
                            classdict['_H_%s' % attr] = item
                            contract_kwargs = contract_kwargs or dict()
                            p = decorators.contracts_decorate(item, modify_docstring=True, **contract_kwargs)
                            classdict[attr] = p
                    if (hasattr(base_func, "__isabstractstaticmethod__") and
                            getattr(base_func, "__isabstractstaticmethod__")):
                        classdict[attr] = staticmethod(classdict[attr])
                    if (hasattr(base_func, "__isabstractclassmethod__") and
                            getattr(base_func, "__isabstractclassmethod__")):
                        classdict[attr] = classmethod(classdict[attr])

        c = abc.ABCMeta.__new__(cls, classname, bases, classdict)

        # Beware! The following will probably break in python 3 if there are
        # keyword-only arguemnts
        try:
            args, varargs, keywords, defaults = inspect.getargspec(c.__init__)
            if varargs:
                raise NotImplementedError
            assert args[0] == 'self'
            c.init_arguments = tuple(args[1:])
        except TypeError:       # happens when no one declares an __init__ method and object is reached
            c.init_arguments = tuple()
        return c