예제 #1
0
def _assert_invariant(contract: Contract, instance: Any) -> None:
    """Assert that the contract holds as a class invariant given the instance of the class."""
    if 'self' in contract.condition_arg_set:
        check = contract.condition(self=instance)
    else:
        check = contract.condition()

    if _not_check(check=check, contract=contract):
        if contract.error is not None and (inspect.ismethod(contract.error) or
                                           inspect.isfunction(contract.error)):
            assert contract.error_arg_set is not None, "Expected error_arg_set non-None if contract.error a function."
            assert contract.error_args is not None, "Expected error_args non-None if contract.error a function."

            if 'self' in contract.error_arg_set:
                raise contract.error(self=instance)
            else:
                raise contract.error()
        else:
            if 'self' in contract.condition_arg_set:
                msg = icontract._represent.generate_message(
                    contract=contract, condition_kwargs={"self": instance})
            else:
                msg = icontract._represent.generate_message(
                    contract=contract, condition_kwargs=dict())

            if contract.error is None:
                raise ViolationError(msg)
            elif isinstance(contract.error, type):
                raise contract.error(msg)
            else:
                raise NotImplementedError(
                    "Unhandled contract.error: {}".format(contract.error))
예제 #2
0
def _assert_invariant(contract: Contract, instance: Any) -> None:
    """Assert that the contract holds as a class invariant given the instance of the class."""
    if 'self' in contract.condition_arg_set:
        check = contract.condition(self=instance)
    else:
        check = contract.condition()

    if not_check(check=check, contract=contract):
        raise _create_violation_error(contract=contract, resolved_kwargs={'self': instance})
예제 #3
0
def _assert_precondition(contract: Contract,
                         resolved_kwargs: Mapping[str, Any]) -> None:
    """
    Assert that the contract holds as a precondition.

    :param contract: contract to be verified
    :param resolved_kwargs:
        resolved keyword arguments of the call (including the default argument values of the decorated function)
    :return:
    """
    condition_kwargs = select_condition_kwargs(contract=contract,
                                               resolved_kwargs=resolved_kwargs)

    check = contract.condition(**condition_kwargs)

    if not_check(check=check, contract=contract):
        if contract.error is not None and (inspect.ismethod(contract.error) or
                                           inspect.isfunction(contract.error)):
            assert contract.error_arg_set is not None, "Expected error_arg_set non-None if contract.error a function."
            assert contract.error_args is not None, "Expected error_args non-None if contract.error a function."

            error_kwargs = {
                arg_name: value
                for arg_name, value in resolved_kwargs.items()
                if arg_name in contract.error_arg_set
            }

            missing_args = [
                arg_name for arg_name in contract.error_args
                if arg_name not in resolved_kwargs
            ]
            if missing_args:
                msg_parts = []
                if contract.location is not None:
                    msg_parts.append("{}:\n".format(contract.location))

                msg_parts.append((
                    "The argument(s) of the precondition error have not been set: {}. "
                    "Does the original function define them? Did you supply them in the call?"
                ).format(missing_args))

                raise TypeError(''.join(msg_parts))

            raise contract.error(**error_kwargs)

        else:
            msg = icontract._represent.generate_message(
                contract=contract, condition_kwargs=condition_kwargs)
            if contract.error is None:
                raise ViolationError(msg)
            elif isinstance(contract.error, type):
                raise contract.error(msg)
예제 #4
0
def _assert_postcondition(contract: Contract,
                          resolved_kwargs: Mapping[str, Any]) -> None:
    """
    Assert that the contract holds as a postcondition.

    The arguments to the postcondition are given as ``resolved_kwargs`` which includes
    both argument values captured in snapshots and actual argument values and the result of a function.

    :param contract: contract to be verified
    :param resolved_kwargs: resolved keyword arguments (including the default values, ``result`` and ``OLD``)
    :return:
    """
    assert 'result' in resolved_kwargs, \
        "Expected 'result' to be set in the resolved keyword arguments of a postcondition."

    # Check that all arguments to the condition function have been set.
    missing_args = [
        arg_name for arg_name in contract.mandatory_args
        if arg_name not in resolved_kwargs
    ]
    if missing_args:
        msg_parts = []  # type: List[str]
        if contract.location is not None:
            msg_parts.append("{}:\n".format(contract.location))

        msg_parts.append((
            "The argument(s) of the postcondition have not been set: {}. "
            "Does the original function define them? Did you supply them in the call?"
        ).format(missing_args))

        raise TypeError(''.join(msg_parts))

    condition_kwargs = {
        arg_name: value
        for arg_name, value in resolved_kwargs.items()
        if arg_name in contract.condition_arg_set
    }

    check = contract.condition(**condition_kwargs)

    if _not_check(check=check, contract=contract):
        if contract.error is not None and (inspect.ismethod(contract.error) or
                                           inspect.isfunction(contract.error)):
            assert contract.error_arg_set is not None, "Expected error_arg_set non-None if contract.error a function."
            assert contract.error_args is not None, "Expected error_args non-None if contract.error a function."

            error_kwargs = {
                arg_name: value
                for arg_name, value in resolved_kwargs.items()
                if arg_name in contract.error_arg_set
            }

            missing_args = [
                arg_name for arg_name in contract.error_args
                if arg_name not in resolved_kwargs
            ]
            if missing_args:
                msg_parts = []
                if contract.location is not None:
                    msg_parts.append("{}:\n".format(contract.location))

                msg_parts.append((
                    "The argument(s) of the postcondition error have not been set: {}. "
                    "Does the original function define them? Did you supply them in the call?"
                ).format(missing_args))

                raise TypeError(''.join(msg_parts))

            raise contract.error(**error_kwargs)

        else:
            msg = icontract._represent.generate_message(
                contract=contract, condition_kwargs=condition_kwargs)
            if contract.error is None:
                raise ViolationError(msg)
            elif isinstance(contract.error, type):
                raise contract.error(msg)