classes icon indicating copy to clipboard operation
classes copied to clipboard

Use `returns` in testing

Open sobolevn opened this issue 4 years ago • 9 comments

We need to be sure that classes and returns can be used together and that typing works.

Plan:

  1. Install returns as dev-dependency
  2. Create special typesafety/test_integration/test_returns folder where we would test it
  3. In pytest-mypy-plugins we would need to add returns_plugin to mypy settings

sobolevn avatar Jun 20 '21 08:06 sobolevn

We would probably would need to improve https://classes.readthedocs.io/en/latest/pages/dry-python.html page as well.

sobolevn avatar Jun 20 '21 08:06 sobolevn

Could you say more about what those tests should be, please?

thepabloaguilar avatar Oct 02 '21 08:10 thepabloaguilar

We need to test:

  1. Result.success_type and failure_type
  2. Maybe with empty
  3. IOResult

So, imagine that you want to dispatch some action based on the result/mayb type using classes. That's we basically need to cover for different types.

sobolevn avatar Oct 02 '21 08:10 sobolevn

I got some errors with Result using the example from the docs:

from classes import typeclass
from returns.result import Result, Success, Failure

@typeclass
def result_to_str(instance) -> str:
    """This is a typeclass definition to convert Result container to str."""

@result_to_str.instance(Result.success_type)
def _result_to_str_success(instance: Result) -> str:
    return str(instance.unwrap())  # will always receive `Success` types

@result_to_str.instance(Result.failure_type)
def _result_to_str_failure(instance: Result) -> str:
    return str(instance.failure())  # will always receive `Failure` types

if __name__ == '__main__':
    result_to_str(Success('test'))
    result_to_str(Failure('test'))

mypy output:

ex.py:10: error: Instance "returns.result.Result[Any, Any]" does not match inferred type "Type[returns.result._Success[Any]]"
ex.py:16: error: Instance "returns.result.Result[Any, Any]" does not match inferred type "Type[returns.result._Failure[Any]]"
ex.py:23: error: Argument 1 to "result_to_str" has incompatible type "Result[str, Any]"; expected <nothing>
ex.py:24: error: Argument 1 to "result_to_str" has incompatible type "Result[Any, str]"; expected <nothing>
Found 4 errors in 1 file (checked 1 source file)

PS.: I'm using the returns plugin too

thepabloaguilar avatar Oct 03 '21 03:10 thepabloaguilar

The same thing for Maybe 😢

from classes import typeclass
from returns.maybe import Maybe, Some, Nothing

@typeclass
def maybe_to_str(instance) -> str:
    """This is a typeclass definition to convert Maybe container to str."""

@maybe_to_str.instance(Maybe.success_type)
def _maybe_to_str(instance: Maybe) -> str:
    return str(instance.unwrap())  # will always receive `Maybe` types

@maybe_to_str.instance(Maybe.failure_type)
def _nothing_to_str(instance: Maybe) -> str:
    return str(instance)  # will always receive `Nothing`

if __name__ == '__main__':
    maybe_to_str(Some('test'))
    maybe_to_str(Nothing)

mypy output:

ex.py:10: error: Instance "returns.maybe.Maybe[Any]" does not match inferred type "Type[returns.maybe._Some[Any]]"
ex.py:15: error: Instance "returns.maybe.Maybe[Any]" does not match inferred type "Type[returns.maybe._Nothing]"
ex.py:21: error: Argument 1 to "maybe_to_str" has incompatible type "Maybe[str]"; expected <nothing>
ex.py:22: error: Argument 1 to "maybe_to_str" has incompatible type "Maybe[NoReturn]"; expected <nothing>
Found 4 errors in 1 file (checked 1 source file)

thepabloaguilar avatar Oct 03 '21 03:10 thepabloaguilar

@thepabloaguilar Will you have the time to debug why this happens?

sobolevn avatar Oct 03 '21 06:10 sobolevn

I can try, it's a problem with classes mypy plugin

thepabloaguilar avatar Oct 03 '21 06:10 thepabloaguilar

How do you develop mypy plugin locally? I want to put some breakpoints 😄

thepabloaguilar avatar Oct 04 '21 02:10 thepabloaguilar

Try --pdb option for mypy. I don't use debuggers, sorry.

sobolevn avatar Oct 04 '21 07:10 sobolevn