Pyre Extensions
Pyre Extensions is a Python library offering type system extensions designed specifically for use with the Pyre type checker. Currently at version 0.0.32 and classified as 'Alpha' development status, it provides advanced typing constructs like `ParameterSpecification`, `none_throws`, and a type-safe `safe_json` module. Its release cadence is closely tied to the development and releases of the main Pyre type checker.
Warnings
- gotcha The library is in 'Development Status :: 3 - Alpha'. This means the API may not be stable, and breaking changes might occur in future versions.
- gotcha The `ParameterSpecification` type variable's `args` and `kwargs` properties can only be used together in a function definition as `*args` and `**kwargs` with no other parameters listed.
- gotcha The `none_throws` function explicitly raises an `AssertionError` if `None` is passed to it. This might be unexpected if other exception types (e.g., `ValueError` or `TypeError`) are anticipated for null checks.
- breaking The `safe_json` module is a type-safe replacement for the built-in `json` module. Unlike the standard `json` module, `safe_json` will raise an exception if the input JSON does not strictly match the expected type, which can break existing code expecting more lenient parsing.
Install
-
pip install pyre-extensions
Imports
- ParameterSpecification
from pyre_extensions import ParameterSpecification
- none_throws
from pyre_extensions import none_throws
- safe_json
from pyre_extensions import safe_json
Quickstart
from typing import TypeVar, Callable, List
from pyre_extensions import ParameterSpecification, none_throws
TParams = ParameterSpecification("TParams")
TReturn = TypeVar("TReturn")
def unwrap(f: Callable[TParams, List[TReturn]]) -> Callable[TParams, TReturn]:
"""Example of a decorator using ParameterSpecification."""
def inner(*args: TParams.args, **kwargs: TParams.kwargs) -> TReturn:
result = f(*args, **kwargs)
# Using none_throws for explicit Optional handling
first_item = none_throws(result[0]) if result else None
if first_item is None:
raise ValueError("List must not be empty for unwrap to extract an item")
return first_item
return inner
@unwrap
def get_first_char_list(s: str, upper: bool = False) -> List[str]:
chars = [c.upper() for c in s] if upper else list(s)
return chars
@unwrap
def get_empty_list(x: int) -> List[int]:
return []
# Example usage
print(f"First char (upper): {get_first_char_list('hello', upper=True)}")
print(f"First char (lower): {get_first_char_list('world')}")
try:
get_empty_list(123)
except ValueError as e:
print(f"Caught expected error for empty list: {e}")