Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python 3.13で進化したtype predicateについてと、タグ付きユニオンを使っ...

Avatar for nsuz nsuz
December 22, 2024

Python 3.13で進化したtype predicateについてと、タグ付きユニオンを使ったtype narrowingについて

Avatar for nsuz

nsuz

December 22, 2024
Tweet

More Decks by nsuz

Other Decks in Programming

Transcript

  1. a: list[str | None] = ["foo", None, "bar", None, "baz"]

    b = filter(lambda x: x is not None, a) c = map(lambda x: x.upper(), b)
  2. type predicete function def is_not_none[T](x: T | None) -> TypeIs[T]:

    return x is not None typing.TypeIs Python 3.13で追加された。TypeGuard(3.10~)の進化版。
  3. class Ok[T](TypedDict): type: Literal["ok"] value: T class Error(TypedDict): type: Literal["error"]

    value: Exception type Result[T] = Ok[T] | Error def unwrap[T](result: Result[T]) -> T: if result["type"] == "ok": return result["value"] # result: Ok[T] else: raise result["value"] # result: Error
  4. data: list[Result[int]] = [ {"type": "ok", "value": 42}, {"type": "error",

    "value": ValueError("Something went wrong")}, ] for d in data: try: print(unwrap(d)) except Exception as e: print(f"Error!!!! {e}")
  5. from typing import Literal, TypedDict type Data = list[str] class

    OkResponse(TypedDict): result: Literal[0] data: Data class ErrorResponse(TypedDict): result: Literal[1] error: str type Response = OkResponse | ErrorResponse def unwrap[T](res: Response) -> Data: if res["result"] == 0: return res["data"] else: raise Exception(res["error"]) data: list[Response] = [ {"result": 0, "data": ["foo", "bar", "baz"]}, {"result": 1, "error": "ERROR_CODE_123"}, ] for d in data: try: print(unwrap(d)) except Exception as e: print(f"Error!!!! {e}")
  6. from dataclasses import dataclass @dataclass class Ok[T]: value: T @dataclass

    class Error: value: Exception type Result[T] = Ok[T] | Error def unwrap[T](result: Result[T]) -> T: match result: case Ok(v): return v case Error(e): raise e
  7. data: list[Result[int]] = [ Ok(42), Error(ValueError("Something went wrong")), ] for

    d in data: try: print(unwrap(d)) except Exception as e: print(f"Error!!!! {e}")