dbrattli / Expression

Pragmatic functional programming for Python inspired by F#
https://expression.readthedocs.io
MIT License
421 stars 30 forks source link

fix: typed "yield from" in pylance (issue #14) #108

Closed phi-friday closed 1 year ago

phi-friday commented 1 year ago

14 Explore better typing for comprehensions / computational expressions

# expression.core.result.Result
# replace return type
Iterator[_TSource] -> Generator[_TSource, _TSource, _TSource]

# expression.core.option.Option
# add abstractmethod
@abstractmethod
def __iter__(self) -> Generator[_TSource, _TSource, _TSource]:
    raise NotImplementedError

then pylance can analysis Result, Option

# before
from typing import Any, Generator

from expression import Option, Some, effect

def get_result(x: int, y: str) -> Option[list[str]]:
    return Some([y, str(x)])

@effect.option[list[str]]()
def fn() -> Generator[Any, Any, list[str]]:
    x = yield 42  # in pylance:: (variable) x: Any
    y = yield f"{x} as a string"  # in pylance:: (variable) x: Any
    z = yield from get_result(x, y)  # in pylance:: (variable) z: Unknown

    return z

fn  # in pylance:: (function) fn() -> Option[list[str]]

# after
from typing import Any, Generator

from expression import Option, Some, effect

def get_result(x: int, y: str) -> Option[list[str]]:
    return Some([y, str(x)])

@effect.option[list[str]]()
def fn() -> Generator[Any, Any, list[str]]:
    x = yield 42  # in pylance:: (variable) x: Any
    y = yield f"{x} as a string"  # in pylance:: (variable) x: Any
    z = yield from get_result(x, y)  # in pylance:: (variable) z: list[str]

    return z

fn  # in pylance:: (function) fn() -> Option[list[str]]