From 515f440ee6f77c3fa1c53e4c21fb7159e6c006ef Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Sat, 27 Jun 2020 16:49:05 -0300 Subject: [PATCH 01/11] Adds missing return type hint to the `collect_traces` function --- returns/primitives/tracing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/returns/primitives/tracing.py b/returns/primitives/tracing.py index 4ae98c6ed..fc324b7fe 100644 --- a/returns/primitives/tracing.py +++ b/returns/primitives/tracing.py @@ -1,13 +1,13 @@ import types from contextlib import contextmanager from inspect import FrameInfo, stack -from typing import List, Optional +from typing import Iterator, List, Optional from returns.result import _Failure @contextmanager -def collect_traces(): +def collect_traces() -> Iterator[None]: """ Context Manager/Decorator to active traces collect to the Failures. From 5f88a48ee9acc8326c3587dde58b2cfd8ae831d9 Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Sat, 27 Jun 2020 17:08:50 -0300 Subject: [PATCH 02/11] Creates type safety tests to `collect_traces` function --- .../test_tracing/test_collect_traces.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 typesafety/test_primitives/test_tracing/test_collect_traces.yml diff --git a/typesafety/test_primitives/test_tracing/test_collect_traces.yml b/typesafety/test_primitives/test_tracing/test_collect_traces.yml new file mode 100644 index 000000000..28f7343a7 --- /dev/null +++ b/typesafety/test_primitives/test_tracing/test_collect_traces.yml @@ -0,0 +1,13 @@ +- case: collect_traces_context_manager_return_type_hint + disable_cache: true + main: | + from returns.primitives.tracing import collect_traces + + reveal_type(collect_traces) # N: Revealed type is 'def () -> contextlib._GeneratorContextManager[None]' + +- case: collect_traces_context_manager_return_type + disable_cache: true + main: | + from returns.primitives.tracing import collect_traces + + reveal_type(collect_traces()) # N: Revealed type is 'contextlib._GeneratorContextManager[None]' From 05c1bcb2c567cbcfb66f921067588c14fd899d87 Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Mon, 29 Jun 2020 00:42:37 -0300 Subject: [PATCH 03/11] Removes `@contextmanager` decorator from `collect_traces` function Now we pass `collect_traces` directly to `contextmanager` function at end of file to avoid return type problems. --- returns/primitives/tracing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/returns/primitives/tracing.py b/returns/primitives/tracing.py index fc324b7fe..bcad787bd 100644 --- a/returns/primitives/tracing.py +++ b/returns/primitives/tracing.py @@ -6,7 +6,6 @@ from returns.result import _Failure -@contextmanager def collect_traces() -> Iterator[None]: """ Context Manager/Decorator to active traces collect to the Failures. @@ -65,3 +64,6 @@ class on Monkey Patching promoted by """ current_stack = stack() return current_stack[2:] + + +collect_traces = contextmanager(collect_traces) # type: ignore From 275c0a1563532a8326ed7f38b537a64692088be8 Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Mon, 29 Jun 2020 00:43:36 -0300 Subject: [PATCH 04/11] Fixes type safety tests for `collect_traces` function --- .../test_primitives/test_tracing/test_collect_traces.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typesafety/test_primitives/test_tracing/test_collect_traces.yml b/typesafety/test_primitives/test_tracing/test_collect_traces.yml index 28f7343a7..c52158c17 100644 --- a/typesafety/test_primitives/test_tracing/test_collect_traces.yml +++ b/typesafety/test_primitives/test_tracing/test_collect_traces.yml @@ -3,11 +3,11 @@ main: | from returns.primitives.tracing import collect_traces - reveal_type(collect_traces) # N: Revealed type is 'def () -> contextlib._GeneratorContextManager[None]' + reveal_type(collect_traces) # N: Revealed type is 'def () -> typing.Iterator[None]' - case: collect_traces_context_manager_return_type disable_cache: true main: | from returns.primitives.tracing import collect_traces - reveal_type(collect_traces()) # N: Revealed type is 'contextlib._GeneratorContextManager[None]' + reveal_type(collect_traces()) # N: Revealed type is 'typing.Iterator[None]' From cf68d80bfe41300fe4fa080f90b78b4406103d4e Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Mon, 29 Jun 2020 00:48:31 -0300 Subject: [PATCH 05/11] Adds `noqa: WPS501` flag in `try` block on `collect_traces` function --- returns/primitives/tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/returns/primitives/tracing.py b/returns/primitives/tracing.py index bcad787bd..ab46bcd21 100644 --- a/returns/primitives/tracing.py +++ b/returns/primitives/tracing.py @@ -38,7 +38,7 @@ def collect_traces() -> Iterator[None]: unpatched_get_trace = getattr(_Failure, '_get_trace') # noqa: B009 substitute_get_trace = types.MethodType(_get_trace, _Failure) setattr(_Failure, '_get_trace', substitute_get_trace) # noqa: B010 - try: + try: # noqa: WPS501 yield finally: setattr(_Failure, '_get_trace', unpatched_get_trace) # noqa: B010 From 7e50f7b659d4991ed4ea0e2e14e7745597c276a2 Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Tue, 30 Jun 2020 02:55:54 -0300 Subject: [PATCH 06/11] Modifies `tracing.py` To fix type hint errors we separate all the possible `collect_traces` function signatures using `@overload` decorator The implementation of `collect_traces`, now, acts like a factory! --- returns/primitives/tracing.py | 47 ++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/returns/primitives/tracing.py b/returns/primitives/tracing.py index ab46bcd21..cc50deccb 100644 --- a/returns/primitives/tracing.py +++ b/returns/primitives/tracing.py @@ -1,12 +1,35 @@ import types from contextlib import contextmanager from inspect import FrameInfo, stack -from typing import Iterator, List, Optional +from typing import ( + Callable, + ContextManager, + Iterator, + List, + Optional, + TypeVar, + Union, + overload, +) from returns.result import _Failure +Function = TypeVar('Function', bound=Callable) -def collect_traces() -> Iterator[None]: + +@overload +def collect_traces() -> ContextManager[None]: + """Context Manager to active traces collect to the Failures.""" + + +@overload +def collect_traces(function: Function) -> Function: + """Decorator to active traces collect to the Failures.""" + + +def collect_traces( + function: Optional[Function] = None, +) -> Union[Function, ContextManager[None]]: # noqa: DAR101, DAR201, DAR301 """ Context Manager/Decorator to active traces collect to the Failures. @@ -35,13 +58,16 @@ def collect_traces() -> Iterator[None]: # doctest: # noqa: DAR301, E501 """ - unpatched_get_trace = getattr(_Failure, '_get_trace') # noqa: B009 - substitute_get_trace = types.MethodType(_get_trace, _Failure) - setattr(_Failure, '_get_trace', substitute_get_trace) # noqa: B010 - try: # noqa: WPS501 - yield - finally: - setattr(_Failure, '_get_trace', unpatched_get_trace) # noqa: B010 + def factory() -> Iterator[None]: + unpatched_get_trace = getattr(_Failure, '_get_trace') # noqa: B009 + substitute_get_trace = types.MethodType(_get_trace, _Failure) + setattr(_Failure, '_get_trace', substitute_get_trace) # noqa: B010 + try: # noqa: WPS501 + yield + finally: + setattr(_Failure, '_get_trace', unpatched_get_trace) # noqa: B010 + collect_traces_cm = contextmanager(factory)() + return collect_traces_cm(function) if function else collect_traces_cm def _get_trace(_self: _Failure) -> Optional[List[FrameInfo]]: @@ -64,6 +90,3 @@ class on Monkey Patching promoted by """ current_stack = stack() return current_stack[2:] - - -collect_traces = contextmanager(collect_traces) # type: ignore From c39150a3a7723108d36b5faa2b0a69b46710909c Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Tue, 30 Jun 2020 02:56:15 -0300 Subject: [PATCH 07/11] Updates safety tests of `collect_traces` function --- .../test_tracing/test_collect_traces.yml | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/typesafety/test_primitives/test_tracing/test_collect_traces.yml b/typesafety/test_primitives/test_tracing/test_collect_traces.yml index c52158c17..23460b0b3 100644 --- a/typesafety/test_primitives/test_tracing/test_collect_traces.yml +++ b/typesafety/test_primitives/test_tracing/test_collect_traces.yml @@ -1,13 +1,35 @@ -- case: collect_traces_context_manager_return_type_hint +- case: collect_traces_context_manager_return_type_one disable_cache: true main: | from returns.primitives.tracing import collect_traces - reveal_type(collect_traces) # N: Revealed type is 'def () -> typing.Iterator[None]' + reveal_type(collect_traces) # N: Revealed type is 'Overload(def () -> typing.ContextManager[None], def [Function <: def (*Any, **Any) -> Any] (function: Function`-1) -> Function`-1)' -- case: collect_traces_context_manager_return_type +- case: collect_traces_context_manager_return_type_two disable_cache: true main: | from returns.primitives.tracing import collect_traces - reveal_type(collect_traces()) # N: Revealed type is 'typing.Iterator[None]' + reveal_type(collect_traces()) # N: Revealed type is 'typing.ContextManager[None]' + +- case: collect_traces_decorated_function_return_type + disable_cache: true + main: | + from returns.primitives.tracing import collect_traces + + @collect_traces + def function() -> int: + return 0 + + reveal_type(function) # N: Revealed type is 'def () -> builtins.int' + +- case: collect_traces_decorated_function_with_argument_return_type + disable_cache: true + main: | + from returns.primitives.tracing import collect_traces + + @collect_traces + def function(number: int) -> str: + return str(number) + + reveal_type(function) # N: Revealed type is 'def (number: builtins.int) -> builtins.str' From 329475da329d94c8c195d37bc6b20ca247d81d4f Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Tue, 30 Jun 2020 02:56:27 -0300 Subject: [PATCH 08/11] Updates documentation of `collect_traces` function --- docs/pages/development.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/development.rst b/docs/pages/development.rst index 82e7d1d27..0733c9adc 100644 --- a/docs/pages/development.rst +++ b/docs/pages/development.rst @@ -54,7 +54,7 @@ Or as a decorator: >>> from returns.result import Failure, Result >>> from returns.primitives.tracing import collect_traces - >>> @collect_traces() + >>> @collect_traces ... def traced_function(value: str) -> IOResult[str, str]: ... return IOFailure(value) From 8c274c9185f31efeee777cdf8b516110ee71be17 Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Wed, 1 Jul 2020 00:15:19 -0300 Subject: [PATCH 09/11] Changes type var name from `Function` to `_FunctionType` --- returns/primitives/tracing.py | 8 ++++---- .../test_primitives/test_tracing/test_collect_traces.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/returns/primitives/tracing.py b/returns/primitives/tracing.py index cc50deccb..6086cbc2b 100644 --- a/returns/primitives/tracing.py +++ b/returns/primitives/tracing.py @@ -14,7 +14,7 @@ from returns.result import _Failure -Function = TypeVar('Function', bound=Callable) +_FunctionType = TypeVar('_FunctionType', bound=Callable) @overload @@ -23,13 +23,13 @@ def collect_traces() -> ContextManager[None]: @overload -def collect_traces(function: Function) -> Function: +def collect_traces(function: _FunctionType) -> _FunctionType: """Decorator to active traces collect to the Failures.""" def collect_traces( - function: Optional[Function] = None, -) -> Union[Function, ContextManager[None]]: # noqa: DAR101, DAR201, DAR301 + function: Optional[_FunctionType] = None, +) -> Union[_FunctionType, ContextManager[None]]: # noqa: DAR101, DAR201, DAR301 """ Context Manager/Decorator to active traces collect to the Failures. diff --git a/typesafety/test_primitives/test_tracing/test_collect_traces.yml b/typesafety/test_primitives/test_tracing/test_collect_traces.yml index 23460b0b3..e6637929e 100644 --- a/typesafety/test_primitives/test_tracing/test_collect_traces.yml +++ b/typesafety/test_primitives/test_tracing/test_collect_traces.yml @@ -3,7 +3,7 @@ main: | from returns.primitives.tracing import collect_traces - reveal_type(collect_traces) # N: Revealed type is 'Overload(def () -> typing.ContextManager[None], def [Function <: def (*Any, **Any) -> Any] (function: Function`-1) -> Function`-1)' + reveal_type(collect_traces) # N: Revealed type is 'Overload(def () -> typing.ContextManager[None], def [_FunctionType <: def (*Any, **Any) -> Any] (function: _FunctionType`-1) -> _FunctionType`-1)' - case: collect_traces_context_manager_return_type_two disable_cache: true From 7f8736ee6780a87b52bf850d30aac94cce1406ee Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Wed, 1 Jul 2020 00:40:37 -0300 Subject: [PATCH 10/11] Changes `factory` function to use the `@contextmanager` decorator instead of passing `factory` through the `contextmanager` function --- returns/primitives/tracing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/returns/primitives/tracing.py b/returns/primitives/tracing.py index 6086cbc2b..42e7f2838 100644 --- a/returns/primitives/tracing.py +++ b/returns/primitives/tracing.py @@ -58,6 +58,7 @@ def collect_traces( # doctest: # noqa: DAR301, E501 """ + @contextmanager def factory() -> Iterator[None]: unpatched_get_trace = getattr(_Failure, '_get_trace') # noqa: B009 substitute_get_trace = types.MethodType(_get_trace, _Failure) @@ -66,8 +67,7 @@ def factory() -> Iterator[None]: yield finally: setattr(_Failure, '_get_trace', unpatched_get_trace) # noqa: B010 - collect_traces_cm = contextmanager(factory)() - return collect_traces_cm(function) if function else collect_traces_cm + return factory()(function) if function else factory() def _get_trace(_self: _Failure) -> Optional[List[FrameInfo]]: From 95db932a483a320d46b76d58d5a7cbd8fa390782 Mon Sep 17 00:00:00 2001 From: Pablo Aguilar Date: Wed, 1 Jul 2020 00:42:46 -0300 Subject: [PATCH 11/11] Updates safety tests of `collect_traces` function, specifically the `collect_traces_context_manager_return_type_two` case --- .../test_primitives/test_tracing/test_collect_traces.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/typesafety/test_primitives/test_tracing/test_collect_traces.yml b/typesafety/test_primitives/test_tracing/test_collect_traces.yml index e6637929e..e6dee6a5a 100644 --- a/typesafety/test_primitives/test_tracing/test_collect_traces.yml +++ b/typesafety/test_primitives/test_tracing/test_collect_traces.yml @@ -10,7 +10,8 @@ main: | from returns.primitives.tracing import collect_traces - reveal_type(collect_traces()) # N: Revealed type is 'typing.ContextManager[None]' + with reveal_type(collect_traces()): # N: Revealed type is 'typing.ContextManager[None]' + pass - case: collect_traces_decorated_function_return_type disable_cache: true