From eea1136a742aa7f5276f4d2437014c4012803048 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 05:45:04 +0000 Subject: [PATCH 01/19] mlx only on Apple silicon --- pydantic_ai_slim/pyproject.toml | 2 +- pyproject.toml | 2 +- uv.lock | 12 ++++-------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pydantic_ai_slim/pyproject.toml b/pydantic_ai_slim/pyproject.toml index 1b5909140d..262c54d7f2 100644 --- a/pydantic_ai_slim/pyproject.toml +++ b/pydantic_ai_slim/pyproject.toml @@ -78,7 +78,7 @@ bedrock = ["boto3>=1.40.14"] huggingface = ["huggingface-hub[inference]>=0.33.5"] outlines-transformers = ["outlines[transformers]>=1.0.0, <1.3.0; (sys_platform != 'darwin' or platform_machine != 'x86_64')", "transformers>=4.0.0", "pillow", "torch; (sys_platform != 'darwin' or platform_machine != 'x86_64')"] outlines-llamacpp = ["outlines[llamacpp]>=1.0.0, <1.3.0"] -outlines-mlxlm = ["outlines[mlxlm]>=1.0.0, <1.3.0; (sys_platform != 'darwin' or platform_machine != 'x86_64')"] +outlines-mlxlm = ["outlines[mlxlm]>=1.0.0, <1.3.0; platform_system == 'Darwin' and platform_machine == 'arm64'"] outlines-sglang = ["outlines[sglang]>=1.0.0, <1.3.0", "pillow"] outlines-vllm-offline = ["vllm; python_version < '3.12' and (sys_platform != 'darwin' or platform_machine != 'x86_64')", "torch; (sys_platform != 'darwin' or platform_machine != 'x86_64')", "outlines>=1.0.0, <1.3.0"] # Tools diff --git a/pyproject.toml b/pyproject.toml index 3c13afdece..8f67d198a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ dbos = ["pydantic-ai-slim[dbos]=={{ version }}"] prefect = ["pydantic-ai-slim[prefect]=={{ version }}"] outlines-transformers = ["pydantic-ai-slim[outlines-transformers]=={{ version }}"] outlines-llamacpp = ["pydantic-ai-slim[outlines-llamacpp]=={{ version }}"] -outlines-mlxlm = ["pydantic-ai-slim[outlines-mlxlm]=={{ version }}"] +outlines-mlxlm = ["pydantic-ai-slim[outlines-mlxlm]=={{ version }}; platform_system == 'Darwin' and platform_machine == 'arm64'"] outlines-sglang = ["pydantic-ai-slim[outlines-sglang]=={{ version }}"] outlines-vllm-offline = ["pydantic-ai-slim[outlines-vllm-offline]=={{ version }}"] diff --git a/uv.lock b/uv.lock index 908e0e91da..6cea8768e7 100644 --- a/uv.lock +++ b/uv.lock @@ -3307,19 +3307,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/8a/743ff24a07f8cfd6fb14b3fe05f122f1d8e04e8a912b2f6d0e14369c8caf/mlx-0.29.3-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:340d46443fe0b1e5d84c1e36aa633310de70365ce79aefcaa6f618e62bd4b045", size = 548930, upload-time = "2025-10-17T19:16:49.872Z" }, { url = "https://files.pythonhosted.org/packages/b3/2a/af1b8391b6f543e59ca595f63aaddc33e320d3cc57a4c86ded6932d9dc3c/mlx-0.29.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8449c0e7c221e38368a734a471e0c4b1a7fea072947c75e893a1ee214f208d34", size = 548928, upload-time = "2025-10-17T19:16:58.275Z" }, { url = "https://files.pythonhosted.org/packages/49/85/0c58bdc5733ba92f78f067fc25e131e34db46562719d7909cebfad9313c5/mlx-0.29.3-cp310-cp310-macosx_15_0_arm64.whl", hash = "sha256:1bba5203ed3f785167f5b8891c2e91ede23401586b0a723bfaf815a3ed450e3d", size = 548931, upload-time = "2025-10-17T19:16:52.198Z" }, - { url = "https://files.pythonhosted.org/packages/1b/53/a9648dff9544a201e9ed483f1e0b18cdd92d9be453d58f1fedfd99cde6e1/mlx-0.29.3-cp310-cp310-manylinux_2_35_x86_64.whl", hash = "sha256:ffb3a167da52baeb05756895298a2d582b5e9b9b9364b4a454b78b824a9fa482", size = 652400, upload-time = "2025-10-17T19:20:48.146Z" }, { url = "https://files.pythonhosted.org/packages/94/13/3e91a37fa55dc0e9114620729ab61b27f45ed59053fc77846cad2df54f21/mlx-0.29.3-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:0ffdf1f171c903adeaa688210ba39063059b102f3dcc52a64c2200d95d237f15", size = 549089, upload-time = "2025-10-17T19:17:00.446Z" }, { url = "https://files.pythonhosted.org/packages/13/01/ce008d14fbd2e22b694f568ab4014e14c979a2262c5f8c10e06d4806709f/mlx-0.29.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:e7d1d815be0d4a41e598bdb2992822dafd9ab0d59d4b88af760ee0b6584506b7", size = 549091, upload-time = "2025-10-17T19:16:54.428Z" }, { url = "https://files.pythonhosted.org/packages/72/1c/45642746d36e91e26f3401e9b7931f92d8cc1eb6015cc40218628f320747/mlx-0.29.3-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:d33bff69887fadfd85ce67b8e11318c2319984f3ad4157f871aa9d3beb9de972", size = 549092, upload-time = "2025-10-17T19:17:10.963Z" }, - { url = "https://files.pythonhosted.org/packages/cb/17/9c85fc6ebe6b8ad30c3e75c0cb869939df82146aa8728de1261adacc731d/mlx-0.29.3-cp311-cp311-manylinux_2_35_x86_64.whl", hash = "sha256:8ead74126ffcc1ae49f3b1e0e988620ffbb059c38184f4e9390e294808e2c614", size = 652523, upload-time = "2025-10-17T19:24:01.159Z" }, { url = "https://files.pythonhosted.org/packages/07/f5/14e12e219a2715296150d35f930dc3a6ff319cd60126408e563f03100113/mlx-0.29.3-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:86c62791ce930028d75c41b88b4e3ceb58f5f2e263ff9bfacda998b0c03d9544", size = 549516, upload-time = "2025-10-17T19:18:13.831Z" }, { url = "https://files.pythonhosted.org/packages/c6/e2/5177c80e8c33a8be89fa45fa0a839d5b6a5578687d0ec973bf03638a4e73/mlx-0.29.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cddf6bcdc561094af6b3f0706f8768ecc5216a97eb6973e838c3ac2e2fca2cc8", size = 549509, upload-time = "2025-10-17T19:17:21.517Z" }, { url = "https://files.pythonhosted.org/packages/11/89/aa424217a7a0291b84f8969d504ac63f5af0ef60f248fe5562c3d6e44048/mlx-0.29.3-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:b2e1a249437d017a7425358420d28e641b7bc9c2650f3e013c1b1f4f239d8533", size = 549511, upload-time = "2025-10-17T19:16:54.227Z" }, - { url = "https://files.pythonhosted.org/packages/0e/c7/af484ab5a4864384dc8a5f6f8ade9a29bd6e7a652e535f2ca39cf473ce26/mlx-0.29.3-cp312-cp312-manylinux_2_35_x86_64.whl", hash = "sha256:f09f71ee958f04824b7c7b275a1c1deb052740f5e69eccbff6672e43d9d7f890", size = 649834, upload-time = "2025-10-17T19:23:59.474Z" }, { url = "https://files.pythonhosted.org/packages/fe/a2/078152b45aa8a23949a1b09601d0044f8bb4ab85e909e4475a440c21aaea/mlx-0.29.3-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:d59eccf6a1e1e131becc5a3910504507862da3a4e9b7bd9e73a625515d767844", size = 549585, upload-time = "2025-10-17T19:17:01.872Z" }, { url = "https://files.pythonhosted.org/packages/ae/bb/869eaac4efaae033c13db5fddd6a8907b5d667d135a35a2e482b1af402ee/mlx-0.29.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6642aa0a6dc2242c024fb8274d00631a7e7ffbdcef26148afd299b877c1e6a4a", size = 549586, upload-time = "2025-10-17T19:16:57.844Z" }, { url = "https://files.pythonhosted.org/packages/ad/76/196c248c2b2a471f795356564ad1d7dc40284160c8b66370ffadfd991fa1/mlx-0.29.3-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:ec0aef311fab10cb5f2c274afa6edf6c482636096a5f7886aba43676454aa462", size = 549586, upload-time = "2025-10-17T19:16:39.912Z" }, - { url = "https://files.pythonhosted.org/packages/f2/90/d481dd70b351e28718cfc9a0deb229a75e140abda3ed59284cf635f93f12/mlx-0.29.3-cp313-cp313-manylinux_2_35_x86_64.whl", hash = "sha256:e217a99ece66832a2e631131df32e9feb047276b68ac59ca0ad63735842f6dd0", size = 649781, upload-time = "2025-10-17T19:21:26.075Z" }, ] [[package]] @@ -5347,7 +5343,7 @@ outlines-llamacpp = [ { name = "pydantic-ai-slim", extra = ["outlines-llamacpp"] }, ] outlines-mlxlm = [ - { name = "pydantic-ai-slim", extra = ["outlines-mlxlm"] }, + { name = "pydantic-ai-slim", extra = ["outlines-mlxlm"], marker = "platform_machine == 'arm64' and sys_platform == 'darwin'" }, ] outlines-sglang = [ { name = "pydantic-ai-slim", extra = ["outlines-sglang"] }, @@ -5412,7 +5408,7 @@ requires-dist = [ { name = "pydantic-ai-slim", extras = ["ag-ui", "anthropic", "bedrock", "cli", "cohere", "evals", "fastmcp", "google", "groq", "huggingface", "logfire", "mcp", "mistral", "openai", "retries", "temporal", "ui", "vertexai"], editable = "pydantic_ai_slim" }, { name = "pydantic-ai-slim", extras = ["dbos"], marker = "extra == 'dbos'", editable = "pydantic_ai_slim" }, { name = "pydantic-ai-slim", extras = ["outlines-llamacpp"], marker = "extra == 'outlines-llamacpp'", editable = "pydantic_ai_slim" }, - { name = "pydantic-ai-slim", extras = ["outlines-mlxlm"], marker = "extra == 'outlines-mlxlm'", editable = "pydantic_ai_slim" }, + { name = "pydantic-ai-slim", extras = ["outlines-mlxlm"], marker = "platform_machine == 'arm64' and sys_platform == 'darwin' and extra == 'outlines-mlxlm'", editable = "pydantic_ai_slim" }, { name = "pydantic-ai-slim", extras = ["outlines-sglang"], marker = "extra == 'outlines-sglang'", editable = "pydantic_ai_slim" }, { name = "pydantic-ai-slim", extras = ["outlines-transformers"], marker = "extra == 'outlines-transformers'", editable = "pydantic_ai_slim" }, { name = "pydantic-ai-slim", extras = ["outlines-vllm-offline"], marker = "extra == 'outlines-vllm-offline'", editable = "pydantic_ai_slim" }, @@ -5578,7 +5574,7 @@ outlines-llamacpp = [ { name = "outlines", extra = ["llamacpp"] }, ] outlines-mlxlm = [ - { name = "outlines", extra = ["mlxlm"], marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" }, + { name = "outlines", extra = ["mlxlm"], marker = "platform_machine == 'arm64' and sys_platform == 'darwin'" }, ] outlines-sglang = [ { name = "outlines", extra = ["sglang"] }, @@ -5644,7 +5640,7 @@ requires-dist = [ { name = "opentelemetry-api", specifier = ">=1.28.0" }, { name = "outlines", marker = "extra == 'outlines-vllm-offline'", specifier = ">=1.0.0,<1.3.0" }, { name = "outlines", extras = ["llamacpp"], marker = "extra == 'outlines-llamacpp'", specifier = ">=1.0.0,<1.3.0" }, - { name = "outlines", extras = ["mlxlm"], marker = "(platform_machine != 'x86_64' and extra == 'outlines-mlxlm') or (sys_platform != 'darwin' and extra == 'outlines-mlxlm')", specifier = ">=1.0.0,<1.3.0" }, + { name = "outlines", extras = ["mlxlm"], marker = "platform_machine == 'arm64' and sys_platform == 'darwin' and extra == 'outlines-mlxlm'", specifier = ">=1.0.0,<1.3.0" }, { name = "outlines", extras = ["sglang"], marker = "extra == 'outlines-sglang'", specifier = ">=1.0.0,<1.3.0" }, { name = "outlines", extras = ["transformers"], marker = "(platform_machine != 'x86_64' and extra == 'outlines-transformers') or (sys_platform != 'darwin' and extra == 'outlines-transformers')", specifier = ">=1.0.0,<1.3.0" }, { name = "pillow", marker = "extra == 'outlines-sglang'" }, From eb32ac43cb070900b9ce02e518378920a468fdb2 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 07:20:47 +0000 Subject: [PATCH 02/19] stubs for mlx, vllm, outlines and transformers --- .../pydantic_ai/models/outlines.py | 4 +-- pyproject.toml | 2 ++ stubs/mlx/__init__.pyi | 4 +++ stubs/mlx/nn.pyi | 5 +++ stubs/mlx_lm.pyi | 7 +++++ stubs/outlines/models/base.pyi | 11 +++++++ stubs/outlines/models/mlxlm.pyi | 12 +++++++ stubs/outlines/models/transformers.pyi | 23 ++++++++++++++ stubs/outlines/models/vllm_offline.pyi | 9 ++++++ stubs/transformers/__init__.pyi | 29 +++++++++++++++++ stubs/transformers/modeling_utils.pyi | 5 +++ stubs/transformers/processing_utils.pyi | 5 +++ stubs/transformers/tokenization_utils.pyi | 11 +++++++ stubs/vllm/__init__.pyi | 5 +++ stubs/vllm/sampling_params.pyi | 26 ++++++++++++++++ tests/models/test_outlines.py | 31 ++++++++++--------- 16 files changed, 172 insertions(+), 17 deletions(-) create mode 100644 stubs/mlx/__init__.pyi create mode 100644 stubs/mlx/nn.pyi create mode 100644 stubs/mlx_lm.pyi create mode 100644 stubs/outlines/models/base.pyi create mode 100644 stubs/outlines/models/mlxlm.pyi create mode 100644 stubs/outlines/models/transformers.pyi create mode 100644 stubs/outlines/models/vllm_offline.pyi create mode 100644 stubs/transformers/__init__.pyi create mode 100644 stubs/transformers/modeling_utils.pyi create mode 100644 stubs/transformers/processing_utils.pyi create mode 100644 stubs/transformers/tokenization_utils.pyi create mode 100644 stubs/vllm/__init__.pyi create mode 100644 stubs/vllm/sampling_params.pyi diff --git a/pydantic_ai_slim/pydantic_ai/models/outlines.py b/pydantic_ai_slim/pydantic_ai/models/outlines.py index 5b439952c1..e2f16ffa0d 100644 --- a/pydantic_ai_slim/pydantic_ai/models/outlines.py +++ b/pydantic_ai_slim/pydantic_ai/models/outlines.py @@ -60,7 +60,7 @@ ) from outlines.models.vllm_offline import ( VLLMOffline, - from_vllm_offline, # pyright: ignore[reportUnknownVariableType] + from_vllm_offline, ) from outlines.types.dsl import JsonSchema from PIL import Image as PILImage @@ -393,7 +393,7 @@ def _format_vllm_offline_inference_kwargs( # pragma: no cover self, model_settings: dict[str, Any] ) -> dict[str, Any]: """Select the model settings supported by the vLLMOffline model.""" - from vllm.sampling_params import SamplingParams # pyright: ignore + from vllm.sampling_params import SamplingParams supported_args = [ 'max_tokens', diff --git a/pyproject.toml b/pyproject.toml index 8f67d198a6..4007e29424 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -188,6 +188,7 @@ quote-style = "single" "docs/**/*.py" = ["D"] [tool.pyright] +stubPath = "stubs" pythonVersion = "3.12" typeCheckingMode = "strict" reportMissingTypeStubs = false @@ -217,6 +218,7 @@ exclude = [ [tool.mypy] files = "tests/typed_agent.py,tests/typed_graph.py" strict = true +mypy_path = "stubs" [tool.pytest.ini_options] testpaths = ["tests", "docs/.hooks"] diff --git a/stubs/mlx/__init__.pyi b/stubs/mlx/__init__.pyi new file mode 100644 index 0000000000..ab8297aebc --- /dev/null +++ b/stubs/mlx/__init__.pyi @@ -0,0 +1,4 @@ +from typing import Any + +# mlx is imported as a package, primarily for mlx.nn +__all__: list[str] diff --git a/stubs/mlx/nn.pyi b/stubs/mlx/nn.pyi new file mode 100644 index 0000000000..d6b3473036 --- /dev/null +++ b/stubs/mlx/nn.pyi @@ -0,0 +1,5 @@ +from typing import Any + + +class Module: + ... diff --git a/stubs/mlx_lm.pyi b/stubs/mlx_lm.pyi new file mode 100644 index 0000000000..50d8e42fbc --- /dev/null +++ b/stubs/mlx_lm.pyi @@ -0,0 +1,7 @@ +from typing import Any + +from mlx.nn import Module +from transformers.tokenization_utils import PreTrainedTokenizer + +def load(model_path: str) -> tuple[Module, PreTrainedTokenizer]: ... +def generate_step(*args: Any, **kwargs: Any) -> Any: ... diff --git a/stubs/outlines/models/base.pyi b/stubs/outlines/models/base.pyi new file mode 100644 index 0000000000..da8dea2adc --- /dev/null +++ b/stubs/outlines/models/base.pyi @@ -0,0 +1,11 @@ +from typing import Any, AsyncIterable, Iterable + + +class Model: + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + def stream(self, *args: Any, **kwargs: Any) -> Iterable[Any]: ... + + +class AsyncModel(Model): + async def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + def stream(self, *args: Any, **kwargs: Any) -> AsyncIterable[Any]: ... diff --git a/stubs/outlines/models/mlxlm.pyi b/stubs/outlines/models/mlxlm.pyi new file mode 100644 index 0000000000..0d96326739 --- /dev/null +++ b/stubs/outlines/models/mlxlm.pyi @@ -0,0 +1,12 @@ +from typing import Any +from outlines.models.base import Model + +from mlx.nn import Module +from transformers.tokenization_utils import PreTrainedTokenizer + + +class MLXLM(Model): + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + + +def from_mlxlm(model: Module, tokenizer: PreTrainedTokenizer) -> MLXLM: ... diff --git a/stubs/outlines/models/transformers.pyi b/stubs/outlines/models/transformers.pyi new file mode 100644 index 0000000000..43fdef3805 --- /dev/null +++ b/stubs/outlines/models/transformers.pyi @@ -0,0 +1,23 @@ +from typing import Any +from outlines.models.base import Model + +from transformers.modeling_utils import PreTrainedModel +from transformers.processing_utils import ProcessorMixin +from transformers.tokenization_utils import PreTrainedTokenizer + + +class Transformers(Model): + ... + + +class TransformersMultiModal(Model): + ... + + +def from_transformers( + model: PreTrainedModel, + tokenizer_or_processor: PreTrainedTokenizer | ProcessorMixin, + *, + device_dtype: Any = None, +) -> Transformers | TransformersMultiModal: ... + diff --git a/stubs/outlines/models/vllm_offline.pyi b/stubs/outlines/models/vllm_offline.pyi new file mode 100644 index 0000000000..f753bc6c66 --- /dev/null +++ b/stubs/outlines/models/vllm_offline.pyi @@ -0,0 +1,9 @@ +from typing import Any +from outlines.models.base import Model + + +class VLLMOffline(Model): + ... + + +def from_vllm_offline(model: Any) -> VLLMOffline: ... diff --git a/stubs/transformers/__init__.pyi b/stubs/transformers/__init__.pyi new file mode 100644 index 0000000000..d95dc792fe --- /dev/null +++ b/stubs/transformers/__init__.pyi @@ -0,0 +1,29 @@ +from typing import Any + +from . import modeling_utils, processing_utils, tokenization_utils +from .modeling_utils import PreTrainedModel +from .processing_utils import ProcessorMixin +from .tokenization_utils import PreTrainedTokenizer + + +class AutoModelForCausalLM(PreTrainedModel): + @classmethod + def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedModel: ... + + +class AutoTokenizer(PreTrainedTokenizer): + @classmethod + def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedTokenizer: ... + + +class AutoProcessor(ProcessorMixin): + @classmethod + def from_pretrained(cls, *args: Any, **kwargs: Any) -> ProcessorMixin: ... + + +class LlavaForConditionalGeneration(PreTrainedModel): + @classmethod + def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedModel: ... + + +def from_pretrained(*args: Any, **kwargs: Any) -> Any: ... diff --git a/stubs/transformers/modeling_utils.pyi b/stubs/transformers/modeling_utils.pyi new file mode 100644 index 0000000000..3accd6367d --- /dev/null +++ b/stubs/transformers/modeling_utils.pyi @@ -0,0 +1,5 @@ +from typing import Any + + +class PreTrainedModel: + ... diff --git a/stubs/transformers/processing_utils.pyi b/stubs/transformers/processing_utils.pyi new file mode 100644 index 0000000000..0e9ac620f2 --- /dev/null +++ b/stubs/transformers/processing_utils.pyi @@ -0,0 +1,5 @@ +from typing import Any + + +class ProcessorMixin: + ... diff --git a/stubs/transformers/tokenization_utils.pyi b/stubs/transformers/tokenization_utils.pyi new file mode 100644 index 0000000000..f1e78102cc --- /dev/null +++ b/stubs/transformers/tokenization_utils.pyi @@ -0,0 +1,11 @@ +from typing import Any + + +class PreTrainedTokenizer: + chat_template: str | None + + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + + +class ProcessorMixin: + ... diff --git a/stubs/vllm/__init__.pyi b/stubs/vllm/__init__.pyi new file mode 100644 index 0000000000..259a7e93eb --- /dev/null +++ b/stubs/vllm/__init__.pyi @@ -0,0 +1,5 @@ +from typing import Any + + +class LLM: + def __init__(self, model: str, *args: Any, **kwargs: Any) -> None: ... diff --git a/stubs/vllm/sampling_params.pyi b/stubs/vllm/sampling_params.pyi new file mode 100644 index 0000000000..6e77e405d1 --- /dev/null +++ b/stubs/vllm/sampling_params.pyi @@ -0,0 +1,26 @@ +from typing import Any + + +class SamplingParams: + max_tokens: int | None + temperature: float | None + top_p: float | None + seed: int | None + presence_penalty: float | None + frequency_penalty: float | None + logit_bias: dict[int, float] | None + extra_body: dict[str, Any] | None + + def __init__( + self, + max_tokens: int | None = None, + temperature: float | None = None, + top_p: float | None = None, + seed: int | None = None, + presence_penalty: float | None = None, + frequency_penalty: float | None = None, + logit_bias: dict[int, float] | None = None, + extra_body: dict[str, Any] | None = None, + *args: Any, + **kwargs: Any, + ) -> None: ... diff --git a/tests/models/test_outlines.py b/tests/models/test_outlines.py index 73adc28853..5d72bc9bf4 100644 --- a/tests/models/test_outlines.py +++ b/tests/models/test_outlines.py @@ -43,7 +43,7 @@ with try_import() as imports_successful: import outlines - from pydantic_ai.models.outlines import OutlinesModel + from pydantic_ai.models.outlines import OutlinesAsyncBaseModel, OutlinesModel from pydantic_ai.providers.outlines import OutlinesProvider with try_import() as transformer_imports_successful: @@ -53,11 +53,11 @@ import llama_cpp with try_import() as vllm_imports_successful: - import vllm # type: ignore[reportMissingImports] + import vllm # We try to load the vllm model to ensure it is available try: # pragma: no lax cover - vllm.LLM('microsoft/Phi-3-mini-4k-instruct') # type: ignore + vllm.LLM('microsoft/Phi-3-mini-4k-instruct') except RuntimeError as e: # pragma: lax no cover if 'Found no NVIDIA driver' in str(e) or 'Device string must not be empty' in str(e): # Treat as import failure @@ -93,28 +93,29 @@ @pytest.fixture def mock_async_model() -> OutlinesModel: - class MockOutlinesAsyncModel(outlines.models.base.AsyncModel): + class MockOutlinesAsyncModel(OutlinesAsyncBaseModel): """Mock an OutlinesAsyncModel because no Outlines local models have an async version. The `__call__` and `stream` methods will be called by the Pydantic AI model while the other methods are only implemented because they are abstract methods in the OutlinesAsyncModel class. """ - async def __call__(self, model_input, output_type, backend, **inference_kwargs): # type: ignore[reportMissingParameterType] + async def __call__(self, model_input: Any, output_type: Any, backend: Any, **inference_kwargs: Any) -> str: return 'test' - async def stream(self, model_input, output_type, backend, **inference_kwargs): # type: ignore[reportMissingParameterType] + async def stream(self, model_input: Any, output_type: Any, backend: Any, **inference_kwargs: Any): for _ in range(2): yield 'test' - async def generate(self, model_input, output_type, **inference_kwargs): # type: ignore[reportMissingParameterType] - ... # pragma: no cover + async def generate(self, model_input: Any, output_type: Any, **inference_kwargs: Any): ... # pragma: no cover - async def generate_batch(self, model_input, output_type, **inference_kwargs): # type: ignore[reportMissingParameterType] - ... # pragma: no cover + async def generate_batch( + self, model_input: Any, output_type: Any, **inference_kwargs: Any + ): ... # pragma: no cover - async def generate_stream(self, model_input, output_type, **inference_kwargs): # type: ignore[reportMissingParameterType] - ... # pragma: no cover + async def generate_stream( + self, model_input: Any, output_type: Any, **inference_kwargs: Any + ): ... # pragma: no cover return OutlinesModel(MockOutlinesAsyncModel(), provider=OutlinesProvider()) @@ -128,7 +129,7 @@ def transformers_model() -> OutlinesModel: hf_tokenizer = transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini') # type: ignore chat_template = '{% for message in messages %}{{ message.role }}: {{ message.content }}{% endfor %}' hf_tokenizer.chat_template = chat_template - outlines_model = outlines.models.transformers.from_transformers( + outlines_model = outlines.models.transformers.from_transformers( # type: ignore[reportUnknownMemberType] hf_model, # type: ignore[reportUnknownArgumentType] hf_tokenizer, # type: ignore ) @@ -144,7 +145,7 @@ def transformers_multimodal_model() -> OutlinesModel: hf_processor = transformers.AutoProcessor.from_pretrained( # type: ignore 'trl-internal-testing/tiny-LlavaForConditionalGeneration' ) - outlines_model = outlines.models.transformers.from_transformers( + outlines_model = outlines.models.transformers.from_transformers( # type: ignore[reportUnknownMemberType] hf_model, hf_processor, # type: ignore ) @@ -164,7 +165,7 @@ def llamacpp_model() -> OutlinesModel: @pytest.fixture def mlxlm_model() -> OutlinesModel: # pragma: no cover - outlines_model = outlines.models.mlxlm.from_mlxlm( + outlines_model = outlines.models.mlxlm.from_mlxlm( # type: ignore[reportUnknownMemberType] *mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit') # type: ignore ) return OutlinesModel(outlines_model, provider=OutlinesProvider()) From 6498440e2187ae6cfbbca5fffd46b5161895d0ad Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 07:46:29 +0000 Subject: [PATCH 03/19] add stubs to ruff config --- pyproject.toml | 2 ++ stubs/mlx/nn.pyi | 4 +--- stubs/outlines/models/base.pyi | 5 ++--- stubs/outlines/models/mlxlm.pyi | 4 +--- stubs/outlines/models/transformers.pyi | 13 +++---------- stubs/outlines/models/vllm_offline.pyi | 6 ++---- stubs/transformers/__init__.pyi | 5 ----- stubs/transformers/modeling_utils.pyi | 4 +--- stubs/transformers/processing_utils.pyi | 4 +--- stubs/transformers/tokenization_utils.pyi | 5 +---- stubs/vllm/__init__.pyi | 1 - stubs/vllm/sampling_params.pyi | 1 - 12 files changed, 14 insertions(+), 40 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4007e29424..cdebd6bd3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -142,6 +142,7 @@ include = [ "clai/**/*.py", "tests/**/*.py", "docs/**/*.py", + "stubs/**/*.pyi", ] [tool.ruff.lint] @@ -186,6 +187,7 @@ quote-style = "single" "examples/**/*.py" = ["D101", "D103"] "tests/**/*.py" = ["D"] "docs/**/*.py" = ["D"] +"stubs/**/*.pyi" = ["F401"] [tool.pyright] stubPath = "stubs" diff --git a/stubs/mlx/nn.pyi b/stubs/mlx/nn.pyi index d6b3473036..db66a81e5f 100644 --- a/stubs/mlx/nn.pyi +++ b/stubs/mlx/nn.pyi @@ -1,5 +1,3 @@ from typing import Any - -class Module: - ... +class Module: ... diff --git a/stubs/outlines/models/base.pyi b/stubs/outlines/models/base.pyi index da8dea2adc..e7b8063089 100644 --- a/stubs/outlines/models/base.pyi +++ b/stubs/outlines/models/base.pyi @@ -1,11 +1,10 @@ -from typing import Any, AsyncIterable, Iterable - +from collections.abc import AsyncIterable, Iterable +from typing import Any class Model: def __call__(self, *args: Any, **kwargs: Any) -> Any: ... def stream(self, *args: Any, **kwargs: Any) -> Iterable[Any]: ... - class AsyncModel(Model): async def __call__(self, *args: Any, **kwargs: Any) -> Any: ... def stream(self, *args: Any, **kwargs: Any) -> AsyncIterable[Any]: ... diff --git a/stubs/outlines/models/mlxlm.pyi b/stubs/outlines/models/mlxlm.pyi index 0d96326739..77a1a5686a 100644 --- a/stubs/outlines/models/mlxlm.pyi +++ b/stubs/outlines/models/mlxlm.pyi @@ -1,12 +1,10 @@ from typing import Any -from outlines.models.base import Model from mlx.nn import Module +from outlines.models.base import Model from transformers.tokenization_utils import PreTrainedTokenizer - class MLXLM(Model): def __init__(self, *args: Any, **kwargs: Any) -> None: ... - def from_mlxlm(model: Module, tokenizer: PreTrainedTokenizer) -> MLXLM: ... diff --git a/stubs/outlines/models/transformers.pyi b/stubs/outlines/models/transformers.pyi index 43fdef3805..15161091ed 100644 --- a/stubs/outlines/models/transformers.pyi +++ b/stubs/outlines/models/transformers.pyi @@ -1,18 +1,12 @@ from typing import Any -from outlines.models.base import Model +from outlines.models.base import Model from transformers.modeling_utils import PreTrainedModel from transformers.processing_utils import ProcessorMixin from transformers.tokenization_utils import PreTrainedTokenizer - -class Transformers(Model): - ... - - -class TransformersMultiModal(Model): - ... - +class Transformers(Model): ... +class TransformersMultiModal(Model): ... def from_transformers( model: PreTrainedModel, @@ -20,4 +14,3 @@ def from_transformers( *, device_dtype: Any = None, ) -> Transformers | TransformersMultiModal: ... - diff --git a/stubs/outlines/models/vllm_offline.pyi b/stubs/outlines/models/vllm_offline.pyi index f753bc6c66..2fab0321c2 100644 --- a/stubs/outlines/models/vllm_offline.pyi +++ b/stubs/outlines/models/vllm_offline.pyi @@ -1,9 +1,7 @@ from typing import Any -from outlines.models.base import Model - -class VLLMOffline(Model): - ... +from outlines.models.base import Model +class VLLMOffline(Model): ... def from_vllm_offline(model: Any) -> VLLMOffline: ... diff --git a/stubs/transformers/__init__.pyi b/stubs/transformers/__init__.pyi index d95dc792fe..63a8b0d718 100644 --- a/stubs/transformers/__init__.pyi +++ b/stubs/transformers/__init__.pyi @@ -5,25 +5,20 @@ from .modeling_utils import PreTrainedModel from .processing_utils import ProcessorMixin from .tokenization_utils import PreTrainedTokenizer - class AutoModelForCausalLM(PreTrainedModel): @classmethod def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedModel: ... - class AutoTokenizer(PreTrainedTokenizer): @classmethod def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedTokenizer: ... - class AutoProcessor(ProcessorMixin): @classmethod def from_pretrained(cls, *args: Any, **kwargs: Any) -> ProcessorMixin: ... - class LlavaForConditionalGeneration(PreTrainedModel): @classmethod def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedModel: ... - def from_pretrained(*args: Any, **kwargs: Any) -> Any: ... diff --git a/stubs/transformers/modeling_utils.pyi b/stubs/transformers/modeling_utils.pyi index 3accd6367d..bd1aafe2ae 100644 --- a/stubs/transformers/modeling_utils.pyi +++ b/stubs/transformers/modeling_utils.pyi @@ -1,5 +1,3 @@ from typing import Any - -class PreTrainedModel: - ... +class PreTrainedModel: ... diff --git a/stubs/transformers/processing_utils.pyi b/stubs/transformers/processing_utils.pyi index 0e9ac620f2..6c0397bcf8 100644 --- a/stubs/transformers/processing_utils.pyi +++ b/stubs/transformers/processing_utils.pyi @@ -1,5 +1,3 @@ from typing import Any - -class ProcessorMixin: - ... +class ProcessorMixin: ... diff --git a/stubs/transformers/tokenization_utils.pyi b/stubs/transformers/tokenization_utils.pyi index f1e78102cc..b8c826f3bb 100644 --- a/stubs/transformers/tokenization_utils.pyi +++ b/stubs/transformers/tokenization_utils.pyi @@ -1,11 +1,8 @@ from typing import Any - class PreTrainedTokenizer: chat_template: str | None def __init__(self, *args: Any, **kwargs: Any) -> None: ... - -class ProcessorMixin: - ... +class ProcessorMixin: ... diff --git a/stubs/vllm/__init__.pyi b/stubs/vllm/__init__.pyi index 259a7e93eb..eb7907acfd 100644 --- a/stubs/vllm/__init__.pyi +++ b/stubs/vllm/__init__.pyi @@ -1,5 +1,4 @@ from typing import Any - class LLM: def __init__(self, model: str, *args: Any, **kwargs: Any) -> None: ... diff --git a/stubs/vllm/sampling_params.pyi b/stubs/vllm/sampling_params.pyi index 6e77e405d1..71a25b14d2 100644 --- a/stubs/vllm/sampling_params.pyi +++ b/stubs/vllm/sampling_params.pyi @@ -1,6 +1,5 @@ from typing import Any - class SamplingParams: max_tokens: int | None temperature: float | None From 265a0d1c4f83ee0b0f02d7fff8517b8b5d12b013 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 08:46:47 +0000 Subject: [PATCH 04/19] deferred evaluation --- stubs/mlx/__init__.pyi | 2 ++ stubs/mlx/nn.pyi | 2 ++ stubs/mlx_lm.pyi | 2 ++ stubs/outlines/models/base.pyi | 2 ++ stubs/outlines/models/mlxlm.pyi | 2 ++ stubs/outlines/models/transformers.pyi | 2 ++ stubs/outlines/models/vllm_offline.pyi | 2 ++ stubs/transformers/__init__.pyi | 2 ++ stubs/transformers/modeling_utils.pyi | 2 ++ stubs/transformers/processing_utils.pyi | 2 ++ stubs/transformers/tokenization_utils.pyi | 2 ++ stubs/vllm/__init__.pyi | 2 ++ stubs/vllm/sampling_params.pyi | 3 +++ 13 files changed, 27 insertions(+) diff --git a/stubs/mlx/__init__.pyi b/stubs/mlx/__init__.pyi index ab8297aebc..3c8577e53d 100644 --- a/stubs/mlx/__init__.pyi +++ b/stubs/mlx/__init__.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any # mlx is imported as a package, primarily for mlx.nn diff --git a/stubs/mlx/nn.pyi b/stubs/mlx/nn.pyi index db66a81e5f..beb2587a55 100644 --- a/stubs/mlx/nn.pyi +++ b/stubs/mlx/nn.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any class Module: ... diff --git a/stubs/mlx_lm.pyi b/stubs/mlx_lm.pyi index 50d8e42fbc..b4cc64f87f 100644 --- a/stubs/mlx_lm.pyi +++ b/stubs/mlx_lm.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mlx.nn import Module diff --git a/stubs/outlines/models/base.pyi b/stubs/outlines/models/base.pyi index e7b8063089..5e50032007 100644 --- a/stubs/outlines/models/base.pyi +++ b/stubs/outlines/models/base.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections.abc import AsyncIterable, Iterable from typing import Any diff --git a/stubs/outlines/models/mlxlm.pyi b/stubs/outlines/models/mlxlm.pyi index 77a1a5686a..e81b6ad38c 100644 --- a/stubs/outlines/models/mlxlm.pyi +++ b/stubs/outlines/models/mlxlm.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mlx.nn import Module diff --git a/stubs/outlines/models/transformers.pyi b/stubs/outlines/models/transformers.pyi index 15161091ed..c87dbc7718 100644 --- a/stubs/outlines/models/transformers.pyi +++ b/stubs/outlines/models/transformers.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from outlines.models.base import Model diff --git a/stubs/outlines/models/vllm_offline.pyi b/stubs/outlines/models/vllm_offline.pyi index 2fab0321c2..8f37adb8fa 100644 --- a/stubs/outlines/models/vllm_offline.pyi +++ b/stubs/outlines/models/vllm_offline.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from outlines.models.base import Model diff --git a/stubs/transformers/__init__.pyi b/stubs/transformers/__init__.pyi index 63a8b0d718..7d2f2c1b39 100644 --- a/stubs/transformers/__init__.pyi +++ b/stubs/transformers/__init__.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from . import modeling_utils, processing_utils, tokenization_utils diff --git a/stubs/transformers/modeling_utils.pyi b/stubs/transformers/modeling_utils.pyi index bd1aafe2ae..49a593c56b 100644 --- a/stubs/transformers/modeling_utils.pyi +++ b/stubs/transformers/modeling_utils.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any class PreTrainedModel: ... diff --git a/stubs/transformers/processing_utils.pyi b/stubs/transformers/processing_utils.pyi index 6c0397bcf8..2ce57efa38 100644 --- a/stubs/transformers/processing_utils.pyi +++ b/stubs/transformers/processing_utils.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any class ProcessorMixin: ... diff --git a/stubs/transformers/tokenization_utils.pyi b/stubs/transformers/tokenization_utils.pyi index b8c826f3bb..1dd3c6301f 100644 --- a/stubs/transformers/tokenization_utils.pyi +++ b/stubs/transformers/tokenization_utils.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any class PreTrainedTokenizer: diff --git a/stubs/vllm/__init__.pyi b/stubs/vllm/__init__.pyi index eb7907acfd..f9e26d013a 100644 --- a/stubs/vllm/__init__.pyi +++ b/stubs/vllm/__init__.pyi @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any class LLM: diff --git a/stubs/vllm/sampling_params.pyi b/stubs/vllm/sampling_params.pyi index 71a25b14d2..dd96098693 100644 --- a/stubs/vllm/sampling_params.pyi +++ b/stubs/vllm/sampling_params.pyi @@ -1,5 +1,8 @@ +from __future__ import annotations + from typing import Any + class SamplingParams: max_tokens: int | None temperature: float | None From 9756d307cebfb0fb1e1fe7d182ff365b7d8ccb3f Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 09:11:57 +0000 Subject: [PATCH 05/19] ignore more in stubs --- pyproject.toml | 2 +- stubs/mlx/__init__.pyi | 4 +--- stubs/mlx/nn.pyi | 2 -- stubs/mlx_lm.pyi | 2 -- stubs/outlines/models/base.pyi | 2 -- stubs/outlines/models/mlxlm.pyi | 2 -- stubs/outlines/models/transformers.pyi | 2 -- stubs/outlines/models/vllm_offline.pyi | 2 -- stubs/transformers/__init__.pyi | 2 -- stubs/transformers/modeling_utils.pyi | 2 -- stubs/transformers/processing_utils.pyi | 2 -- stubs/transformers/tokenization_utils.pyi | 2 -- stubs/vllm/__init__.pyi | 2 -- stubs/vllm/sampling_params.pyi | 3 --- 14 files changed, 2 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cdebd6bd3c..695fec9e1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,7 +187,7 @@ quote-style = "single" "examples/**/*.py" = ["D101", "D103"] "tests/**/*.py" = ["D"] "docs/**/*.py" = ["D"] -"stubs/**/*.pyi" = ["F401"] +"stubs/**/*.pyi" = ["F401", "PYI044", "PYI035", "ANN401"] [tool.pyright] stubPath = "stubs" diff --git a/stubs/mlx/__init__.pyi b/stubs/mlx/__init__.pyi index 3c8577e53d..43e14e0711 100644 --- a/stubs/mlx/__init__.pyi +++ b/stubs/mlx/__init__.pyi @@ -1,6 +1,4 @@ -from __future__ import annotations - from typing import Any # mlx is imported as a package, primarily for mlx.nn -__all__: list[str] +__all__: list[str] = [] diff --git a/stubs/mlx/nn.pyi b/stubs/mlx/nn.pyi index beb2587a55..db66a81e5f 100644 --- a/stubs/mlx/nn.pyi +++ b/stubs/mlx/nn.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any class Module: ... diff --git a/stubs/mlx_lm.pyi b/stubs/mlx_lm.pyi index b4cc64f87f..50d8e42fbc 100644 --- a/stubs/mlx_lm.pyi +++ b/stubs/mlx_lm.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any from mlx.nn import Module diff --git a/stubs/outlines/models/base.pyi b/stubs/outlines/models/base.pyi index 5e50032007..e7b8063089 100644 --- a/stubs/outlines/models/base.pyi +++ b/stubs/outlines/models/base.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from collections.abc import AsyncIterable, Iterable from typing import Any diff --git a/stubs/outlines/models/mlxlm.pyi b/stubs/outlines/models/mlxlm.pyi index e81b6ad38c..77a1a5686a 100644 --- a/stubs/outlines/models/mlxlm.pyi +++ b/stubs/outlines/models/mlxlm.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any from mlx.nn import Module diff --git a/stubs/outlines/models/transformers.pyi b/stubs/outlines/models/transformers.pyi index c87dbc7718..15161091ed 100644 --- a/stubs/outlines/models/transformers.pyi +++ b/stubs/outlines/models/transformers.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any from outlines.models.base import Model diff --git a/stubs/outlines/models/vllm_offline.pyi b/stubs/outlines/models/vllm_offline.pyi index 8f37adb8fa..2fab0321c2 100644 --- a/stubs/outlines/models/vllm_offline.pyi +++ b/stubs/outlines/models/vllm_offline.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any from outlines.models.base import Model diff --git a/stubs/transformers/__init__.pyi b/stubs/transformers/__init__.pyi index 7d2f2c1b39..63a8b0d718 100644 --- a/stubs/transformers/__init__.pyi +++ b/stubs/transformers/__init__.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any from . import modeling_utils, processing_utils, tokenization_utils diff --git a/stubs/transformers/modeling_utils.pyi b/stubs/transformers/modeling_utils.pyi index 49a593c56b..bd1aafe2ae 100644 --- a/stubs/transformers/modeling_utils.pyi +++ b/stubs/transformers/modeling_utils.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any class PreTrainedModel: ... diff --git a/stubs/transformers/processing_utils.pyi b/stubs/transformers/processing_utils.pyi index 2ce57efa38..6c0397bcf8 100644 --- a/stubs/transformers/processing_utils.pyi +++ b/stubs/transformers/processing_utils.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any class ProcessorMixin: ... diff --git a/stubs/transformers/tokenization_utils.pyi b/stubs/transformers/tokenization_utils.pyi index 1dd3c6301f..b8c826f3bb 100644 --- a/stubs/transformers/tokenization_utils.pyi +++ b/stubs/transformers/tokenization_utils.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any class PreTrainedTokenizer: diff --git a/stubs/vllm/__init__.pyi b/stubs/vllm/__init__.pyi index f9e26d013a..eb7907acfd 100644 --- a/stubs/vllm/__init__.pyi +++ b/stubs/vllm/__init__.pyi @@ -1,5 +1,3 @@ -from __future__ import annotations - from typing import Any class LLM: diff --git a/stubs/vllm/sampling_params.pyi b/stubs/vllm/sampling_params.pyi index dd96098693..71a25b14d2 100644 --- a/stubs/vllm/sampling_params.pyi +++ b/stubs/vllm/sampling_params.pyi @@ -1,8 +1,5 @@ -from __future__ import annotations - from typing import Any - class SamplingParams: max_tokens: int | None temperature: float | None From bb4d9c3335560bbcfb3d20950e54fb1b4fdcd861 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 11:57:26 +0000 Subject: [PATCH 06/19] remove further type ignore --- stubs/transformers/__init__.pyi | 10 ++++++---- tests/models/test_outlines.py | 18 ++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/stubs/transformers/__init__.pyi b/stubs/transformers/__init__.pyi index 63a8b0d718..1d04068382 100644 --- a/stubs/transformers/__init__.pyi +++ b/stubs/transformers/__init__.pyi @@ -1,5 +1,7 @@ from typing import Any +from typing_extensions import Self + from . import modeling_utils, processing_utils, tokenization_utils from .modeling_utils import PreTrainedModel from .processing_utils import ProcessorMixin @@ -7,18 +9,18 @@ from .tokenization_utils import PreTrainedTokenizer class AutoModelForCausalLM(PreTrainedModel): @classmethod - def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedModel: ... + def from_pretrained(cls, *args: Any, **kwargs: Any) -> Self: ... class AutoTokenizer(PreTrainedTokenizer): @classmethod - def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedTokenizer: ... + def from_pretrained(cls, *args: Any, **kwargs: Any) -> Self: ... class AutoProcessor(ProcessorMixin): @classmethod - def from_pretrained(cls, *args: Any, **kwargs: Any) -> ProcessorMixin: ... + def from_pretrained(cls, *args: Any, **kwargs: Any) -> Self: ... class LlavaForConditionalGeneration(PreTrainedModel): @classmethod - def from_pretrained(cls, *args: Any, **kwargs: Any) -> PreTrainedModel: ... + def from_pretrained(cls, *args: Any, **kwargs: Any) -> Self: ... def from_pretrained(*args: Any, **kwargs: Any) -> Any: ... diff --git a/tests/models/test_outlines.py b/tests/models/test_outlines.py index 5d72bc9bf4..f5d634ee47 100644 --- a/tests/models/test_outlines.py +++ b/tests/models/test_outlines.py @@ -122,11 +122,11 @@ async def generate_stream( @pytest.fixture def transformers_model() -> OutlinesModel: - hf_model = transformers.AutoModelForCausalLM.from_pretrained( # type: ignore + hf_model = transformers.AutoModelForCausalLM.from_pretrained( 'erwanf/gpt2-mini', device_map='cpu', ) - hf_tokenizer = transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini') # type: ignore + hf_tokenizer = transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini') chat_template = '{% for message in messages %}{{ message.role }}: {{ message.content }}{% endfor %}' hf_tokenizer.chat_template = chat_template outlines_model = outlines.models.transformers.from_transformers( # type: ignore[reportUnknownMemberType] @@ -138,13 +138,11 @@ def transformers_model() -> OutlinesModel: @pytest.fixture def transformers_multimodal_model() -> OutlinesModel: - hf_model = transformers.LlavaForConditionalGeneration.from_pretrained( # type: ignore + hf_model = transformers.LlavaForConditionalGeneration.from_pretrained( 'trl-internal-testing/tiny-LlavaForConditionalGeneration', device_map='cpu', ) - hf_processor = transformers.AutoProcessor.from_pretrained( # type: ignore - 'trl-internal-testing/tiny-LlavaForConditionalGeneration' - ) + hf_processor = transformers.AutoProcessor.from_pretrained('trl-internal-testing/tiny-LlavaForConditionalGeneration') outlines_model = outlines.models.transformers.from_transformers( # type: ignore[reportUnknownMemberType] hf_model, hf_processor, # type: ignore @@ -198,11 +196,11 @@ def binary_image() -> BinaryImage: pytest.param( 'from_transformers', lambda: ( - transformers.AutoModelForCausalLM.from_pretrained( # type: ignore + transformers.AutoModelForCausalLM.from_pretrained( 'erwanf/gpt2-mini', device_map='cpu', ), - transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini'), # type: ignore + transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini'), ), marks=skip_if_transformers_imports_unsuccessful, ), @@ -257,11 +255,11 @@ def test_init(model_loading_function_name: str, args: Callable[[], tuple[Any]]) pytest.param( 'from_transformers', lambda: ( - transformers.AutoModelForCausalLM.from_pretrained( # type: ignore + transformers.AutoModelForCausalLM.from_pretrained( 'erwanf/gpt2-mini', device_map='cpu', ), - transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini'), # type: ignore + transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini'), ), marks=skip_if_transformers_imports_unsuccessful, ), From 83351287bc1d83070a758d44b73cf32a4b8704fb Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 12:03:13 +0000 Subject: [PATCH 07/19] remove further type check --- stubs/outlines/models/vllm_offline.pyi | 7 +++++-- tests/models/test_outlines.py | 8 +++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/stubs/outlines/models/vllm_offline.pyi b/stubs/outlines/models/vllm_offline.pyi index 2fab0321c2..e5cb85cffe 100644 --- a/stubs/outlines/models/vllm_offline.pyi +++ b/stubs/outlines/models/vllm_offline.pyi @@ -1,7 +1,10 @@ -from typing import Any +from typing import TYPE_CHECKING from outlines.models.base import Model +if TYPE_CHECKING: + from vllm import LLM + class VLLMOffline(Model): ... -def from_vllm_offline(model: Any) -> VLLMOffline: ... +def from_vllm_offline(model: LLM) -> VLLMOffline: ... diff --git a/tests/models/test_outlines.py b/tests/models/test_outlines.py index f5d634ee47..de914373fe 100644 --- a/tests/models/test_outlines.py +++ b/tests/models/test_outlines.py @@ -179,9 +179,7 @@ def sglang_model() -> OutlinesModel: @pytest.fixture def vllm_model_offline() -> OutlinesModel: # pragma: no cover - outlines_model = outlines.models.vllm_offline.from_vllm_offline( # type: ignore - vllm.LLM('microsoft/Phi-3-mini-4k-instruct') # type: ignore - ) + outlines_model = outlines.models.vllm_offline.from_vllm_offline(vllm.LLM('microsoft/Phi-3-mini-4k-instruct')) return OutlinesModel(outlines_model, provider=OutlinesProvider()) @@ -226,7 +224,7 @@ def binary_image() -> BinaryImage: ), pytest.param( 'from_vllm_offline', - lambda: (vllm.LLM('microsoft/Phi-3-mini-4k-instruct'),), # type: ignore + lambda: (vllm.LLM('microsoft/Phi-3-mini-4k-instruct'),), marks=skip_if_vllm_imports_unsuccessful, ), ] @@ -285,7 +283,7 @@ def test_init(model_loading_function_name: str, args: Callable[[], tuple[Any]]) ), pytest.param( 'from_vllm_offline', - lambda: (vllm.LLM('microsoft/Phi-3-mini-4k-instruct'),), # type: ignore + lambda: (vllm.LLM('microsoft/Phi-3-mini-4k-instruct'),), marks=skip_if_vllm_imports_unsuccessful, ), ] From 924101336b80cd643c535cea0abae3fbbcd456d4 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 12:12:18 +0000 Subject: [PATCH 08/19] remove further type ignore --- stubs/outlines/__init__.pyi | 3 +++ stubs/outlines/models/__init__.pyi | 3 +++ stubs/outlines/models/llamacpp.pyi | 10 ++++++++++ stubs/outlines/models/sglang.pyi | 11 +++++++++++ tests/models/test_outlines.py | 8 +++----- 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 stubs/outlines/__init__.pyi create mode 100644 stubs/outlines/models/__init__.pyi create mode 100644 stubs/outlines/models/llamacpp.pyi create mode 100644 stubs/outlines/models/sglang.pyi diff --git a/stubs/outlines/__init__.pyi b/stubs/outlines/__init__.pyi new file mode 100644 index 0000000000..aa54175662 --- /dev/null +++ b/stubs/outlines/__init__.pyi @@ -0,0 +1,3 @@ +from . import models + +__all__: list[str] = [] diff --git a/stubs/outlines/models/__init__.pyi b/stubs/outlines/models/__init__.pyi new file mode 100644 index 0000000000..b4931a7631 --- /dev/null +++ b/stubs/outlines/models/__init__.pyi @@ -0,0 +1,3 @@ +from . import base, llamacpp, mlxlm, sglang, transformers, vllm_offline + +__all__: list[str] = [] diff --git a/stubs/outlines/models/llamacpp.pyi b/stubs/outlines/models/llamacpp.pyi new file mode 100644 index 0000000000..650576fb26 --- /dev/null +++ b/stubs/outlines/models/llamacpp.pyi @@ -0,0 +1,10 @@ +from typing import TYPE_CHECKING + +from outlines.models.base import Model + +if TYPE_CHECKING: + from llama_cpp import Llama + +class LlamaCpp(Model): ... + +def from_llamacpp(model: Llama) -> LlamaCpp: ... diff --git a/stubs/outlines/models/sglang.pyi b/stubs/outlines/models/sglang.pyi new file mode 100644 index 0000000000..c72d500eac --- /dev/null +++ b/stubs/outlines/models/sglang.pyi @@ -0,0 +1,11 @@ +from typing import TYPE_CHECKING, Any, Union + +from outlines.models.base import AsyncModel, Model + +if TYPE_CHECKING: + from openai import AsyncOpenAI, OpenAI + +class SGLang(Model): ... +class AsyncSGLang(AsyncModel): ... + +def from_sglang(client: OpenAI | AsyncOpenAI, *args: Any, **kwargs: Any) -> SGLang | AsyncSGLang: ... diff --git a/tests/models/test_outlines.py b/tests/models/test_outlines.py index de914373fe..1ff9e12b8a 100644 --- a/tests/models/test_outlines.py +++ b/tests/models/test_outlines.py @@ -163,9 +163,7 @@ def llamacpp_model() -> OutlinesModel: @pytest.fixture def mlxlm_model() -> OutlinesModel: # pragma: no cover - outlines_model = outlines.models.mlxlm.from_mlxlm( # type: ignore[reportUnknownMemberType] - *mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit') # type: ignore - ) + outlines_model = outlines.models.mlxlm.from_mlxlm(*mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit')) return OutlinesModel(outlines_model, provider=OutlinesProvider()) @@ -214,7 +212,7 @@ def binary_image() -> BinaryImage: ), pytest.param( 'from_mlxlm', - lambda: mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit'), # type: ignore + lambda: mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit'), marks=skip_if_mlxlm_imports_unsuccessful, ), pytest.param( @@ -273,7 +271,7 @@ def test_init(model_loading_function_name: str, args: Callable[[], tuple[Any]]) ), pytest.param( 'from_mlxlm', - lambda: mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit'), # type: ignore + lambda: mlx_lm.load('mlx-community/SmolLM-135M-Instruct-4bit'), marks=skip_if_mlxlm_imports_unsuccessful, ), pytest.param( From cda13d9976cdf6acd3ed13574e8d6590770e9156 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 12:17:53 +0000 Subject: [PATCH 09/19] remove further type ignore --- stubs/llama_cpp.pyi | 19 +++++++++++++++++++ tests/models/test_outlines.py | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 stubs/llama_cpp.pyi diff --git a/stubs/llama_cpp.pyi b/stubs/llama_cpp.pyi new file mode 100644 index 0000000000..f324f07254 --- /dev/null +++ b/stubs/llama_cpp.pyi @@ -0,0 +1,19 @@ +from collections.abc import Sequence +from os import PathLike +from typing import Any, Literal + +from typing_extensions import Self + +class Llama: + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + @classmethod + def from_pretrained( + cls, + repo_id: str, + filename: str | None = None, + additional_files: Sequence[str] | None = None, + local_dir: str | PathLike[str] | None = None, + local_dir_use_symlinks: bool | Literal['auto'] = 'auto', + cache_dir: str | PathLike[str] | None = None, + **kwargs: Any, + ) -> Self: ... diff --git a/tests/models/test_outlines.py b/tests/models/test_outlines.py index 1ff9e12b8a..a182c95401 100644 --- a/tests/models/test_outlines.py +++ b/tests/models/test_outlines.py @@ -153,7 +153,7 @@ def transformers_multimodal_model() -> OutlinesModel: @pytest.fixture def llamacpp_model() -> OutlinesModel: outlines_model_llamacpp = outlines.models.llamacpp.from_llamacpp( - llama_cpp.Llama.from_pretrained( # type: ignore + llama_cpp.Llama.from_pretrained( repo_id='M4-ai/TinyMistral-248M-v2-Instruct-GGUF', filename='TinyMistral-248M-v2-Instruct.Q4_K_M.gguf', ) @@ -203,7 +203,7 @@ def binary_image() -> BinaryImage: pytest.param( 'from_llamacpp', lambda: ( - llama_cpp.Llama.from_pretrained( # type: ignore + llama_cpp.Llama.from_pretrained( repo_id='M4-ai/TinyMistral-248M-v2-Instruct-GGUF', filename='TinyMistral-248M-v2-Instruct.Q4_K_M.gguf', ), @@ -262,7 +262,7 @@ def test_init(model_loading_function_name: str, args: Callable[[], tuple[Any]]) pytest.param( 'from_llamacpp', lambda: ( - llama_cpp.Llama.from_pretrained( # type: ignore + llama_cpp.Llama.from_pretrained( repo_id='M4-ai/TinyMistral-248M-v2-Instruct-GGUF', filename='TinyMistral-248M-v2-Instruct.Q4_K_M.gguf', ), From ad6b275152d16f23e562c9b4a48d2a1e790b56c4 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 12:24:26 +0000 Subject: [PATCH 10/19] remove further type ignore --- stubs/outlines/models/transformers.pyi | 5 +++-- tests/models/test_outlines.py | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/stubs/outlines/models/transformers.pyi b/stubs/outlines/models/transformers.pyi index 15161091ed..7094d2c9ce 100644 --- a/stubs/outlines/models/transformers.pyi +++ b/stubs/outlines/models/transformers.pyi @@ -1,6 +1,7 @@ from typing import Any from outlines.models.base import Model +from transformers import AutoModelForCausalLM, AutoProcessor, AutoTokenizer, LlavaForConditionalGeneration from transformers.modeling_utils import PreTrainedModel from transformers.processing_utils import ProcessorMixin from transformers.tokenization_utils import PreTrainedTokenizer @@ -9,8 +10,8 @@ class Transformers(Model): ... class TransformersMultiModal(Model): ... def from_transformers( - model: PreTrainedModel, - tokenizer_or_processor: PreTrainedTokenizer | ProcessorMixin, + model: PreTrainedModel | AutoModelForCausalLM | LlavaForConditionalGeneration, + tokenizer_or_processor: PreTrainedTokenizer | ProcessorMixin | AutoTokenizer | AutoProcessor, *, device_dtype: Any = None, ) -> Transformers | TransformersMultiModal: ... diff --git a/tests/models/test_outlines.py b/tests/models/test_outlines.py index a182c95401..580e34ea89 100644 --- a/tests/models/test_outlines.py +++ b/tests/models/test_outlines.py @@ -129,9 +129,9 @@ def transformers_model() -> OutlinesModel: hf_tokenizer = transformers.AutoTokenizer.from_pretrained('erwanf/gpt2-mini') chat_template = '{% for message in messages %}{{ message.role }}: {{ message.content }}{% endfor %}' hf_tokenizer.chat_template = chat_template - outlines_model = outlines.models.transformers.from_transformers( # type: ignore[reportUnknownMemberType] - hf_model, # type: ignore[reportUnknownArgumentType] - hf_tokenizer, # type: ignore + outlines_model = outlines.models.transformers.from_transformers( + hf_model, + hf_tokenizer, ) return OutlinesModel(outlines_model, provider=OutlinesProvider()) @@ -143,9 +143,9 @@ def transformers_multimodal_model() -> OutlinesModel: device_map='cpu', ) hf_processor = transformers.AutoProcessor.from_pretrained('trl-internal-testing/tiny-LlavaForConditionalGeneration') - outlines_model = outlines.models.transformers.from_transformers( # type: ignore[reportUnknownMemberType] + outlines_model = outlines.models.transformers.from_transformers( hf_model, - hf_processor, # type: ignore + hf_processor, ) return OutlinesModel(outlines_model, provider=OutlinesProvider()) From d627aa295224344dd35facf1d94dbec5ed352295 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 13:30:55 +0000 Subject: [PATCH 11/19] add linter rules again --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 695fec9e1c..6bee60939d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,7 +187,7 @@ quote-style = "single" "examples/**/*.py" = ["D101", "D103"] "tests/**/*.py" = ["D"] "docs/**/*.py" = ["D"] -"stubs/**/*.pyi" = ["F401", "PYI044", "PYI035", "ANN401"] +"stubs/**/*.pyi" = ["F401", "ANN401"] [tool.pyright] stubPath = "stubs" From 6f117d72d39d75f9c631f02e81a8f36e83525321 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 13:40:55 +0000 Subject: [PATCH 12/19] ignore rules again --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6bee60939d..695fec9e1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,7 +187,7 @@ quote-style = "single" "examples/**/*.py" = ["D101", "D103"] "tests/**/*.py" = ["D"] "docs/**/*.py" = ["D"] -"stubs/**/*.pyi" = ["F401", "ANN401"] +"stubs/**/*.pyi" = ["F401", "PYI044", "PYI035", "ANN401"] [tool.pyright] stubPath = "stubs" From 3b649310f29e51e59b3cc7a893698f5a83b5cd8d Mon Sep 17 00:00:00 2001 From: lars20070 Date: Sun, 16 Nov 2025 15:14:56 +0000 Subject: [PATCH 13/19] Trigger CI From a8554f07ea51d6ce55ce8a3f57b01b8d8ed84fb2 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Wed, 19 Nov 2025 10:26:41 +0000 Subject: [PATCH 14/19] fix stub inconsistencies and duplications --- stubs/mlx/__init__.pyi | 4 ++++ stubs/mlx_lm.pyi | 2 +- stubs/transformers/tokenization_utils.pyi | 2 -- stubs/vllm/sampling_params.pyi | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/stubs/mlx/__init__.pyi b/stubs/mlx/__init__.pyi index 43e14e0711..e6a4cfec2a 100644 --- a/stubs/mlx/__init__.pyi +++ b/stubs/mlx/__init__.pyi @@ -1,4 +1,8 @@ from typing import Any +from . import nn + # mlx is imported as a package, primarily for mlx.nn __all__: list[str] = [] + +nn: Any diff --git a/stubs/mlx_lm.pyi b/stubs/mlx_lm.pyi index 50d8e42fbc..ea23cb4207 100644 --- a/stubs/mlx_lm.pyi +++ b/stubs/mlx_lm.pyi @@ -3,5 +3,5 @@ from typing import Any from mlx.nn import Module from transformers.tokenization_utils import PreTrainedTokenizer -def load(model_path: str) -> tuple[Module, PreTrainedTokenizer]: ... +def load(model_path: str | None = None, *args: Any, **kwargs: Any) -> tuple[Module, PreTrainedTokenizer]: ... def generate_step(*args: Any, **kwargs: Any) -> Any: ... diff --git a/stubs/transformers/tokenization_utils.pyi b/stubs/transformers/tokenization_utils.pyi index b8c826f3bb..5afbd67b79 100644 --- a/stubs/transformers/tokenization_utils.pyi +++ b/stubs/transformers/tokenization_utils.pyi @@ -4,5 +4,3 @@ class PreTrainedTokenizer: chat_template: str | None def __init__(self, *args: Any, **kwargs: Any) -> None: ... - -class ProcessorMixin: ... diff --git a/stubs/vllm/sampling_params.pyi b/stubs/vllm/sampling_params.pyi index 71a25b14d2..651c824162 100644 --- a/stubs/vllm/sampling_params.pyi +++ b/stubs/vllm/sampling_params.pyi @@ -8,7 +8,7 @@ class SamplingParams: presence_penalty: float | None frequency_penalty: float | None logit_bias: dict[int, float] | None - extra_body: dict[str, Any] | None + extra_args: dict[str, Any] | None def __init__( self, @@ -19,7 +19,7 @@ class SamplingParams: presence_penalty: float | None = None, frequency_penalty: float | None = None, logit_bias: dict[int, float] | None = None, - extra_body: dict[str, Any] | None = None, + extra_args: dict[str, Any] | None = None, *args: Any, **kwargs: Any, ) -> None: ... From 5cc2e78f443fe685637bcbf2f8af99b142e378b7 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Wed, 19 Nov 2025 11:47:42 +0000 Subject: [PATCH 15/19] docu for stubs --- stubs/README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 stubs/README.md diff --git a/stubs/README.md b/stubs/README.md new file mode 100644 index 0000000000..7b90a80b3e --- /dev/null +++ b/stubs/README.md @@ -0,0 +1,26 @@ +Stub files (`*.pyi`) contain type hints used only by type checkers, not at +runtime. They were introduced in +[PEP 484](https://peps.python.org/pep-0484/#stub-files). For example, the +[`typeshed`](https://github.com/python/typeshed) repository maintains a +collection of such stubs for the Python standard library and some third-party +libraries. + +The `./stubs` folder contains type information only for the parts of third-party +dependencies used in the `pydantic-ai` codebase. These stubs must be manually +maintained. When a dependency's API changes, both the codebase and the stubs +need to be updated. There are two ways to update the stubs: + +(1) **Manual update:** Check the dependency's source code and copy the type +information to `./stubs`. Take for example the `from_pretrained()` method of the +`Llama` class in `llama-cpp-python`. The +[source code](https://github.com/abetlen/llama-cpp-python/blob/main/llama_cpp/llama.py#L2240) +contains the type information that is copied to `./stubs/llama_cpp.pyi`. This +eliminates the need for `# type: ignore` comments in the codebase. + +(2) **Update with AI coding assistants:** Most dependencies maintain `llms.txt` +and `llms-full.txt` files with their documentation. This information is compiled +by [Context7](https://context7.com). For example, the `llama-cpp-python` library +is documented [here](https://github.com/abetlen/llama-cpp-python). MCP servers +such as [this one by Upstash](https://github.com/upstash/context7) provide AI +coding assistants access to Context7. AI coding assistants such as VS Code +Copilot or Cursor can reliably generate and update the stubs. From 7c11f0936a8ff39539327c42f92ed51125b58456 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Wed, 19 Nov 2025 14:09:55 +0000 Subject: [PATCH 16/19] further stubs for outlines --- stubs/mlx/__init__.pyi | 2 -- stubs/outlines/inputs.pyi | 18 ++++++++++++++++++ stubs/outlines/models/base.pyi | 2 +- stubs/outlines/types/__init__.pyi | 3 +++ stubs/outlines/types/dsl.pyi | 4 ++++ 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 stubs/outlines/inputs.pyi create mode 100644 stubs/outlines/types/__init__.pyi create mode 100644 stubs/outlines/types/dsl.pyi diff --git a/stubs/mlx/__init__.pyi b/stubs/mlx/__init__.pyi index e6a4cfec2a..9299184781 100644 --- a/stubs/mlx/__init__.pyi +++ b/stubs/mlx/__init__.pyi @@ -4,5 +4,3 @@ from . import nn # mlx is imported as a package, primarily for mlx.nn __all__: list[str] = [] - -nn: Any diff --git a/stubs/outlines/inputs.pyi b/stubs/outlines/inputs.pyi new file mode 100644 index 0000000000..df1a26e410 --- /dev/null +++ b/stubs/outlines/inputs.pyi @@ -0,0 +1,18 @@ +from __future__ import annotations + +from collections.abc import Sequence +from typing import Any + +from PIL.Image import Image as PILImage + +class Chat: + def __init__(self, messages: list[dict[str, Any]] | None = None) -> None: ... + def add_system_message(self, content: str) -> None: ... + def add_user_message(self, content: str | Sequence[str | Image]) -> None: ... + def add_assistant_message(self, content: str | list[str | Image]) -> None: ... + def extend(self, messages: list[dict[str, Any]]) -> None: ... + def append(self, message: dict[str, Any]) -> None: ... + def pop(self) -> dict[str, Any] | None: ... + +class Image: + def __init__(self, image: PILImage.Image) -> None: ... diff --git a/stubs/outlines/models/base.pyi b/stubs/outlines/models/base.pyi index e7b8063089..4bb8329e8d 100644 --- a/stubs/outlines/models/base.pyi +++ b/stubs/outlines/models/base.pyi @@ -5,6 +5,6 @@ class Model: def __call__(self, *args: Any, **kwargs: Any) -> Any: ... def stream(self, *args: Any, **kwargs: Any) -> Iterable[Any]: ... -class AsyncModel(Model): +class AsyncModel: async def __call__(self, *args: Any, **kwargs: Any) -> Any: ... def stream(self, *args: Any, **kwargs: Any) -> AsyncIterable[Any]: ... diff --git a/stubs/outlines/types/__init__.pyi b/stubs/outlines/types/__init__.pyi new file mode 100644 index 0000000000..041e97f748 --- /dev/null +++ b/stubs/outlines/types/__init__.pyi @@ -0,0 +1,3 @@ +from typing import Any + +__all__: list[str] = [] diff --git a/stubs/outlines/types/dsl.pyi b/stubs/outlines/types/dsl.pyi new file mode 100644 index 0000000000..b3e108548f --- /dev/null +++ b/stubs/outlines/types/dsl.pyi @@ -0,0 +1,4 @@ +from typing import Any + +class JsonSchema: + def __init__(self, schema: dict[str, Any]) -> None: ... From e34387643eb22d55882d4881fcb7ae13c2f29074 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Wed, 19 Nov 2025 14:34:27 +0000 Subject: [PATCH 17/19] fix error in outlines stub --- stubs/outlines/inputs.pyi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/stubs/outlines/inputs.pyi b/stubs/outlines/inputs.pyi index df1a26e410..467657a6d4 100644 --- a/stubs/outlines/inputs.pyi +++ b/stubs/outlines/inputs.pyi @@ -5,14 +5,22 @@ from typing import Any from PIL.Image import Image as PILImage + class Chat: - def __init__(self, messages: list[dict[str, Any]] | None = None) -> None: ... + def __init__( + self, messages: list[dict[str, Any]] | None = None) -> None: ... + def add_system_message(self, content: str) -> None: ... - def add_user_message(self, content: str | Sequence[str | Image]) -> None: ... - def add_assistant_message(self, content: str | list[str | Image]) -> None: ... + + def add_user_message(self, content: str | + Sequence[str | Image]) -> None: ... + def add_assistant_message( + self, content: str | list[str | Image]) -> None: ... + def extend(self, messages: list[dict[str, Any]]) -> None: ... def append(self, message: dict[str, Any]) -> None: ... def pop(self) -> dict[str, Any] | None: ... + class Image: - def __init__(self, image: PILImage.Image) -> None: ... + def __init__(self, image: PILImage) -> None: ... From ca13700a2701bf056c4d45cef58a09b4be6b3212 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Wed, 19 Nov 2025 16:30:15 +0100 Subject: [PATCH 18/19] fix linter --- stubs/outlines/inputs.pyi | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/stubs/outlines/inputs.pyi b/stubs/outlines/inputs.pyi index 467657a6d4..a62efbc8fa 100644 --- a/stubs/outlines/inputs.pyi +++ b/stubs/outlines/inputs.pyi @@ -5,22 +5,14 @@ from typing import Any from PIL.Image import Image as PILImage - class Chat: - def __init__( - self, messages: list[dict[str, Any]] | None = None) -> None: ... - + def __init__(self, messages: list[dict[str, Any]] | None = None) -> None: ... def add_system_message(self, content: str) -> None: ... - - def add_user_message(self, content: str | - Sequence[str | Image]) -> None: ... - def add_assistant_message( - self, content: str | list[str | Image]) -> None: ... - + def add_user_message(self, content: str | Sequence[str | Image]) -> None: ... + def add_assistant_message(self, content: str | list[str | Image]) -> None: ... def extend(self, messages: list[dict[str, Any]]) -> None: ... def append(self, message: dict[str, Any]) -> None: ... def pop(self) -> dict[str, Any] | None: ... - class Image: def __init__(self, image: PILImage) -> None: ... From bfeee987daae1660ded9517f47225f58e9dd9bc3 Mon Sep 17 00:00:00 2001 From: lars20070 Date: Wed, 19 Nov 2025 16:00:37 +0000 Subject: [PATCH 19/19] check the stubs --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 4e191a95c2..3a46e6e1d2 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ typecheck-pyright: .PHONY: typecheck-mypy typecheck-mypy: uv run mypy + uv run mypy stubs/ --strict .PHONY: typecheck typecheck: typecheck-pyright ## Run static type checking