Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions returns/context/requires_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@
_FirstType = TypeVar('_FirstType')

# Type Aliases:
#: Sometimes ``RequiresContext`` and other similar types might be used with

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, conver this to comments

#: no explicit dependencies so we need to have this type alias for Any.
NoDeps = Any
"""
Sometimes ``RequiresContext`` and other similar types
might be used with no explicit dependencies so we need to
have this type alias for Any.
"""


@final
Expand Down Expand Up @@ -78,11 +81,13 @@ class RequiresContext( # type: ignore[type-var]

__slots__ = ()

#: This field has an extra 'RequiresContext' just because `mypy` needs it.
_inner_value: Callable[[_EnvType_contra], _ReturnType_co]
"""
This field has an extra 'RequiresContext'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, open a new issue in WPS: we must enforce the same style of docs that we use for docstrings. One line, . in the end.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the clarification! So you mean the formatting style itself. Currently I have:

"""
This field has an extra 'RequiresContext'
just because `mypy` needs it."""

But you want it to follow the docstring convention?

"""This field has an extra 'RequiresContext' just because `mypy` needs it."""

I understand the concern about the 80-character line limit. How should we handle longer docstrings that exceed this limit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same style of docs that we use for docstrings

What is the rule (WPS code)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a ruff rule:

D415 First line should end with a period, question mark, or exclamation point
 --> ex.py:2:5
  |
1 | def some():
2 |     """Ss"""
  |     ^^^^^^^^
help: Add closing punctuation

and

D205 1 blank line required between summary line and description
 --> ex.py:2:5
  |
1 |   def some():
2 | /     """First line
3 | |     second line
4 | |     """
  | |_______^
help: Insert single blank line

D415 First line should end with a period, question mark, or exclamation point
 --> ex.py:2:5
  |
1 |   def some():
2 | /     """First line
3 | |     second line
4 | |     """
  | |_______^
help: Add closing punctuation

But, these rules are not enforced for attr-level docs. This should be proposed and fixed in ruff :)

just because `mypy` needs it."""

#: A convenient placeholder to call methods created by `.from_value()`:
no_args: ClassVar[NoDeps] = object()
"""A convenient placeholder to call methods created by `.from_value()`."""

def __init__(
self,
Expand Down Expand Up @@ -208,8 +213,8 @@ def bind(
"""
return RequiresContext(lambda deps: dekind(function(self(deps)))(deps))

#: Alias for `bind_context` method, it is the same as `bind` here.
bind_context = bind
"""Alias for `bind_context` method, it is the same as `bind` here."""

def modify_env(
self,
Expand Down Expand Up @@ -445,5 +450,5 @@ def from_requires_context_future_result(

# Aliases

#: Sometimes `RequiresContext` is too long to type.
Reader: TypeAlias = RequiresContext
"""Sometimes `RequiresContext` is too long to type."""
22 changes: 11 additions & 11 deletions returns/context/requires_context_future_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ class RequiresContextFutureResult( # type: ignore[type-var]

__slots__ = ()

#: Inner value of `RequiresContext`
#: is just a function that returns `FutureResult`.
#: This field has an extra 'RequiresContext' just because `mypy` needs it.
_inner_value: Callable[
[_EnvType_contra], FutureResult[_ValueType_co, _ErrorType_co]
]
"""Inner value of `RequiresContext` is just a function
that returns `FutureResult`. This field has an extra
'RequiresContext' just because `mypy` needs it."""

#: A convenient placeholder to call methods created by `.from_value()`.
no_args: ClassVar[NoDeps] = object()
"""A convenient placeholder to call methods created by `.from_value()`."""

def __init__(
self,
Expand Down Expand Up @@ -319,9 +319,9 @@ def bind(
),
)

#: Alias for `bind_context_future_result` method,
#: it is the same as `bind` here.
bind_context_future_result = bind
"""Alias for `bind_context_future_result` method,
it is the same as `bind` here."""

def bind_async(
self,
Expand Down Expand Up @@ -377,9 +377,9 @@ def bind_async(
),
)

#: Alias for `bind_async_context_future_result` method,
#: it is the same as `bind_async` here.
bind_async_context_future_result = bind_async
"""Alias for `bind_async_context_future_result` method,
it is the same as `bind_async` here."""

def bind_awaitable(
self,
Expand Down Expand Up @@ -1460,19 +1460,19 @@ def from_failure(

# Aliases:

#: Alias for a popular case when ``Result`` has ``Exception`` as error type.
RequiresContextFutureResultE: TypeAlias = RequiresContextFutureResult[
_ValueType_co,
Exception,
_EnvType_contra,
]
"""Alias for a popular case when ``Result`` has ``Exception`` as error type."""

#: Sometimes `RequiresContextFutureResult` is too long to type.
ReaderFutureResult: TypeAlias = RequiresContextFutureResult
"""Sometimes `RequiresContextFutureResult` is too long to type."""

#: Alias to save you some typing. Uses ``Exception`` as error type.
ReaderFutureResultE: TypeAlias = RequiresContextFutureResult[
_ValueType_co,
Exception,
_EnvType_contra,
]
"""Alias to save you some typing. Uses ``Exception`` as error type."""
17 changes: 9 additions & 8 deletions returns/context/requires_context_ioresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ class RequiresContextIOResult( # type: ignore[type-var]

__slots__ = ()

#: Inner value of `RequiresContext`
#: is just a function that returns `IOResult`.
#: This field has an extra 'RequiresContext' just because `mypy` needs it.
_inner_value: Callable[
[_EnvType_contra], IOResult[_ValueType_co, _ErrorType]
]
"""Inner value of `RequiresContext`. Is just a function that
returns `IOResult`. This field has an extra 'RequiresContext'
just because `mypy` needs it."""

#: A convenient placeholder to call methods created by `.from_value()`.
no_args: ClassVar[NoDeps] = object()
"""A convenient placeholder to call methods created by `.from_value()`."""

def __init__(
self,
Expand Down Expand Up @@ -296,8 +296,9 @@ def bind(
),
)

#: Alias for `bind_context_ioresult` method, it is the same as `bind` here.
bind_context_ioresult = bind
"""Alias for `bind_context_ioresult` method,
it is the same as `bind` here."""

def bind_result(
self,
Expand Down Expand Up @@ -915,19 +916,19 @@ def from_failure(

# Aliases:

#: Alias for a popular case when ``Result`` has ``Exception`` as error type.
RequiresContextIOResultE: TypeAlias = RequiresContextIOResult[
_ValueType_co,
Exception,
_EnvType_contra,
]
"""Alias for a popular case when ``Result`` has ``Exception`` as error type."""

#: Alias to save you some typing. Uses original name from Haskell.
ReaderIOResult: TypeAlias = RequiresContextIOResult
"""Alias to save you some typing. Uses original name from Haskell."""

#: Alias to save you some typing. Uses ``Exception`` as error type.
ReaderIOResultE: TypeAlias = RequiresContextIOResult[
_ValueType_co,
Exception,
_EnvType_contra,
]
"""Alias to save you some typing. Uses ``Exception`` as error type."""
13 changes: 7 additions & 6 deletions returns/context/requires_context_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,14 @@ class RequiresContextResult( # type: ignore[type-var]

__slots__ = ()

#: This field has an extra 'RequiresContext' just because `mypy` needs it.
_inner_value: Callable[
[_EnvType_contra], Result[_ValueType_co, _ErrorType_co]
]
"""This field has an extra 'RequiresContext',
just because `mypy` needs it."""

#: A convenient placeholder to call methods created by `.from_value()`.
no_args: ClassVar[NoDeps] = object()
"""A convenient placeholder to call methods created by `.from_value()`."""

def __init__(
self,
Expand Down Expand Up @@ -282,8 +283,8 @@ def bind(
),
)

#: Alias for `bind_context_result` method, it is the same as `bind` here.
bind_context_result = bind
"""Alias for `bind_context_result` method, it is the same as `bind` here."""

def bind_result(
self,
Expand Down Expand Up @@ -631,19 +632,19 @@ def from_failure(

# Aliases:

#: Alias for a popular case when ``Result`` has ``Exception`` as error type.
RequiresContextResultE: TypeAlias = RequiresContextResult[
_ValueType_co,
Exception,
_EnvType_contra,
]
"""Alias for a popular case when ``Result`` has ``Exception`` as error type."""

#: Alias to save you some typing. Uses original name from Haskell.
ReaderResult: TypeAlias = RequiresContextResult
"""Alias to save you some typing. Uses original name from Haskell."""

#: Alias to save you some typing. Has ``Exception`` as error type.
ReaderResultE: TypeAlias = RequiresContextResult[
_ValueType_co,
Exception,
_EnvType_contra,
]
"""Alias to save you some typing. Has ``Exception`` as error type."""
4 changes: 2 additions & 2 deletions returns/contrib/hypothesis/_entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ def decorator(thing: Any) -> st.SearchStrategy[_Inst]:

return decorator

#: Our types that we register in hypothesis
#: to be working with ``st.from_type``
registered_types: Sequence[type[Lawful]] = (
Result,
Maybe,
Expand All @@ -59,6 +57,8 @@ def decorator(thing: Any) -> st.SearchStrategy[_Inst]:
RequiresContextIOResult,
RequiresContextFutureResult,
)
"""Our types that we register in hypothesis to be
working with ``st.from_type``.""" # noqa: WPS484

for type_ in registered_types:
st.register_type_strategy(type_, factory(type_))
24 changes: 13 additions & 11 deletions returns/contrib/hypothesis/laws.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,23 @@ class Settings:
:func:`default_settings`.
"""

#: Settings directly passed on to `hypothesis`. We support all kwargs from
#: ``@settings``, see `@settings docs
#: <https://hypothesis.readthedocs.io/en/latest/settings.html>`_.
settings_kwargs: dict[str, Any]
#: Whether to create examples using ``__init__`` instead of the default .
"""Settings directly passed on to `hypothesis`. We support all kwargs from
``@settings``, see `@settings docs <https://hypothesis.readthedocs.io/en/latest/settings.html>`_."""

use_init: bool
#: Strategy for generating the container. By default, we generate examples
#: of a container using:
#: :func:`returns.contrib.hypothesis.containers.strategy_from_container`.
"""Whether to create examples using ``__init__`` instead of the default ."""

container_strategy: StrategyFactory | None
#: Strategies for generating values of types other than the container and
#: its lawful interfaces. This can be useful for overriding ``TypeVar``,
#: ``Callable``, etc. in case you use certain types that ``hypothesis`` is
#: unable to find.
"""Strategy for generating the container. By default, we generate examples
of a container using:
:func:`returns.contrib.hypothesis.containers.strategy_from_container`."""

type_strategies: dict[type[object], StrategyFactory]
"""Strategies for generating values of types other than the container and
its lawful interfaces. This can be useful for overriding ``TypeVar``,
``Callable``, etc. in case you use certain types that ``hypothesis`` is
unable to find."""

def __post_init__(self) -> None:
"""Check that the settings are mutually compatible."""
Expand Down
12 changes: 6 additions & 6 deletions returns/contrib/mypy/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,26 @@
# Constant fullnames for typechecking
# ===================================

#: Used for typed ``partial`` function.
TYPED_PARTIAL_FUNCTION: Final = 'returns.curry.partial'
"""Used for typed ``partial`` function."""

#: Used for typed ``curry`` decorator.
TYPED_CURRY_FUNCTION: Final = 'returns.curry.curry'
"""Used for typed ``curry`` decorator."""

#: Used for typed ``flow`` call.
TYPED_FLOW_FUNCTION: Final = 'returns._internal.pipeline.flow.flow'
"""Used for typed ``flow`` call."""

#: Used for typed ``pipe`` call.
TYPED_PIPE_FUNCTION: Final = 'returns._internal.pipeline.pipe.pipe'
TYPED_PIPE_METHOD: Final = 'returns._internal.pipeline.pipe._Pipe.__call__'
"""Used for typed ``pipe`` call."""

#: Used for HKT emulation.
TYPED_KINDN: Final = 'returns.primitives.hkt.KindN'
TYPED_KINDN_ACCESS: Final = f'{TYPED_KINDN}.'
TYPED_KIND_DEKIND: Final = 'returns.primitives.hkt.dekind'
TYPED_KIND_KINDED_CALL: Final = 'returns.primitives.hkt.Kinded.__call__'
TYPED_KIND_KINDED_GET: Final = 'returns.primitives.hkt.Kinded.__get__'
"""Used for HKT emulation."""

#: Used for :ref:`do-notation`.
DO_NOTATION_METHODS: Final = (
# Just validation:
'returns.io.IO.do',
Expand All @@ -34,3 +33,4 @@
'returns.io.IOResult.do',
'returns.future.FutureResult.do',
)
"""Used for :ref:`do-notation`."""
2 changes: 1 addition & 1 deletion returns/contrib/mypy/_features/curry.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
proper_type,
)

#: Raw material to build `_ArgTree`.
_RawArgTree = list[list[list[FuncArg]]]
"""Raw material to build `_ArgTree`."""


def analyze(ctx: FunctionContext) -> MypyType:
Expand Down
2 changes: 1 addition & 1 deletion returns/contrib/mypy/_structures/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

from mypy.plugin import FunctionContext, MethodContext

#: We treat them equally when working with functions or methods.
CallableContext: TypeAlias = FunctionContext | MethodContext
"""We treat them equally when working with functions or methods."""
2 changes: 1 addition & 1 deletion returns/contrib/mypy/_typeops/analtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
from returns.contrib.mypy._structures.args import FuncArg
from returns.contrib.mypy._structures.types import CallableContext

#: Mapping for better `call || function` argument compatibility.
_KIND_MAPPING: Final = MappingProxyType({
# We have to replace `ARG_OPT` to `ARG_NAMED`,
# because `ARG_OPT` is only used in function defs, not calls.
# And `ARG_NAMED` is the same thing for calls.
ARG_OPT: ARG_NAMED,
})
"""Mapping for better `call || function` argument compatibility."""


@overload
Expand Down
2 changes: 1 addition & 1 deletion returns/contrib/mypy/_typeops/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
from returns.contrib.mypy._structures.types import CallableContext
from returns.contrib.mypy._typeops.analtype import analyze_call

#: Mapping of `typevar` to real type.
_Constraints: TypeAlias = Mapping[TypeVarId, MypyType]
"""Mapping of `typevar` to real type."""


@final
Expand Down
10 changes: 5 additions & 5 deletions returns/contrib/mypy/_typeops/transform_callable.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@

from returns.contrib.mypy._structures.args import FuncArg

#: Kinds of arguments that consume the leftover positional or keyword
#: arguments (``*args`` and ``**kwargs``) and therefore cannot be applied.
_VARIADIC_KINDS: Final = frozenset((ARG_STAR, ARG_STAR2))
"""Kinds of arguments that consume the leftover positional or keyword
arguments (``*args`` and ``**kwargs``) and therefore cannot be applied."""

#: Kinds of arguments that can be passed positionally.
_POSITIONAL_KINDS: Final = frozenset((ARG_POS, ARG_OPT))
"""Kinds of arguments that can be passed positionally."""

#: Maps a positional argument kind onto its keyword-only counterpart.
_KEYWORD_ONLY_KINDS: Final = MappingProxyType({
ARG_POS: ARG_NAMED,
ARG_OPT: ARG_NAMED_OPT,
})
"""Maps a positional argument kind onto its keyword-only counterpart."""


def proper_type(
Expand All @@ -55,12 +55,12 @@ class Intermediate:
was already provided in caller.
"""

#: Positional arguments can be of this kind.
_positional_kinds: ClassVar[frozenset[ArgKind]] = frozenset((
ARG_POS,
ARG_OPT,
ARG_STAR,
))
"""Positional arguments can be of this kind."""

def __init__(self, case_function: CallableType) -> None:
"""We only need a callable to work on."""
Expand Down
Loading
Loading