Skip to content

Commit

Permalink
Merge 6e72ab4 into bad6707
Browse files Browse the repository at this point in the history
  • Loading branch information
orsinium committed Oct 7, 2019
2 parents bad6707 + 6e72ab4 commit b87e4c4
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 12 deletions.
8 changes: 6 additions & 2 deletions deal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@


# app
from ._aliases import chain, ensure, inv, invariant, offline, post, pre, pure, raises, require, safe, silent
from ._aliases import (
chain, ensure, inv, invariant, offline, post,
pre, pure, raises, reason, require, safe, silent
)
from ._exceptions import * # noQA
from ._schemes import Scheme
from ._state import reset, switch
Expand All @@ -39,15 +42,16 @@
'chain',
'ensure',
'inv',
'invariant',
'offline',
'post',
'pre',
'pure',
'raises',
'reason',
'safe',
'silent',

# aliases
'invariant',
'require',
]
19 changes: 10 additions & 9 deletions deal/_aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
from typing import Callable

# app
from ._decorators import Ensure, Invariant, Offline, Post, Pre, Raises, Silent
from . import _decorators
from ._types import ExceptionType


require = pre = Pre
post = Post
ensure = Ensure
inv = invariant = Invariant
raises = Raises
require = pre = _decorators.Pre
post = _decorators.Post
ensure = _decorators.Ensure
inv = invariant = _decorators.Invariant
raises = _decorators.Raises
reason = _decorators.Reason


# makes braces for decorator are optional
Expand All @@ -22,9 +23,9 @@ def _optional(_contract, _func: Callable = None, *, message: str = None,
return _contract(message=message, exception=exception, debug=debug)


offline = partial(_optional, Offline)
safe = partial(_optional, Raises)
silent = partial(_optional, Silent)
offline = partial(_optional, _decorators.Offline)
safe = partial(_optional, _decorators.Raises)
silent = partial(_optional, _decorators.Silent)


def chain(*contracts) -> Callable[[Callable], Callable]:
Expand Down
2 changes: 2 additions & 0 deletions deal/_decorators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .post import Post
from .pre import Pre
from .raises import Raises
from .reason import Reason
from .silent import Silent


Expand All @@ -15,5 +16,6 @@
'Post',
'Pre',
'Raises',
'Reason',
'Silent',
]
37 changes: 37 additions & 0 deletions deal/_decorators/reason.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# built-in
from typing import Callable

# app
from .._exceptions import ReasonContractError
from .._types import ExceptionType
from .base import Base


class Reason(Base):
exception: ExceptionType = ReasonContractError

def __init__(self, event: Exception, validator: Callable, *,
message: str = None, exception: ExceptionType = None, debug: bool = False):
"""
Step 1. Set allowed exceptions list.
"""
self.event = event
super().__init__(
validator=validator,
message=message,
exception=exception,
debug=debug,
)

def patched_function(self, *args, **kwargs):
"""
Step 3. Wrapped function calling.
"""
try:
return self.function(*args, **kwargs)
except self.event as origin:
try:
self.validate(*args, **kwargs)
except self.exception:
raise self.exception from origin
raise
4 changes: 4 additions & 0 deletions deal/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class RaisesContractError(ContractError):
pass


class ReasonContractError(ContractError):
pass


class OfflineContractError(ContractError):
pass

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ command = "sphinx-build -M html docs docs/build"


[tool.isort]
line_length = 120
line_length = 90
combine_as_imports = true
balanced_wrapping = true
lines_after_imports = 2
Expand Down
28 changes: 28 additions & 0 deletions tests/test_reason.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest

import deal


@deal.reason(ValueError, lambda x: x == 1)
def func(x):
if x == 0:
raise ZeroDivisionError
if x == 1:
raise ValueError
if x == 2:
raise ValueError
return x


def test_reason_just_works():
assert func(3) == 3


@pytest.mark.parametrize('value, exc', [
(0, ZeroDivisionError),
(1, ValueError),
(2, deal.ReasonContractError),
])
def test_reason_exception(value, exc):
with pytest.raises(exc):
func(value)

0 comments on commit b87e4c4

Please sign in to comment.