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

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

nsuz
December 22, 2024

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

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}")