Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct handling of None in TupleNode + Extended support from typing.List to typing.Iterable #65

Merged
merged 2 commits into from
Mar 7, 2018

Conversation

smarie
Copy link

@smarie smarie commented Jan 31, 2018

Correct handling of None in TupleNode: Fixes #62.

You might wish to add corresponding unit tests:

This should not raise an error anymore:

from typing import Optional, Tuple
from enforce import runtime_validation

@runtime_validation
def foo(arg: Optional[Tuple[str, str]] = None):
    pass

foo()

While this should continue to raise an error as usual:

from typing import Tuple
from enforce import runtime_validation

@runtime_validation
def foo(arg: Tuple[str, str]):
    pass


foo(None)

Extended support from typing.List to typing.Iterable (and Dict to Mapping)

Fixes #52, Fixes #51, fixes #47.

You might wish to include the following basic tests:

from enforce import runtime_validation, config
from enforce.exceptions import RuntimeTypeError
config(dict(mode='covariant'))  # by the way, so sad that this is not the default :)


########## SEQUENCE / ITERABLE / SET / GENERATOR
from typing import Sequence, Iterable, Set, Generator

@runtime_validation
def seq(s: Sequence[str]):
    pass

@runtime_validation
def it(s: Iterable[str]):
    pass


seq(['a'])
# transform this into appropriate test handler
try:
    seq(['r', 1])
    raise Exception('failed!')
except RuntimeTypeError:
    pass

it(['a'])
# transform this into appropriate test handler
try:
    it(['r', 1])
    raise Exception('failed!')
except RuntimeTypeError:
    pass


@runtime_validation
def st(m: Set[int]):
    pass


st({2, 2})
# transform this into appropriate test handler
try:
    st({'r', 1})
    raise Exception('failed!')
except RuntimeTypeError:
    pass


@runtime_validation
def generator() -> Generator[int, None, None]:
    i = 0
    while True:
        if i == 0:
            yield i
        else:
            yield 'a string! it cannot be detected by enforce but thats a bit normal'
        i += 1


g = generator()
print(next(g))
print(next(g))


########## MAPPING
from typing import Mapping


@runtime_validation
def bar(m: Mapping[int, int]):
    pass


bar({2: 2})
# transform this into appropriate test handler
try:
    bar({'r': 1})
    raise Exception('failed!')
except RuntimeTypeError:
    pass

Note: the fix with Iterable can probably fail in some rare cases where users define a custom typing.GenericMeta type inheriting from typing.Iterable BUT having several inner generic arguments (like it is in typing.Mapping, that we currently handle correctly by handling it BEFORE other Iterables). Not sure that this case will happen soon :)

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 92.622% when pulling 4ae2ea7 on smarie:dev into b5a8899 on RussBaz:dev.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 92.622% when pulling 4ae2ea7 on smarie:dev into b5a8899 on RussBaz:dev.

@RussBaz RussBaz merged commit 9a1b230 into RussBaz:dev Mar 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants