Skip to content

Instantly share code, notes, and snippets.

View lmmx's full-sized avatar
💡
lights, camera, action

Louis Maddox lmmx

💡
lights, camera, action
View GitHub Profile
@lmmx
lmmx / uv-add-pdm-test-deps.sh
Created September 10, 2024 18:08
Migrate PDM test dev deps to uv dev deps
uv add --dev $(tq -f pyproject.toml 'tool.pdm.dev-dependencies.test' -o json | jq -r '.[]')
@lmmx
lmmx / subclass_str.py
Created August 20, 2024 14:32
Demo of a custom string type using Pydantic constr validation
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, GetCoreSchemaHandler, TypeAdapter, constr
from pydantic_core import CoreSchema, core_schema
aa_ta = TypeAdapter(constr(pattern=r"^(?i)aa.{10}$"))
@lmmx
lmmx / round_for_snapshot.py
Last active August 21, 2024 00:50
A little rounding trick to keep snapshot tests with dynamic parts less noisy
from pprint import pformat
from inline_snapshot import outsource, snapshot
def round_down_to_order_of_magnitude(n):
"""Small values go to a decimal, so `int` would coerce to zero"""
magnitude = 10 ** (len(str(n)) - 1)
return int((n // magnitude) * magnitude) or n
@lmmx
lmmx / hint_router.py
Last active August 16, 2024 11:04
Controlled data access: Router specifies named Routes (paths that the data is accessed at), a model BeforeValidator on a Routee is populated with those paths, or a ValueError if the path was missing/partial, or a Route in Router was extra (not modelled in the Routee). The generic type argument lets Routee 'mirror' the interface of Router
from pathlib import Path
from pydantic import BaseModel, BeforeValidator, TypeAdapter, model_validator
from typing import Annotated, Union, Any, Generic, TypeVar
RoutePart = Union[int, str]
rp_ta = TypeAdapter(RoutePart)
def split_route(route: str) -> list[RoutePart]:
match route:
@lmmx
lmmx / demo.py
Created August 15, 2024 22:04
A simple type validation approach to JSON key path modelling
from pathlib import Path
from pydantic import BaseModel, BeforeValidator, TypeAdapter
from typing import Annotated, Union
RoutePart = Union[int, str]
rp_ta = TypeAdapter(RoutePart)
def split_route(route: str) -> list[RoutePart]:
match route:
@lmmx
lmmx / extra_split_demo.py
Created August 14, 2024 21:22
Separating extra keys in an `extra` key (either implied by the validator or explicitly in the model)
from pydantic import BaseModel, model_validator
class Model(BaseModel, extra="allow"):
a: int
b: int
@model_validator(mode="before")
@classmethod
def pop_off_extra(cls, values: dict):
fields = list(cls.model_fields)
from inspect import Parameter, signature
from typing import Any, Callable, ClassVar, Generic, ParamSpec, TypeVar
from pydantic import BaseModel, Field, model_validator
P = ParamSpec("P")
R = TypeVar("R")
T = TypeVar("T", bound=BaseModel)
@lmmx
lmmx / function_submodel_registry.py
Last active August 13, 2024 23:11
Demo program using a pattern where functions register themselves against a config, and must be valid submodels at class creation time to be able to 'siphon' off data from larger models. Ensures submodels are guaranteed safe to use at import time.
from inspect import Parameter, signature
from typing import Any, Callable, Generic, ParamSpec, TypeVar
from pydantic import BaseModel, Field, model_validator
P = ParamSpec("P")
R = TypeVar("R")
T = TypeVar("T", bound=BaseModel)
@lmmx
lmmx / prompt.md
Created August 13, 2024 17:42
Prompt for nice Python

Code style: one file, no external libraries besides pathlib and Pydantic, never use with open, Python 3.10+ modern code style (list not List style hints), no bloat or sprawl. Prefer list/dictcomps over loops where possible. Don't use global or otherwise 'free' variables for configuration when you could use a Pydantic model, and set default values on fields rather than setting them at runtime where applicable.

@lmmx
lmmx / autodetect_fx.py
Last active August 11, 2024 13:39
Example of automatically detecting IO effects in function signatures and linting them prior to function execution
from typing import Any, Callable, Generic, Literal, ParamSpec, TypeVar
from pydantic import BaseModel, Field, model_validator, TypeAdapter, NewPath, FilePath
from inspect import signature, Parameter
from pathlib import Path
P = ParamSpec("P")
R = TypeVar("R")
class FileEffect(BaseModel):