Beispiel #1
0
    def __init__(
            self,
            condition: Callable[..., Any],
            description: Optional[str] = None,
            a_repr: reprlib.Repr = icontract._globals.aRepr,
            enabled: bool = __debug__,
            error: Optional[Union[Callable[..., Exception],
                                  type]] = None) -> None:
        """
        Initialize a class decorator to establish the invariant on all the public methods.

        :param condition: invariant predicate
        :param description: textual description of the invariant
        :param a_repr: representation instance that defines how the values are represented
        :param enabled:
                The decorator is applied only if this argument is set.

                Otherwise, the condition check is disabled and there is no run-time overhead.

                The default is to always check the condition unless the interpreter runs in optimized mode (``-O`` or
                ``-OO``).
        :param error:
            if given as a callable, ``error`` is expected to accept a subset of function arguments
            (*e.g.*, also including ``result`` for perconditions, only ``self`` for invariants *etc.*) and return
            an exception. The ``error`` is called on contract violation and the resulting exception is raised.

            Otherwise, it is expected to denote an Exception class which is instantiated with the violation message
            and raised on contract violation.
        :return:

        """
        # pylint: disable=too-many-arguments
        self.enabled = enabled
        self._contract = None  # type: Optional[Contract]

        if not enabled:
            return

        location = None  # type: Optional[str]
        tb_stack = traceback.extract_stack(limit=2)[:1]
        if len(tb_stack) > 0:
            frame = tb_stack[0]
            location = 'File {}, line {} in {}'.format(frame.filename,
                                                       frame.lineno,
                                                       frame.name)

        self._contract = Contract(condition=condition,
                                  description=description,
                                  a_repr=a_repr,
                                  error=error,
                                  location=location)

        if self._contract.mandatory_args and self._contract.mandatory_args != [
                'self'
        ]:
            raise ValueError(
                "Expected an invariant condition with at most an argument 'self', but got: {}"
                .format(self._contract.condition_args))
Beispiel #2
0
    def __init__(
            self,
            condition: Callable[..., Any],
            description: Optional[str] = None,
            a_repr: reprlib.Repr = icontract._globals.aRepr,
            enabled: bool = __debug__,
            error: Optional[Union[Callable[..., Exception],
                                  type]] = None) -> None:
        """
        Initialize.

        :param condition: precondition predicate
        :param description: textual description of the precondition
        :param a_repr: representation instance that defines how the values are represented
        :param enabled:
            The decorator is applied only if this argument is set.

            Otherwise, the condition check is disabled and there is no run-time overhead.

            The default is to always check the condition unless the interpreter runs in optimized mode (``-O`` or
            ``-OO``).
        :param error:
            if given as a callable, ``error`` is expected to accept a subset of function arguments
            (*e.g.*, also including ``result`` for perconditions, only ``self`` for invariants *etc.*) and return
            an exception. The ``error`` is called on contract violation and the resulting exception is raised.

            Otherwise, it is expected to denote an Exception class which is instantiated with the violation message
            and raised on contract violation.

        """
        # pylint: disable=too-many-arguments
        self.enabled = enabled
        self._contract = None  # type: Optional[Contract]

        if not enabled:
            return

        self._contract = Contract(condition=condition,
                                  description=description,
                                  a_repr=a_repr,
                                  error=error)
Beispiel #3
0
    def __init__(
        self,
        condition: Callable[..., Any],
        description: Optional[str] = None,
        a_repr: reprlib.Repr = icontract._globals.aRepr,
        enabled: bool = __debug__,
        error: Optional[Union[Callable[..., ExceptionT], Type[ExceptionT],
                              BaseException]] = None
    ) -> None:
        """
        Initialize a class decorator to establish the invariant on all the public methods.

        :param condition:
            invariant predicate.

            The condition must not be a coroutine function as dunder functions (including ``__init__``)
            of a class can not be async.
        :param description: textual description of the invariant
        :param a_repr: representation instance that defines how the values are represented
        :param enabled:
                The decorator is applied only if this argument is set.

                Otherwise, the condition check is disabled and there is no run-time overhead.

                The default is to always check the condition unless the interpreter runs in optimized mode (``-O`` or
                ``-OO``).
        :param error:
            The error is expected to denote either:

            * A callable. ``error`` is expected to accept a subset of function arguments and return an exception.
              The ``error`` is called on contract violation and the resulting exception is raised.
            * A subclass of ``BaseException`` which is instantiated with the violation message and raised
              on contract violation.
            * An instance of ``BaseException`` that will be raised with the traceback on contract violation.
        :return:

        """
        # pylint: disable=too-many-arguments
        self.enabled = enabled
        self._contract = None  # type: Optional[Contract]

        if not enabled:
            return

        if error is None:
            pass
        elif isinstance(error, type):
            if not issubclass(error, BaseException):
                raise ValueError(
                    ("The error of the contract is given as a type, "
                     "but the type does not inherit from BaseException: {}"
                     ).format(error))
        else:
            if not inspect.isfunction(error) and not inspect.ismethod(
                    error) and not isinstance(error, BaseException):
                raise ValueError((
                    "The error of the contract must be either a callable (a function or a method), "
                    "a class (subclass of BaseException) or an instance of BaseException, but got: {}"
                ).format(error))

        location = None  # type: Optional[str]
        tb_stack = traceback.extract_stack(limit=2)[:1]
        if len(tb_stack) > 0:
            frame = tb_stack[0]
            location = 'File {}, line {} in {}'.format(frame.filename,
                                                       frame.lineno,
                                                       frame.name)

        if inspect.iscoroutinefunction(condition):
            raise ValueError(
                "Async conditions are not possible in invariants as sync methods such as __init__ have to be wrapped."
            )

        self._contract = Contract(condition=condition,
                                  description=description,
                                  a_repr=a_repr,
                                  error=error,
                                  location=location)

        if self._contract.mandatory_args and self._contract.mandatory_args != [
                'self'
        ]:
            raise ValueError(
                "Expected an invariant condition with at most an argument 'self', but got: {}"
                .format(self._contract.condition_args))
Beispiel #4
0
    def __init__(
        self,
        condition: Callable[..., Any],
        description: Optional[str] = None,
        a_repr: reprlib.Repr = icontract._globals.aRepr,
        enabled: bool = __debug__,
        error: Optional[Union[Callable[..., ExceptionT], Type[ExceptionT],
                              BaseException]] = None
    ) -> None:
        """
        Initialize.

        :param condition: precondition predicate

            If the condition returns a coroutine, you must specify the `error` as
            coroutines have side effects and can not be recomputed.
        :param description: textual description of the precondition
        :param a_repr: representation instance that defines how the values are represented
        :param enabled:
            The decorator is applied only if this argument is set.

            Otherwise, the condition check is disabled and there is no run-time overhead.

            The default is to always check the condition unless the interpreter runs in optimized mode (``-O`` or
            ``-OO``).
        :param error:
            The error is expected to denote either:

            * A callable. ``error`` is expected to accept a subset of function arguments and return an exception.
              The ``error`` is called on contract violation and the resulting exception is raised.
            * A subclass of ``BaseException`` which is instantiated with the violation message and raised
              on contract violation.
            * An instance of ``BaseException`` that will be raised with the traceback on contract violation.

        """
        # pylint: disable=too-many-arguments
        self.enabled = enabled
        self._contract = None  # type: Optional[Contract]

        if not enabled:
            return

        if error is None:
            pass
        elif isinstance(error, type):
            if not issubclass(error, BaseException):
                raise ValueError(
                    ("The error of the contract is given as a type, "
                     "but the type does not inherit from BaseException: {}"
                     ).format(error))
        else:
            if not inspect.isfunction(error) and not inspect.ismethod(
                    error) and not isinstance(error, BaseException):
                raise ValueError((
                    "The error of the contract must be either a callable (a function or a method), "
                    "a class (subclass of BaseException) or an instance of BaseException, but got: {}"
                ).format(error))

        location = None  # type: Optional[str]
        tb_stack = traceback.extract_stack(limit=2)[:1]
        if len(tb_stack) > 0:
            frame = tb_stack[0]
            location = 'File {}, line {} in {}'.format(frame.filename,
                                                       frame.lineno,
                                                       frame.name)

        self._contract = Contract(condition=condition,
                                  description=description,
                                  a_repr=a_repr,
                                  error=error,
                                  location=location)