From 4828a85ab007080342ae0ee8478dcf0f0342be80 Mon Sep 17 00:00:00 2001 From: Shahroz Ahmad <97090106+ishahroz@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:57:25 -0300 Subject: [PATCH 01/30] feat(core): add `web_search` in OpenAI tools list (#32738) --- libs/core/langchain_core/utils/function_calling.py | 1 + .../openai/langchain_openai/chat_models/base.py | 3 ++- libs/partners/openai/pyproject.toml | 2 +- libs/partners/openai/uv.lock | 10 +++++----- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index 4775a06c5c5..acc50e7acdd 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -515,6 +515,7 @@ _WellKnownOpenAITools = ( "mcp", "image_generation", "web_search_preview", + "web_search", ) diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index afdcf47445b..7965e45d922 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -123,6 +123,7 @@ global_ssl_context = ssl.create_default_context(cafile=certifi.where()) WellKnownTools = ( "file_search", "web_search_preview", + "web_search", "computer_use_preview", "code_interpreter", "mcp", @@ -2374,7 +2375,7 @@ class ChatOpenAI(BaseChatOpenAI): # type: ignore[override] llm = ChatOpenAI(model="gpt-4.1-mini", output_version="responses/v1") - tool = {"type": "web_search_preview"} + tool = {"type": "web_search"} llm_with_tools = llm.bind_tools([tool]) response = llm_with_tools.invoke( diff --git a/libs/partners/openai/pyproject.toml b/libs/partners/openai/pyproject.toml index 7707dd1c4c6..226a2e73137 100644 --- a/libs/partners/openai/pyproject.toml +++ b/libs/partners/openai/pyproject.toml @@ -8,7 +8,7 @@ license = { text = "MIT" } requires-python = ">=3.9" dependencies = [ "langchain-core<1.0.0,>=0.3.74", - "openai<2.0.0,>=1.99.9", + "openai<2.0.0,>=1.104.2", "tiktoken<1,>=0.7", ] name = "langchain-openai" diff --git a/libs/partners/openai/uv.lock b/libs/partners/openai/uv.lock index 9b39b22ea2d..027bda7fb49 100644 --- a/libs/partners/openai/uv.lock +++ b/libs/partners/openai/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.9" resolution-markers = [ "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", @@ -588,7 +588,7 @@ typing = [ [package.metadata] requires-dist = [ { name = "langchain-core", editable = "../../core" }, - { name = "openai", specifier = ">=1.99.9,<2.0.0" }, + { name = "openai", specifier = ">=1.104.2,<2.0.0" }, { name = "tiktoken", specifier = ">=0.7,<1" }, ] @@ -1001,7 +1001,7 @@ wheels = [ [[package]] name = "openai" -version = "1.101.0" +version = "1.104.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1013,9 +1013,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/7c/eaf06b62281f5ca4f774c4cff066e6ddfd6a027e0ac791be16acec3a95e3/openai-1.101.0.tar.gz", hash = "sha256:29f56df2236069686e64aca0e13c24a4ec310545afb25ef7da2ab1a18523f22d", size = 518415, upload-time = "2025-08-21T21:11:01.645Z" } +sdist = { url = "https://files.pythonhosted.org/packages/94/dc/965b3528ed0435b717acca45e2541d94bd827c0520ce172366323c9edcab/openai-1.104.2.tar.gz", hash = "sha256:9b582ead9dd208753f89dae8e36b6548c6ada076e87ba3db36630e29239661ab", size = 557160, upload-time = "2025-09-02T21:42:31.054Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/a6/0e39baa335bbd1c66c7e0a41dbbec10c5a15ab95c1344e7f7beb28eee65a/openai-1.101.0-py3-none-any.whl", hash = "sha256:6539a446cce154f8d9fb42757acdfd3ed9357ab0d34fcac11096c461da87133b", size = 810772, upload-time = "2025-08-21T21:10:59.215Z" }, + { url = "https://files.pythonhosted.org/packages/46/9c/d0b56971e5584aea338bb00d3ca96a7f6694dff77006581b21cd773497ce/openai-1.104.2-py3-none-any.whl", hash = "sha256:0148951da12ea651f890ef38f8adef75b78c053dba37ea2bdba857c8945860d4", size = 928160, upload-time = "2025-09-02T21:42:28.678Z" }, ] [[package]] From ad26c892ea1f9fd5fcb8e1da370e72829f6e8d20 Mon Sep 17 00:00:00 2001 From: Martin Meier-Zavodsky <40723691+bephenomenal@users.noreply.github.com> Date: Wed, 3 Sep 2025 21:22:46 +0200 Subject: [PATCH 02/30] docs(langchain): update evaluation tutorial link (#32796) **Description** This PR updates the evaluation tutorial link for LangSmith to the new official docs location. **Issue** N/A **Dependencies** None --- docs/docs/tutorials/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/tutorials/index.mdx b/docs/docs/tutorials/index.mdx index c7603e61ab5..c960903c358 100644 --- a/docs/docs/tutorials/index.mdx +++ b/docs/docs/tutorials/index.mdx @@ -44,4 +44,4 @@ You can peruse [LangSmith tutorials here](https://docs.smith.langchain.com/). LangSmith helps you evaluate the performance of your LLM applications. The tutorial below is a great way to get started: -- [Evaluate your LLM application](https://docs.smith.langchain.com/tutorials/Developers/evaluation) +- [Evaluate your LLM application](https://docs.langchain.com/langsmith/evaluate-llm-application) From 36037c9251321d1feb69fd8a525d45af4d82b823 Mon Sep 17 00:00:00 2001 From: JING <124344487+starchou6@users.noreply.github.com> Date: Thu, 4 Sep 2025 04:25:13 +0900 Subject: [PATCH 03/30] fix(docs): update Anthropic model name and add version warnings (#32807) **Description:** This PR fixes the broken Anthropic model example in the documentation introduction page and adds a comment field to display model version warnings in code blocks. The changes ensure that users can successfully run the example code and are reminded to check for the latest model versions. **Issue:** https://github.com/langchain-ai/langchain/issues/32806 **Changes made:** - Update Anthropic model from broken "claude-3-5-sonnet-latest" to working "claude-3-7-sonnet-20250219" - Add comment field to display model version warnings in code blocks - Improve user experience by providing working examples and version guidance **Dependencies:** None required --- docs/src/theme/ChatModelTabs.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/src/theme/ChatModelTabs.js b/docs/src/theme/ChatModelTabs.js index c584baaaacf..5fb83fdd681 100644 --- a/docs/src/theme/ChatModelTabs.js +++ b/docs/src/theme/ChatModelTabs.js @@ -118,7 +118,8 @@ export default function ChatModelTabs(props) { { value: "anthropic", label: "Anthropic", - model: "claude-3-5-sonnet-latest", + model: "claude-3-7-sonnet-20250219", + comment: "# Note: Model versions may become outdated. Check https://docs.anthropic.com/en/docs/models-overview for latest versions", apiKeyName: "ANTHROPIC_API_KEY", packageName: "langchain[anthropic]", }, @@ -269,6 +270,9 @@ if not os.environ.get("${selectedTabItem.apiKeyName}"): ${llmVarName} = init_chat_model("${selectedTabItem.model}", model_provider="${selectedTabItem.value}"${selectedTabItem?.kwargs ? `, ${selectedTabItem.kwargs}` : ""})`; + // Add comment if available + const commentText = selectedTabItem?.comment ? selectedTabItem.comment + "\n\n" : ""; + return (
- {apiKeyText ? apiKeyText + "\n\n" + initModelText : initModelText} + {apiKeyText ? apiKeyText + "\n\n" + commentText + initModelText : commentText + initModelText}
); From 86fa34f3ebe284b51d7f2476787f26367105a8d1 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Wed, 3 Sep 2025 21:26:17 +0200 Subject: [PATCH 04/30] chore(langchain): add ruff rules D for `langchain_v1` (#32808) --- .../langchain/agents/react_agent.py | 2 + .../langchain/chat_models/__init__.py | 2 + .../langchain/chat_models/base.py | 2 + .../langchain/documents/__init__.py | 2 + .../langchain/embeddings/__init__.py | 2 + .../langchain_v1/langchain/embeddings/base.py | 2 + .../langchain/storage/encoder_backed.py | 2 + .../langchain/storage/exceptions.py | 2 + libs/langchain_v1/langchain/tools/__init__.py | 2 + libs/langchain_v1/pyproject.toml | 7 +-- .../cache/fake_embeddings.py | 34 +++++++----- libs/langchain_v1/uv.lock | 52 +++++++++---------- 12 files changed, 66 insertions(+), 45 deletions(-) diff --git a/libs/langchain_v1/langchain/agents/react_agent.py b/libs/langchain_v1/langchain/agents/react_agent.py index a0a33681545..5bce0f84c0d 100644 --- a/libs/langchain_v1/langchain/agents/react_agent.py +++ b/libs/langchain_v1/langchain/agents/react_agent.py @@ -1,3 +1,5 @@ +"""React agent implementation.""" + from __future__ import annotations import inspect diff --git a/libs/langchain_v1/langchain/chat_models/__init__.py b/libs/langchain_v1/langchain/chat_models/__init__.py index 166cf430a12..324c590865b 100644 --- a/libs/langchain_v1/langchain/chat_models/__init__.py +++ b/libs/langchain_v1/langchain/chat_models/__init__.py @@ -1,3 +1,5 @@ +"""Chat models.""" + from langchain_core.language_models import BaseChatModel from langchain.chat_models.base import init_chat_model diff --git a/libs/langchain_v1/langchain/chat_models/base.py b/libs/langchain_v1/langchain/chat_models/base.py index f9ae98e4368..fc337f0718d 100644 --- a/libs/langchain_v1/langchain/chat_models/base.py +++ b/libs/langchain_v1/langchain/chat_models/base.py @@ -1,3 +1,5 @@ +"""Factory functions for chat models.""" + from __future__ import annotations import warnings diff --git a/libs/langchain_v1/langchain/documents/__init__.py b/libs/langchain_v1/langchain/documents/__init__.py index 6450cfeef07..dcc14ce68b5 100644 --- a/libs/langchain_v1/langchain/documents/__init__.py +++ b/libs/langchain_v1/langchain/documents/__init__.py @@ -1,3 +1,5 @@ +"""Document.""" + from langchain_core.documents import Document __all__ = [ diff --git a/libs/langchain_v1/langchain/embeddings/__init__.py b/libs/langchain_v1/langchain/embeddings/__init__.py index a7d78087168..84c453a9f60 100644 --- a/libs/langchain_v1/langchain/embeddings/__init__.py +++ b/libs/langchain_v1/langchain/embeddings/__init__.py @@ -1,3 +1,5 @@ +"""Embeddings.""" + from langchain_core.embeddings import Embeddings from langchain.embeddings.base import init_embeddings diff --git a/libs/langchain_v1/langchain/embeddings/base.py b/libs/langchain_v1/langchain/embeddings/base.py index 1b3383474aa..e4ebe301e65 100644 --- a/libs/langchain_v1/langchain/embeddings/base.py +++ b/libs/langchain_v1/langchain/embeddings/base.py @@ -1,3 +1,5 @@ +"""Factory functions for embeddings.""" + import functools from importlib import util from typing import Any, Union diff --git a/libs/langchain_v1/langchain/storage/encoder_backed.py b/libs/langchain_v1/langchain/storage/encoder_backed.py index b2f4be7b9f3..39b567225e4 100644 --- a/libs/langchain_v1/langchain/storage/encoder_backed.py +++ b/libs/langchain_v1/langchain/storage/encoder_backed.py @@ -1,3 +1,5 @@ +"""Encoder-backed store implementation.""" + from collections.abc import AsyncIterator, Callable, Iterator, Sequence from typing import ( Any, diff --git a/libs/langchain_v1/langchain/storage/exceptions.py b/libs/langchain_v1/langchain/storage/exceptions.py index 82d7c8a2fa2..74d2a43c531 100644 --- a/libs/langchain_v1/langchain/storage/exceptions.py +++ b/libs/langchain_v1/langchain/storage/exceptions.py @@ -1,3 +1,5 @@ +"""Store exceptions.""" + from langchain_core.stores import InvalidKeyException __all__ = ["InvalidKeyException"] diff --git a/libs/langchain_v1/langchain/tools/__init__.py b/libs/langchain_v1/langchain/tools/__init__.py index 2831f5de4b7..f4b2e7c1495 100644 --- a/libs/langchain_v1/langchain/tools/__init__.py +++ b/libs/langchain_v1/langchain/tools/__init__.py @@ -1,3 +1,5 @@ +"""Tools.""" + from langchain_core.tools import ( BaseTool, InjectedToolArg, diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index 2c6539c90c3..85e39348e52 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -59,7 +59,7 @@ test = [ ] codespell = ["codespell<3.0.0,>=2.2.0"] lint = [ - "ruff>=0.12.2", + "ruff<0.13,>=0.12.11", "mypy>=1.15", ] typing = [ @@ -112,9 +112,6 @@ select = [ "ALL" ] ignore = [ - "D100", # pydocstyle: Missing docstring in public module - "D104", # pydocstyle: Missing docstring in public package - "D105", # pydocstyle: Missing docstring in magic method "COM812", # Messes with the formatter "ISC001", # Messes with the formatter "PERF203", # Rarely useful @@ -132,7 +129,7 @@ flake8-annotations.allow-star-arg-any = true [tool.ruff.lint.per-file-ignores] "tests/*" = [ - "D", # Documentation rules + "D1", # Documentation rules "PLC0415", # Imports should be at the top. Not always desirable for tests ] "langchain/agents/*" = [ diff --git a/libs/langchain_v1/tests/integration_tests/cache/fake_embeddings.py b/libs/langchain_v1/tests/integration_tests/cache/fake_embeddings.py index 9f318b60cfe..a07f3312a25 100644 --- a/libs/langchain_v1/tests/integration_tests/cache/fake_embeddings.py +++ b/libs/langchain_v1/tests/integration_tests/cache/fake_embeddings.py @@ -12,7 +12,9 @@ class FakeEmbeddings(Embeddings): def embed_documents(self, texts: list[str]) -> list[list[float]]: """Return simple embeddings. - Embeddings encode each text as its index.""" + + Embeddings encode each text as its index. + """ return [[1.0] * 9 + [float(i)] for i in range(len(texts))] async def aembed_documents(self, texts: list[str]) -> list[list[float]]: @@ -20,9 +22,11 @@ class FakeEmbeddings(Embeddings): def embed_query(self, text: str) -> list[float]: """Return constant query embeddings. + Embeddings are identical to embed_documents(texts)[0]. Distance to each text will be that text's index, - as it was passed to embed_documents.""" + as it was passed to embed_documents. + """ return [1.0] * 9 + [0.0] async def aembed_query(self, text: str) -> list[float]: @@ -30,8 +34,11 @@ class FakeEmbeddings(Embeddings): class ConsistentFakeEmbeddings(FakeEmbeddings): - """Fake embeddings which remember all the texts seen so far to return consistent - vectors for the same texts.""" + """Consistent fake embeddings. + + Fake embeddings which remember all the texts seen so far to return consistent + vectors for the same texts. + """ def __init__(self, dimensionality: int = 10) -> None: self.known_texts: list[str] = [] @@ -50,25 +57,24 @@ class ConsistentFakeEmbeddings(FakeEmbeddings): return out_vectors def embed_query(self, text: str) -> list[float]: - """Return consistent embeddings for the text, if seen before, or a constant - one if the text is unknown.""" + """Return consistent embeddings. + + Return consistent embeddings for the text, if seen before, or a constant + one if the text is unknown. + """ return self.embed_documents([text])[0] class AngularTwoDimensionalEmbeddings(Embeddings): - """ - From angles (as strings in units of pi) to unit embedding vectors on a circle. - """ + """From angles (as strings in units of pi) to unit embedding vectors on a circle.""" def embed_documents(self, texts: list[str]) -> list[list[float]]: - """ - Make a list of texts into a list of embedding vectors. - """ + """Make a list of texts into a list of embedding vectors.""" return [self.embed_query(text) for text in texts] def embed_query(self, text: str) -> list[float]: - """ - Convert input text to a 'vector' (list of floats). + """Convert input text to a 'vector' (list of floats). + If the text is a number, use it as the angle for the unit vector in units of pi. Any other input text becomes the singular result [0, 0] ! diff --git a/libs/langchain_v1/uv.lock b/libs/langchain_v1/uv.lock index c83d4e58083..911b2dc04b6 100644 --- a/libs/langchain_v1/uv.lock +++ b/libs/langchain_v1/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", @@ -1550,7 +1550,7 @@ provides-extras = ["anthropic", "openai", "azure-ai", "google-vertexai", "google codespell = [{ name = "codespell", specifier = ">=2.2.0,<3.0.0" }] lint = [ { name = "mypy", specifier = ">=1.15" }, - { name = "ruff", specifier = ">=0.12.2" }, + { name = "ruff", specifier = ">=0.12.11,<0.13" }, ] test = [ { name = "langchain-openai", editable = "../partners/openai" }, @@ -1819,7 +1819,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "langchain-core", editable = "../core" }, - { name = "openai", specifier = ">=1.99.9,<2.0.0" }, + { name = "openai", specifier = ">=1.104.2,<2.0.0" }, { name = "tiktoken", specifier = ">=0.7,<1" }, ] @@ -2462,7 +2462,7 @@ wheels = [ [[package]] name = "openai" -version = "1.102.0" +version = "1.105.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -2474,9 +2474,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/07/55/da5598ed5c6bdd9939633854049cddc5cbac0da938dfcfcb3c6b119c16c0/openai-1.102.0.tar.gz", hash = "sha256:2e0153bcd64a6523071e90211cbfca1f2bbc5ceedd0993ba932a5869f93b7fc9", size = 519027, upload-time = "2025-08-26T20:50:29.397Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/a9/c8c2dea8066a8f3079f69c242f7d0d75aaad4c4c3431da5b0df22a24e75d/openai-1.105.0.tar.gz", hash = "sha256:a68a47adce0506d34def22dd78a42cbb6cfecae1cf6a5fe37f38776d32bbb514", size = 557265, upload-time = "2025-09-03T14:14:08.586Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/0d/c9e7016d82c53c5b5e23e2bad36daebb8921ed44f69c0a985c6529a35106/openai-1.102.0-py3-none-any.whl", hash = "sha256:d751a7e95e222b5325306362ad02a7aa96e1fab3ed05b5888ce1c7ca63451345", size = 812015, upload-time = "2025-08-26T20:50:27.219Z" }, + { url = "https://files.pythonhosted.org/packages/51/01/186845829d3a3609bb5b474067959076244dd62540d3e336797319b13924/openai-1.105.0-py3-none-any.whl", hash = "sha256:3ad7635132b0705769ccae31ca7319f59ec0c7d09e94e5e713ce2d130e5b021f", size = 928203, upload-time = "2025-09-03T14:14:06.842Z" }, ] [[package]] @@ -3400,28 +3400,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.12.10" +version = "0.12.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3b/eb/8c073deb376e46ae767f4961390d17545e8535921d2f65101720ed8bd434/ruff-0.12.10.tar.gz", hash = "sha256:189ab65149d11ea69a2d775343adf5f49bb2426fc4780f65ee33b423ad2e47f9", size = 5310076, upload-time = "2025-08-21T18:23:22.595Z" } +sdist = { url = "https://files.pythonhosted.org/packages/de/55/16ab6a7d88d93001e1ae4c34cbdcfb376652d761799459ff27c1dc20f6fa/ruff-0.12.11.tar.gz", hash = "sha256:c6b09ae8426a65bbee5425b9d0b82796dbb07cb1af045743c79bfb163001165d", size = 5347103, upload-time = "2025-08-28T13:59:08.87Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/e7/560d049d15585d6c201f9eeacd2fd130def3741323e5ccf123786e0e3c95/ruff-0.12.10-py3-none-linux_armv6l.whl", hash = "sha256:8b593cb0fb55cc8692dac7b06deb29afda78c721c7ccfed22db941201b7b8f7b", size = 11935161, upload-time = "2025-08-21T18:22:26.965Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b0/ad2464922a1113c365d12b8f80ed70fcfb39764288ac77c995156080488d/ruff-0.12.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ebb7333a45d56efc7c110a46a69a1b32365d5c5161e7244aaf3aa20ce62399c1", size = 12660884, upload-time = "2025-08-21T18:22:30.925Z" }, - { url = "https://files.pythonhosted.org/packages/d7/f1/97f509b4108d7bae16c48389f54f005b62ce86712120fd8b2d8e88a7cb49/ruff-0.12.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d59e58586829f8e4a9920788f6efba97a13d1fa320b047814e8afede381c6839", size = 11872754, upload-time = "2025-08-21T18:22:34.035Z" }, - { url = "https://files.pythonhosted.org/packages/12/ad/44f606d243f744a75adc432275217296095101f83f966842063d78eee2d3/ruff-0.12.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:822d9677b560f1fdeab69b89d1f444bf5459da4aa04e06e766cf0121771ab844", size = 12092276, upload-time = "2025-08-21T18:22:36.764Z" }, - { url = "https://files.pythonhosted.org/packages/06/1f/ed6c265e199568010197909b25c896d66e4ef2c5e1c3808caf461f6f3579/ruff-0.12.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b4a64f4062a50c75019c61c7017ff598cb444984b638511f48539d3a1c98db", size = 11734700, upload-time = "2025-08-21T18:22:39.822Z" }, - { url = "https://files.pythonhosted.org/packages/63/c5/b21cde720f54a1d1db71538c0bc9b73dee4b563a7dd7d2e404914904d7f5/ruff-0.12.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c6f4064c69d2542029b2a61d39920c85240c39837599d7f2e32e80d36401d6e", size = 13468783, upload-time = "2025-08-21T18:22:42.559Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/39369e6ac7f2a1848f22fb0b00b690492f20811a1ac5c1fd1d2798329263/ruff-0.12.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:059e863ea3a9ade41407ad71c1de2badfbe01539117f38f763ba42a1206f7559", size = 14436642, upload-time = "2025-08-21T18:22:45.612Z" }, - { url = "https://files.pythonhosted.org/packages/e3/03/5da8cad4b0d5242a936eb203b58318016db44f5c5d351b07e3f5e211bb89/ruff-0.12.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1bef6161e297c68908b7218fa6e0e93e99a286e5ed9653d4be71e687dff101cf", size = 13859107, upload-time = "2025-08-21T18:22:48.886Z" }, - { url = "https://files.pythonhosted.org/packages/19/19/dd7273b69bf7f93a070c9cec9494a94048325ad18fdcf50114f07e6bf417/ruff-0.12.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4f1345fbf8fb0531cd722285b5f15af49b2932742fc96b633e883da8d841896b", size = 12886521, upload-time = "2025-08-21T18:22:51.567Z" }, - { url = "https://files.pythonhosted.org/packages/c0/1d/b4207ec35e7babaee62c462769e77457e26eb853fbdc877af29417033333/ruff-0.12.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f68433c4fbc63efbfa3ba5db31727db229fa4e61000f452c540474b03de52a9", size = 13097528, upload-time = "2025-08-21T18:22:54.609Z" }, - { url = "https://files.pythonhosted.org/packages/ff/00/58f7b873b21114456e880b75176af3490d7a2836033779ca42f50de3b47a/ruff-0.12.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:141ce3d88803c625257b8a6debf4a0473eb6eed9643a6189b68838b43e78165a", size = 13080443, upload-time = "2025-08-21T18:22:57.413Z" }, - { url = "https://files.pythonhosted.org/packages/12/8c/9e6660007fb10189ccb78a02b41691288038e51e4788bf49b0a60f740604/ruff-0.12.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f3fc21178cd44c98142ae7590f42ddcb587b8e09a3b849cbc84edb62ee95de60", size = 11896759, upload-time = "2025-08-21T18:23:00.473Z" }, - { url = "https://files.pythonhosted.org/packages/67/4c/6d092bb99ea9ea6ebda817a0e7ad886f42a58b4501a7e27cd97371d0ba54/ruff-0.12.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7d1a4e0bdfafcd2e3e235ecf50bf0176f74dd37902f241588ae1f6c827a36c56", size = 11701463, upload-time = "2025-08-21T18:23:03.211Z" }, - { url = "https://files.pythonhosted.org/packages/59/80/d982c55e91df981f3ab62559371380616c57ffd0172d96850280c2b04fa8/ruff-0.12.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e67d96827854f50b9e3e8327b031647e7bcc090dbe7bb11101a81a3a2cbf1cc9", size = 12691603, upload-time = "2025-08-21T18:23:06.935Z" }, - { url = "https://files.pythonhosted.org/packages/ad/37/63a9c788bbe0b0850611669ec6b8589838faf2f4f959647f2d3e320383ae/ruff-0.12.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ae479e1a18b439c59138f066ae79cc0f3ee250712a873d00dbafadaad9481e5b", size = 13164356, upload-time = "2025-08-21T18:23:10.225Z" }, - { url = "https://files.pythonhosted.org/packages/47/d4/1aaa7fb201a74181989970ebccd12f88c0fc074777027e2a21de5a90657e/ruff-0.12.10-py3-none-win32.whl", hash = "sha256:9de785e95dc2f09846c5e6e1d3a3d32ecd0b283a979898ad427a9be7be22b266", size = 11896089, upload-time = "2025-08-21T18:23:14.232Z" }, - { url = "https://files.pythonhosted.org/packages/ad/14/2ad38fd4037daab9e023456a4a40ed0154e9971f8d6aed41bdea390aabd9/ruff-0.12.10-py3-none-win_amd64.whl", hash = "sha256:7837eca8787f076f67aba2ca559cefd9c5cbc3a9852fd66186f4201b87c1563e", size = 13004616, upload-time = "2025-08-21T18:23:17.422Z" }, - { url = "https://files.pythonhosted.org/packages/24/3c/21cf283d67af33a8e6ed242396863af195a8a6134ec581524fd22b9811b6/ruff-0.12.10-py3-none-win_arm64.whl", hash = "sha256:cc138cc06ed9d4bfa9d667a65af7172b47840e1a98b02ce7011c391e54635ffc", size = 12074225, upload-time = "2025-08-21T18:23:20.137Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a2/3b3573e474de39a7a475f3fbaf36a25600bfeb238e1a90392799163b64a0/ruff-0.12.11-py3-none-linux_armv6l.whl", hash = "sha256:93fce71e1cac3a8bf9200e63a38ac5c078f3b6baebffb74ba5274fb2ab276065", size = 11979885, upload-time = "2025-08-28T13:58:26.654Z" }, + { url = "https://files.pythonhosted.org/packages/76/e4/235ad6d1785a2012d3ded2350fd9bc5c5af8c6f56820e696b0118dfe7d24/ruff-0.12.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8e33ac7b28c772440afa80cebb972ffd823621ded90404f29e5ab6d1e2d4b93", size = 12742364, upload-time = "2025-08-28T13:58:30.256Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0d/15b72c5fe6b1e402a543aa9d8960e0a7e19dfb079f5b0b424db48b7febab/ruff-0.12.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d69fb9d4937aa19adb2e9f058bc4fbfe986c2040acb1a4a9747734834eaa0bfd", size = 11920111, upload-time = "2025-08-28T13:58:33.677Z" }, + { url = "https://files.pythonhosted.org/packages/3e/c0/f66339d7893798ad3e17fa5a1e587d6fd9806f7c1c062b63f8b09dda6702/ruff-0.12.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411954eca8464595077a93e580e2918d0a01a19317af0a72132283e28ae21bee", size = 12160060, upload-time = "2025-08-28T13:58:35.74Z" }, + { url = "https://files.pythonhosted.org/packages/03/69/9870368326db26f20c946205fb2d0008988aea552dbaec35fbacbb46efaa/ruff-0.12.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a2c0a2e1a450f387bf2c6237c727dd22191ae8c00e448e0672d624b2bbd7fb0", size = 11799848, upload-time = "2025-08-28T13:58:38.051Z" }, + { url = "https://files.pythonhosted.org/packages/25/8c/dd2c7f990e9b3a8a55eee09d4e675027d31727ce33cdb29eab32d025bdc9/ruff-0.12.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ca4c3a7f937725fd2413c0e884b5248a19369ab9bdd850b5781348ba283f644", size = 13536288, upload-time = "2025-08-28T13:58:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/7a/30/d5496fa09aba59b5e01ea76775a4c8897b13055884f56f1c35a4194c2297/ruff-0.12.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4d1df0098124006f6a66ecf3581a7f7e754c4df7644b2e6704cd7ca80ff95211", size = 14490633, upload-time = "2025-08-28T13:58:42.285Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2f/81f998180ad53445d403c386549d6946d0748e536d58fce5b5e173511183/ruff-0.12.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a8dd5f230efc99a24ace3b77e3555d3fbc0343aeed3fc84c8d89e75ab2ff793", size = 13888430, upload-time = "2025-08-28T13:58:44.641Z" }, + { url = "https://files.pythonhosted.org/packages/87/71/23a0d1d5892a377478c61dbbcffe82a3476b050f38b5162171942a029ef3/ruff-0.12.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc75533039d0ed04cd33fb8ca9ac9620b99672fe7ff1533b6402206901c34ee", size = 12913133, upload-time = "2025-08-28T13:58:47.039Z" }, + { url = "https://files.pythonhosted.org/packages/80/22/3c6cef96627f89b344c933781ed38329bfb87737aa438f15da95907cbfd5/ruff-0.12.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc58f9266d62c6eccc75261a665f26b4ef64840887fc6cbc552ce5b29f96cc8", size = 13169082, upload-time = "2025-08-28T13:58:49.157Z" }, + { url = "https://files.pythonhosted.org/packages/05/b5/68b3ff96160d8b49e8dd10785ff3186be18fd650d356036a3770386e6c7f/ruff-0.12.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a0113bd6eafd545146440225fe60b4e9489f59eb5f5f107acd715ba5f0b3d2f", size = 13139490, upload-time = "2025-08-28T13:58:51.593Z" }, + { url = "https://files.pythonhosted.org/packages/59/b9/050a3278ecd558f74f7ee016fbdf10591d50119df8d5f5da45a22c6afafc/ruff-0.12.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0d737b4059d66295c3ea5720e6efc152623bb83fde5444209b69cd33a53e2000", size = 11958928, upload-time = "2025-08-28T13:58:53.943Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bc/93be37347db854806904a43b0493af8d6873472dfb4b4b8cbb27786eb651/ruff-0.12.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:916fc5defee32dbc1fc1650b576a8fed68f5e8256e2180d4d9855aea43d6aab2", size = 11764513, upload-time = "2025-08-28T13:58:55.976Z" }, + { url = "https://files.pythonhosted.org/packages/7a/a1/1471751e2015a81fd8e166cd311456c11df74c7e8769d4aabfbc7584c7ac/ruff-0.12.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c984f07d7adb42d3ded5be894fb4007f30f82c87559438b4879fe7aa08c62b39", size = 12745154, upload-time = "2025-08-28T13:58:58.16Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/2542b14890d0f4872dd81b7b2a6aed3ac1786fae1ce9b17e11e6df9e31e3/ruff-0.12.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e07fbb89f2e9249f219d88331c833860489b49cdf4b032b8e4432e9b13e8a4b9", size = 13227653, upload-time = "2025-08-28T13:59:00.276Z" }, + { url = "https://files.pythonhosted.org/packages/22/16/2fbfc61047dbfd009c58a28369a693a1484ad15441723be1cd7fe69bb679/ruff-0.12.11-py3-none-win32.whl", hash = "sha256:c792e8f597c9c756e9bcd4d87cf407a00b60af77078c96f7b6366ea2ce9ba9d3", size = 11944270, upload-time = "2025-08-28T13:59:02.347Z" }, + { url = "https://files.pythonhosted.org/packages/08/a5/34276984705bfe069cd383101c45077ee029c3fe3b28225bf67aa35f0647/ruff-0.12.11-py3-none-win_amd64.whl", hash = "sha256:a3283325960307915b6deb3576b96919ee89432ebd9c48771ca12ee8afe4a0fd", size = 13046600, upload-time = "2025-08-28T13:59:04.751Z" }, + { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290, upload-time = "2025-08-28T13:59:06.933Z" }, ] [[package]] From aa63de936659ea68ffcd788f3bd97215985b0e2c Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Wed, 3 Sep 2025 21:28:06 +0200 Subject: [PATCH 05/30] chore(langchain): cleanup `langchain_v1` mypy config (#32809) Co-authored-by: Mason Daugherty --- libs/langchain_v1/pyproject.toml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index 85e39348e52..e5e7e7acd57 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -59,10 +59,10 @@ test = [ ] codespell = ["codespell<3.0.0,>=2.2.0"] lint = [ - "ruff<0.13,>=0.12.11", - "mypy>=1.15", + "ruff>=0.12.2", ] typing = [ + "mypy<0.18,>=1.17.1", "types-toml>=0.10.8.20240310", ] @@ -88,19 +88,14 @@ exclude = ["tests/integration_tests/examples/non-utf8-encoding.py"] line-length = 100 [tool.mypy] -strict = "True" -strict_bytes = "True" -ignore_missing_imports = "True" +strict = true +ignore_missing_imports = true enable_error_code = "deprecated" -report_deprecated_as_note = "True" exclude = ["tests/unit_tests/agents/*", "tests/integration_tests/agents/*"] # TODO: activate for 'strict' checking -disallow_untyped_calls = "False" -disallow_any_generics = "False" -disallow_untyped_decorators = "False" -warn_return_any = "False" -strict_equality = "False" +disallow_any_generics = false +warn_return_any = false [tool.codespell] skip = ".git,*.pdf,*.svg,*.pdf,*.yaml,*.ipynb,poetry.lock,*.min.js,*.css,package-lock.json,example_data,_dist,examples,*.trig" From 05a61f9508b6045c4c5ce73e132607fcd049301a Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Thu, 4 Sep 2025 17:51:08 +0200 Subject: [PATCH 06/30] fix(langchain): fix mypy versions in `langchain_v1` (#32816) --- libs/langchain_v1/pyproject.toml | 2 +- libs/langchain_v1/uv.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index e5e7e7acd57..ca1ccd37a5c 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -62,7 +62,7 @@ lint = [ "ruff>=0.12.2", ] typing = [ - "mypy<0.18,>=1.17.1", + "mypy<1.18,>=1.17.1", "types-toml>=0.10.8.20240310", ] diff --git a/libs/langchain_v1/uv.lock b/libs/langchain_v1/uv.lock index 911b2dc04b6..5cae5e0d6b3 100644 --- a/libs/langchain_v1/uv.lock +++ b/libs/langchain_v1/uv.lock @@ -1492,7 +1492,6 @@ codespell = [ { name = "codespell" }, ] lint = [ - { name = "mypy" }, { name = "ruff" }, ] test = [ @@ -1519,6 +1518,7 @@ test-integration = [ { name = "wrapt" }, ] typing = [ + { name = "mypy" }, { name = "types-toml" }, ] @@ -1548,10 +1548,7 @@ provides-extras = ["anthropic", "openai", "azure-ai", "google-vertexai", "google [package.metadata.requires-dev] codespell = [{ name = "codespell", specifier = ">=2.2.0,<3.0.0" }] -lint = [ - { name = "mypy", specifier = ">=1.15" }, - { name = "ruff", specifier = ">=0.12.11,<0.13" }, -] +lint = [{ name = "ruff", specifier = ">=0.12.2" }] test = [ { name = "langchain-openai", editable = "../partners/openai" }, { name = "langchain-tests", editable = "../standard-tests" }, @@ -1575,7 +1572,10 @@ test-integration = [ { name = "vcrpy", specifier = ">=7.0" }, { name = "wrapt", specifier = ">=1.15.0" }, ] -typing = [{ name = "types-toml", specifier = ">=0.10.8.20240310" }] +typing = [ + { name = "mypy", specifier = ">=1.17.1,<1.18" }, + { name = "types-toml", specifier = ">=0.10.8.20240310" }, +] [[package]] name = "langchain-anthropic" From bc91a4811c454511af50a2fbd95f48f024b5738a Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Thu, 4 Sep 2025 15:53:54 -0400 Subject: [PATCH 07/30] chore: update PR template (#32819) --- .github/PULL_REQUEST_TEMPLATE.md | 9 +++++---- docs/docs/contributing/how_to/code/guidelines.mdx | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b99fdd92cc3..b29dceac80d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,5 @@ +(Replace this entire block of text) + Thank you for contributing to LangChain! Follow these steps to mark your pull request as ready for review. **If any of these steps are not completed, your PR will not be considered for review.** - [ ] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION} @@ -9,14 +11,13 @@ Thank you for contributing to LangChain! Follow these steps to mark your pull re - feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, release - Allowed `{SCOPE}` values (optional): - core, cli, langchain, standard-tests, docs, anthropic, chroma, deepseek, exa, fireworks, groq, huggingface, mistralai, nomic, ollama, openai, perplexity, prompty, qdrant, xai - - Note: the `{DESCRIPTION}` must not start with an uppercase letter. + - *Note:* the `{DESCRIPTION}` must not start with an uppercase letter. - Once you've written the title, please delete this checklist item; do not include it in the PR. - [ ] **PR message**: ***Delete this entire checklist*** and replace with - **Description:** a description of the change. Include a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) if applicable to a relevant issue. - **Issue:** the issue # it fixes, if applicable (e.g. Fixes #123) - **Dependencies:** any dependencies required for this change - - **Twitter handle:** if your PR gets announced, and you'd like a mention, we'll gladly shout you out! - [ ] **Add tests and docs**: If you're adding a new integration, you must include: 1. A test for the integration, preferably unit tests that do not rely on network access, @@ -26,7 +27,7 @@ Thank you for contributing to LangChain! Follow these steps to mark your pull re Additional guidelines: -- Make sure optional dependencies are imported within a function. -- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests. - Most PRs should not touch more than one package. +- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests. - Changes should be backwards compatible. +- Make sure optional dependencies are imported within a function. diff --git a/docs/docs/contributing/how_to/code/guidelines.mdx b/docs/docs/contributing/how_to/code/guidelines.mdx index 54bf05238d1..0fcffe9c2e9 100644 --- a/docs/docs/contributing/how_to/code/guidelines.mdx +++ b/docs/docs/contributing/how_to/code/guidelines.mdx @@ -3,9 +3,9 @@ Here are some things to keep in mind for all types of contributions: - Follow the ["fork and pull request"](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project) workflow. -- Fill out the checked-in pull request template when opening pull requests. Note related issues and tag relevant maintainers. +- Fill out the checked-in pull request template when opening pull requests. Note related issues. - Ensure your PR passes formatting, linting, and testing checks before requesting a review. - - If you would like comments or feedback on your current progress, please open an issue or discussion and tag a maintainer. + - If you would like comments or feedback on your current progress, please open an issue or discussion. - See the sections on [Testing](setup.mdx#testing) and [Formatting and Linting](setup.mdx#formatting-and-linting) for how to run these checks locally. - Backwards compatibility is key. Your changes must not be breaking, except in case of critical bug and security fixes. - Look for duplicate PRs or issues that have already been opened before opening a new one. From 0b3af47335af43a4f02b0d2481baca6f76c9384a Mon Sep 17 00:00:00 2001 From: ScarletMercy <508965837@qq.com> Date: Fri, 5 Sep 2025 23:28:56 +0800 Subject: [PATCH 08/30] fix(docs): resolve malformed character in `tool_calling.ipynb` (#32825) **Description:** Remove a character in tool_calling.ipynb that causes a grammatical error Verification: Local docs build passed after fix **Issue:** None (direct hotfix for rendering issue identified during documentation review) **Dependencies:** None --- docs/docs/how_to/tool_calling.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how_to/tool_calling.ipynb b/docs/docs/how_to/tool_calling.ipynb index dbff12bf4cd..877a7c38426 100644 --- a/docs/docs/how_to/tool_calling.ipynb +++ b/docs/docs/how_to/tool_calling.ipynb @@ -55,7 +55,7 @@ "source": [ "## Defining tool schemas\n", "\n", - "For a model to be able to call tools, we need to pass in tool schemas that describe what the tool does and what it's arguments are. Chat models that support tool calling features implement a `.bind_tools()` method for passing tool schemas to the model. Tool schemas can be passed in as Python functions (with typehints and docstrings), Pydantic models, TypedDict classes, or LangChain [Tool objects](https://python.langchain.com/api_reference/core/tools/langchain_core.tools.base.BaseTool.html#basetool). Subsequent invocations of the model will pass in these tool schemas along with the prompt.\n", + "For a model to be able to call tools, we need to pass in tool schemas that describe what the tool does and what its arguments are. Chat models that support tool calling features implement a `.bind_tools()` method for passing tool schemas to the model. Tool schemas can be passed in as Python functions (with typehints and docstrings), Pydantic models, TypedDict classes, or LangChain [Tool objects](https://python.langchain.com/api_reference/core/tools/langchain_core.tools.base.BaseTool.html#basetool). Subsequent invocations of the model will pass in these tool schemas along with the prompt.\n", "\n", "### Python functions\n", "Our tool schemas can be Python functions:" From 4e39c164bb55ba5f877beb555a1797fc55c31baa Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Fri, 5 Sep 2025 14:28:58 -0400 Subject: [PATCH 09/30] fix(anthropic): remove beta header warning for TTL (#32832) No longer beta as of Aug 13 --- .../langchain_anthropic/chat_models.py | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/libs/partners/anthropic/langchain_anthropic/chat_models.py b/libs/partners/anthropic/langchain_anthropic/chat_models.py index 66f07c7ffd3..b1052a1f100 100644 --- a/libs/partners/anthropic/langchain_anthropic/chat_models.py +++ b/libs/partners/anthropic/langchain_anthropic/chat_models.py @@ -999,24 +999,27 @@ class ChatAnthropic(BaseChatModel): .. dropdown:: Extended caching - .. versionadded:: 0.3.15 - The cache lifetime is 5 minutes by default. If this is too short, you can - apply one hour caching by enabling the ``'extended-cache-ttl-2025-04-11'`` - beta header: + apply one hour caching by setting ``ttl`` to ``'1h'``. .. code-block:: python llm = ChatAnthropic( model="claude-3-7-sonnet-20250219", - betas=["extended-cache-ttl-2025-04-11"], ) - and specifying ``"cache_control": {"type": "ephemeral", "ttl": "1h"}``. + messages = [{ + "role": "user", + "content": [ + { + "type": "text", + "text": f"{long_text}", + "cache_control": {"type": "ephemeral", "ttl": "1h"}, + }, + ], + }] - .. important:: - Specifying a `ttl` key under `cache_control` will not work unless the - beta header is set! + response = llm.invoke(messages) Details of cached token counts will be included on the ``InputTokenDetails`` of response's ``usage_metadata``: @@ -1432,23 +1435,6 @@ class ChatAnthropic(BaseChatModel): # If cache_control is provided in kwargs, add it to last message # and content block. if "cache_control" in kwargs and formatted_messages: - cache_control = kwargs["cache_control"] - - # Validate TTL usage requires extended cache TTL beta header - if ( - isinstance(cache_control, dict) - and "ttl" in cache_control - and ( - not self.betas or "extended-cache-ttl-2025-04-11" not in self.betas - ) - ): - msg = ( - "Specifying a 'ttl' under 'cache_control' requires enabling " - "the 'extended-cache-ttl-2025-04-11' beta header. " - "Set betas=['extended-cache-ttl-2025-04-11'] when initializing " - "ChatAnthropic." - ) - warnings.warn(msg, stacklevel=2) if isinstance(formatted_messages[-1]["content"], list): formatted_messages[-1]["content"][-1]["cache_control"] = kwargs.pop( "cache_control" From 5bf0b218c8f992aba6626e9c80c6c1ab4d55520f Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Sun, 7 Sep 2025 22:53:19 +0200 Subject: [PATCH 10/30] chore(cli): fix some ruff preview rules (#32803) --- libs/cli/langchain_cli/namespaces/app.py | 4 +--- libs/cli/langchain_cli/namespaces/template.py | 2 +- libs/cli/langchain_cli/utils/git.py | 14 +++++++------- libs/cli/scripts/generate_migrations.py | 6 +++--- libs/cli/uv.lock | 18 +++--------------- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/libs/cli/langchain_cli/namespaces/app.py b/libs/cli/langchain_cli/namespaces/app.py index 2894b0013e9..557380dc9cb 100644 --- a/libs/cli/langchain_cli/namespaces/app.py +++ b/libs/cli/langchain_cli/namespaces/app.py @@ -72,9 +72,7 @@ def new( name_str = name pip_bool = bool(pip) # None should be false else: - name_str = ( - name if name else typer.prompt("What folder would you like to create?") - ) + name_str = name or typer.prompt("What folder would you like to create?") if not has_packages: package = [] package_prompt = "What package would you like to add? (leave blank to skip)" diff --git a/libs/cli/langchain_cli/namespaces/template.py b/libs/cli/langchain_cli/namespaces/template.py index 4c2c0272e7f..80b09722ce1 100644 --- a/libs/cli/langchain_cli/namespaces/template.py +++ b/libs/cli/langchain_cli/namespaces/template.py @@ -34,7 +34,7 @@ def new( package_name_split = computed_name.split("/") package_name = ( package_name_split[-2] - if len(package_name_split) > 1 and package_name_split[-1] == "" + if len(package_name_split) > 1 and not package_name_split[-1] else package_name_split[-1] ) module_name = re.sub( diff --git a/libs/cli/langchain_cli/utils/git.py b/libs/cli/langchain_cli/utils/git.py index d2ba1f4298c..0ca83eb6a4c 100644 --- a/libs/cli/langchain_cli/utils/git.py +++ b/libs/cli/langchain_cli/utils/git.py @@ -138,8 +138,8 @@ def parse_dependencies( if ( (dependencies and len(dependencies) != num_deps) or (api_path and len(api_path) != num_deps) - or (repo and len(repo) not in [1, num_deps]) - or (branch and len(branch) not in [1, num_deps]) + or (repo and len(repo) not in {1, num_deps}) + or (branch and len(branch) not in {1, num_deps}) ): msg = ( "Number of defined repos/branches/api_paths did not match the " @@ -151,15 +151,15 @@ def parse_dependencies( inner_repos = _list_arg_to_length(repo, num_deps) inner_branches = _list_arg_to_length(branch, num_deps) - return [ - parse_dependency_string(iter_dep, iter_repo, iter_branch, iter_api_path) - for iter_dep, iter_repo, iter_branch, iter_api_path in zip( + return list( + map( + parse_dependency_string, inner_deps, inner_repos, inner_branches, inner_api_paths, ) - ] + ) def _get_repo_path(gitstring: str, ref: Optional[str], repo_dir: Path) -> Path: @@ -167,7 +167,7 @@ def _get_repo_path(gitstring: str, ref: Optional[str], repo_dir: Path) -> Path: ref_str = ref if ref is not None else "" hashed = hashlib.sha256((f"{gitstring}:{ref_str}").encode()).hexdigest()[:8] - removed_protocol = gitstring.split("://")[-1] + removed_protocol = gitstring.split("://", maxsplit=1)[-1] removed_basename = re.split(r"[/:]", removed_protocol, maxsplit=1)[-1] removed_extras = removed_basename.split("#")[0] foldername = re.sub(r"\W", "_", removed_extras) diff --git a/libs/cli/scripts/generate_migrations.py b/libs/cli/scripts/generate_migrations.py index 5d01c7ae15f..2876ec487f2 100644 --- a/libs/cli/scripts/generate_migrations.py +++ b/libs/cli/scripts/generate_migrations.py @@ -73,7 +73,7 @@ def generic( else: dumped = dump_migrations_as_grit(name, migrations) - Path(output).write_text(dumped) + Path(output).write_text(dumped, encoding="utf-8") def handle_partner(pkg: str, output: Optional[str] = None) -> None: @@ -84,7 +84,7 @@ def handle_partner(pkg: str, output: Optional[str] = None) -> None: data = dump_migrations_as_grit(name, migrations) output_name = f"{name}.grit" if output is None else output if migrations: - Path(output_name).write_text(data) + Path(output_name).write_text(data, encoding="utf-8") click.secho(f"LangChain migration script saved to {output_name}") else: click.secho(f"No migrations found for {pkg}", fg="yellow") @@ -109,7 +109,7 @@ def json_to_grit(json_file: str) -> None: name = file.stem data = dump_migrations_as_grit(name, migrations) output_name = f"{name}.grit" - Path(output_name).write_text(data) + Path(output_name).write_text(data, encoding="utf-8") click.secho(f"GritQL migration script saved to {output_name}") diff --git a/libs/cli/uv.lock b/libs/cli/uv.lock index 5a7bdc3e182..efe67b1401e 100644 --- a/libs/cli/uv.lock +++ b/libs/cli/uv.lock @@ -629,18 +629,14 @@ typing = [ [[package]] name = "langchain-text-splitters" -version = "0.3.10" +version = "0.3.11" source = { editable = "../text-splitters" } dependencies = [ { name = "langchain-core" }, - { name = "pip" }, ] [package.metadata] -requires-dist = [ - { name = "langchain-core", editable = "../core" }, - { name = "pip", specifier = ">=25.2" }, -] +requires-dist = [{ name = "langchain-core", editable = "../core" }] [package.metadata.requires-dev] dev = [ @@ -662,6 +658,7 @@ test = [ { name = "pytest-xdist", specifier = ">=3.6.1,<4.0.0" }, ] test-integration = [ + { name = "en-core-web-sm", url = "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl" }, { name = "nltk", specifier = ">=3.9.1,<4.0.0" }, { name = "sentence-transformers", specifier = ">=3.0.1" }, { name = "spacy", specifier = ">=3.8.7,<4.0.0" }, @@ -887,15 +884,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] -[[package]] -name = "pip" -version = "25.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/16/650289cd3f43d5a2fadfd98c68bd1e1e7f2550a1a5326768cddfbcedb2c5/pip-25.2.tar.gz", hash = "sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2", size = 1840021, upload-time = "2025-07-30T21:50:15.401Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/3f/945ef7ab14dc4f9d7f40288d2df998d1837ee0888ec3659c813487572faa/pip-25.2-py3-none-any.whl", hash = "sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717", size = 1752557, upload-time = "2025-07-30T21:50:13.323Z" }, -] - [[package]] name = "pluggy" version = "1.5.0" From 6e2f46d04cb9a551c8821c3a9f7050f76d61bc9a Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Sun, 7 Sep 2025 21:10:57 -0400 Subject: [PATCH 11/30] feat(langchain): middleware support in `create_agent` (#32828) ## Overview Adding new `AgentMiddleware` primitive that supports `before_model`, `after_model`, and `prepare_model_request` hooks. This is very exciting! It makes our `create_agent` prebuilt much more extensible + capable. Still in alpha and subject to change. This is different than the initial [implementation](https://github.com/langchain-ai/langgraph/tree/nc/25aug/agent) in that it: * Fills in gaps w/ missing features, for ex -- new structured output, optionality of tools + system prompt, sync and async model requests, provider builtin tools * Exposes private state extensions for middleware, enabling things like model call tracking, etc * Middleware can register tools * Uses a `TypedDict` for `AgentState` -- dataclass subclassing is tricky w/ required values + required decorators * Addition of `model_settings` to `ModelRequest` so that we can pass through things to bind (like cache kwargs for anthropic middleware) ## TODOs ### top prio - [x] add middleware support to existing agent - [x] top prio middlewares - [x] summarization node - [x] HITL - [x] prompt caching other ones - [x] model call limits - [x] tool calling limits - [ ] usage (requires output state) ### secondary prio - [x] improve typing for state updates from middleware (not working right now w/ simple `AgentUpdate` and `AgentJump`, at least in Python) - [ ] add support for public state (input / output modifications via pregel channel mods) -- to be tackled in another PR - [x] testing! ### docs See https://github.com/langchain-ai/docs/pull/390 - [x] high level docs about middleware - [x] summarization node - [x] HITL - [x] prompt caching ## open questions Lots of open questions right now, many of them inlined as comments for the short term, will catalog some more significant ones here. --------- Co-authored-by: Harrison Chase --- .../langchain/agents/middleware/__init__.py | 15 + .../langchain/agents/middleware/_utils.py | 11 + .../agents/middleware/human_in_the_loop.py | 128 ++++ .../agents/middleware/prompt_caching.py | 57 ++ .../agents/middleware/summarization.py | 248 ++++++ .../langchain/agents/middleware/types.py | 78 ++ .../langchain/agents/middleware_agent.py | 554 ++++++++++++++ .../langchain/agents/react_agent.py | 26 + libs/langchain_v1/pyproject.toml | 4 +- .../__snapshots__/test_middleware_agent.ambr | 533 +++++++++++++ .../agents/test_middleware_agent.py | 712 ++++++++++++++++++ libs/langchain_v1/uv.lock | 566 +++++++------- 12 files changed, 2647 insertions(+), 285 deletions(-) create mode 100644 libs/langchain_v1/langchain/agents/middleware/__init__.py create mode 100644 libs/langchain_v1/langchain/agents/middleware/_utils.py create mode 100644 libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py create mode 100644 libs/langchain_v1/langchain/agents/middleware/prompt_caching.py create mode 100644 libs/langchain_v1/langchain/agents/middleware/summarization.py create mode 100644 libs/langchain_v1/langchain/agents/middleware/types.py create mode 100644 libs/langchain_v1/langchain/agents/middleware_agent.py create mode 100644 libs/langchain_v1/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr create mode 100644 libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py diff --git a/libs/langchain_v1/langchain/agents/middleware/__init__.py b/libs/langchain_v1/langchain/agents/middleware/__init__.py new file mode 100644 index 00000000000..efc31b6eb73 --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/__init__.py @@ -0,0 +1,15 @@ +"""Middleware plugins for agents.""" + +from .human_in_the_loop import HumanInTheLoopMiddleware +from .prompt_caching import AnthropicPromptCachingMiddleware +from .summarization import SummarizationMiddleware +from .types import AgentMiddleware, AgentState, ModelRequest + +__all__ = [ + "AgentMiddleware", + "AgentState", + "AnthropicPromptCachingMiddleware", + "HumanInTheLoopMiddleware", + "ModelRequest", + "SummarizationMiddleware", +] diff --git a/libs/langchain_v1/langchain/agents/middleware/_utils.py b/libs/langchain_v1/langchain/agents/middleware/_utils.py new file mode 100644 index 00000000000..2debfd4c884 --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/_utils.py @@ -0,0 +1,11 @@ +"""Utility functions for middleware.""" + +from typing import Any + + +def _generate_correction_tool_messages(content: str, tool_calls: list) -> list[dict[str, Any]]: + """Generate tool messages for model behavior correction.""" + return [ + {"role": "tool", "content": content, "tool_call_id": tool_call["id"]} + for tool_call in tool_calls + ] diff --git a/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py b/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py new file mode 100644 index 00000000000..b2ed04867cf --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py @@ -0,0 +1,128 @@ +"""Human in the loop middleware.""" + +from typing import Any + +from langgraph.prebuilt.interrupt import ( + ActionRequest, + HumanInterrupt, + HumanInterruptConfig, + HumanResponse, +) +from langgraph.types import interrupt + +from langchain.agents.middleware._utils import _generate_correction_tool_messages +from langchain.agents.middleware.types import AgentMiddleware, AgentState + +ToolInterruptConfig = dict[str, HumanInterruptConfig] + + +class HumanInTheLoopMiddleware(AgentMiddleware): + """Human in the loop middleware.""" + + def __init__( + self, + tool_configs: ToolInterruptConfig, + message_prefix: str = "Tool execution requires approval", + ) -> None: + """Initialize the human in the loop middleware. + + Args: + tool_configs: The tool interrupt configs to use for the middleware. + message_prefix: The message prefix to use when constructing interrupt content. + """ + super().__init__() + self.tool_configs = tool_configs + self.message_prefix = message_prefix + + def after_model(self, state: AgentState) -> dict[str, Any] | None: + """Trigger HITL flows for relevant tool calls after an AIMessage.""" + messages = state["messages"] + if not messages: + return None + + last_message = messages[-1] + + if not hasattr(last_message, "tool_calls") or not last_message.tool_calls: + return None + + # Separate tool calls that need interrupts from those that don't + interrupt_tool_calls = [] + auto_approved_tool_calls = [] + + for tool_call in last_message.tool_calls: + tool_name = tool_call["name"] + if tool_name in self.tool_configs: + interrupt_tool_calls.append(tool_call) + else: + auto_approved_tool_calls.append(tool_call) + + # If no interrupts needed, return early + if not interrupt_tool_calls: + return None + + approved_tool_calls = auto_approved_tool_calls.copy() + + # Right now, we do not support multiple tool calls with interrupts + if len(interrupt_tool_calls) > 1: + tool_names = [t["name"] for t in interrupt_tool_calls] + msg = f"Called the following tools which require interrupts: {tool_names}\n\nYou may only call ONE tool that requires an interrupt at a time" + return { + "messages": _generate_correction_tool_messages(msg, last_message.tool_calls), + "jump_to": "model", + } + + # Right now, we do not support interrupting a tool call if other tool calls exist + if auto_approved_tool_calls: + tool_names = [t["name"] for t in interrupt_tool_calls] + msg = f"Called the following tools which require interrupts: {tool_names}. You also called other tools that do not require interrupts. If you call a tool that requires and interrupt, you may ONLY call that tool." + return { + "messages": _generate_correction_tool_messages(msg, last_message.tool_calls), + "jump_to": "model", + } + + # Only one tool call will need interrupts + tool_call = interrupt_tool_calls[0] + tool_name = tool_call["name"] + tool_args = tool_call["args"] + description = f"{self.message_prefix}\n\nTool: {tool_name}\nArgs: {tool_args}" + tool_config = self.tool_configs[tool_name] + + request: HumanInterrupt = { + "action_request": ActionRequest( + action=tool_name, + args=tool_args, + ), + "config": tool_config, + "description": description, + } + + responses: list[HumanResponse] = interrupt([request]) + response = responses[0] + + if response["type"] == "accept": + approved_tool_calls.append(tool_call) + elif response["type"] == "edit": + edited: ActionRequest = response["args"] # type: ignore[assignment] + new_tool_call = { + "type": "tool_call", + "name": tool_call["name"], + "args": edited["args"], + "id": tool_call["id"], + } + approved_tool_calls.append(new_tool_call) + elif response["type"] == "ignore": + return {"jump_to": "__end__"} + elif response["type"] == "response": + tool_message = { + "role": "tool", + "tool_call_id": tool_call["id"], + "content": response["args"], + } + return {"messages": [tool_message], "jump_to": "model"} + else: + msg = f"Unknown response type: {response['type']}" + raise ValueError(msg) + + last_message.tool_calls = approved_tool_calls + + return {"messages": [last_message]} diff --git a/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py b/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py new file mode 100644 index 00000000000..52eb2c147de --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py @@ -0,0 +1,57 @@ +"""Anthropic prompt caching middleware.""" + +from typing import Literal + +from langchain.agents.middleware.types import AgentMiddleware, AgentState, ModelRequest + + +class AnthropicPromptCachingMiddleware(AgentMiddleware): + """Prompt Caching Middleware - Optimizes API usage by caching conversation prefixes for Anthropic models. + + Learn more about anthropic prompt caching [here](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching). + """ + + def __init__( + self, + type: Literal["ephemeral"] = "ephemeral", + ttl: Literal["5m", "1h"] = "5m", + min_messages_to_cache: int = 0, + ) -> None: + """Initialize the middleware with cache control settings. + + Args: + type: The type of cache to use, only "ephemeral" is supported. + ttl: The time to live for the cache, only "5m" and "1h" are supported. + min_messages_to_cache: The minimum number of messages until the cache is used, default is 0. + """ + self.type = type + self.ttl = ttl + self.min_messages_to_cache = min_messages_to_cache + + def modify_model_request(self, request: ModelRequest, state: AgentState) -> ModelRequest: # noqa: ARG002 + """Modify the model request to add cache control blocks.""" + try: + from langchain_anthropic import ChatAnthropic + except ImportError: + msg = ( + "AnthropicPromptCachingMiddleware caching middleware only supports Anthropic models." + "Please install langchain-anthropic." + ) + raise ValueError(msg) + + if not isinstance(request.model, ChatAnthropic): + msg = ( + "AnthropicPromptCachingMiddleware caching middleware only supports Anthropic models, " + f"not instances of {type(request.model)}" + ) + raise ValueError(msg) + + messages_count = ( + len(request.messages) + 1 if request.system_prompt else len(request.messages) + ) + if messages_count < self.min_messages_to_cache: + return request + + request.model_settings["cache_control"] = {"type": self.type, "ttl": self.ttl} + + return request diff --git a/libs/langchain_v1/langchain/agents/middleware/summarization.py b/libs/langchain_v1/langchain/agents/middleware/summarization.py new file mode 100644 index 00000000000..04274b14c87 --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/summarization.py @@ -0,0 +1,248 @@ +"""Summarization middleware.""" + +import uuid +from collections.abc import Callable, Iterable +from typing import Any, cast + +from langchain_core.messages import ( + AIMessage, + AnyMessage, + MessageLikeRepresentation, + RemoveMessage, + ToolMessage, +) +from langchain_core.messages.human import HumanMessage +from langchain_core.messages.utils import count_tokens_approximately, trim_messages +from langgraph.graph.message import ( + REMOVE_ALL_MESSAGES, +) + +from langchain.agents.middleware.types import AgentMiddleware, AgentState +from langchain.chat_models import BaseChatModel, init_chat_model + +TokenCounter = Callable[[Iterable[MessageLikeRepresentation]], int] + +DEFAULT_SUMMARY_PROMPT = """ +Context Extraction Assistant + + + +Your sole objective in this task is to extract the highest quality/most relevant context from the conversation history below. + + + +You're nearing the total number of input tokens you can accept, so you must extract the highest quality/most relevant pieces of information from your conversation history. +This context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to your overall goal. + + + +The conversation history below will be replaced with the context you extract in this step. Because of this, you must do your very best to extract and record all of the most important context from the conversation history. +You want to ensure that you don't repeat any actions you've already completed, so the context you extract from the conversation history should be focused on the most important information to your overall goal. + + +The user will message you with the full message history you'll be extracting context from, to then replace. Carefully read over it all, and think deeply about what information is most important to your overall goal that should be saved: + +With all of this in mind, please carefully read over the entire conversation history, and extract the most important and relevant context to replace it so that you can free up space in the conversation history. +Respond ONLY with the extracted context. Do not include any additional information, or text before or after the extracted context. + + +Messages to summarize: +{messages} +""" + +SUMMARY_PREFIX = "## Previous conversation summary:" + +_DEFAULT_MESSAGES_TO_KEEP = 20 +_DEFAULT_TRIM_TOKEN_LIMIT = 4000 +_DEFAULT_FALLBACK_MESSAGE_COUNT = 15 +_SEARCH_RANGE_FOR_TOOL_PAIRS = 5 + + +class SummarizationMiddleware(AgentMiddleware): + """Middleware that summarizes conversation history when token limits are approached. + + This middleware monitors message token counts and automatically summarizes older + messages when a threshold is reached, preserving recent messages and maintaining + context continuity by ensuring AI/Tool message pairs remain together. + """ + + def __init__( + self, + model: str | BaseChatModel, + max_tokens_before_summary: int | None = None, + messages_to_keep: int = _DEFAULT_MESSAGES_TO_KEEP, + token_counter: TokenCounter = count_tokens_approximately, + summary_prompt: str = DEFAULT_SUMMARY_PROMPT, + summary_prefix: str = SUMMARY_PREFIX, + ) -> None: + """Initialize the summarization middleware. + + Args: + model: The language model to use for generating summaries. + max_tokens_before_summary: Token threshold to trigger summarization. + If None, summarization is disabled. + messages_to_keep: Number of recent messages to preserve after summarization. + token_counter: Function to count tokens in messages. + summary_prompt: Prompt template for generating summaries. + summary_prefix: Prefix added to system message when including summary. + """ + super().__init__() + + if isinstance(model, str): + model = init_chat_model(model) + + self.model = model + self.max_tokens_before_summary = max_tokens_before_summary + self.messages_to_keep = messages_to_keep + self.token_counter = token_counter + self.summary_prompt = summary_prompt + self.summary_prefix = summary_prefix + + def before_model(self, state: AgentState) -> dict[str, Any] | None: + """Process messages before model invocation, potentially triggering summarization.""" + messages = state["messages"] + self._ensure_message_ids(messages) + + total_tokens = self.token_counter(messages) + if ( + self.max_tokens_before_summary is not None + and total_tokens < self.max_tokens_before_summary + ): + return None + + cutoff_index = self._find_safe_cutoff(messages) + + if cutoff_index <= 0: + return None + + messages_to_summarize, preserved_messages = self._partition_messages(messages, cutoff_index) + + summary = self._create_summary(messages_to_summarize) + new_messages = self._build_new_messages(summary) + + return { + "messages": [ + RemoveMessage(id=REMOVE_ALL_MESSAGES), + *new_messages, + *preserved_messages, + ] + } + + def _build_new_messages(self, summary: str) -> list[HumanMessage]: + return [ + HumanMessage(content=f"Here is a summary of the conversation to date:\n\n{summary}") + ] + + def _ensure_message_ids(self, messages: list[AnyMessage]) -> None: + """Ensure all messages have unique IDs for the add_messages reducer.""" + for msg in messages: + if msg.id is None: + msg.id = str(uuid.uuid4()) + + def _partition_messages( + self, + conversation_messages: list[AnyMessage], + cutoff_index: int, + ) -> tuple[list[AnyMessage], list[AnyMessage]]: + """Partition messages into those to summarize and those to preserve.""" + messages_to_summarize = conversation_messages[:cutoff_index] + preserved_messages = conversation_messages[cutoff_index:] + + return messages_to_summarize, preserved_messages + + def _find_safe_cutoff(self, messages: list[AnyMessage]) -> int: + """Find safe cutoff point that preserves AI/Tool message pairs. + + Returns the index where messages can be safely cut without separating + related AI and Tool messages. Returns 0 if no safe cutoff is found. + """ + if len(messages) <= self.messages_to_keep: + return 0 + + target_cutoff = len(messages) - self.messages_to_keep + + for i in range(target_cutoff, -1, -1): + if self._is_safe_cutoff_point(messages, i): + return i + + return 0 + + def _is_safe_cutoff_point(self, messages: list[AnyMessage], cutoff_index: int) -> bool: + """Check if cutting at index would separate AI/Tool message pairs.""" + if cutoff_index >= len(messages): + return True + + search_start = max(0, cutoff_index - _SEARCH_RANGE_FOR_TOOL_PAIRS) + search_end = min(len(messages), cutoff_index + _SEARCH_RANGE_FOR_TOOL_PAIRS) + + for i in range(search_start, search_end): + if not self._has_tool_calls(messages[i]): + continue + + tool_call_ids = self._extract_tool_call_ids(cast("AIMessage", messages[i])) + if self._cutoff_separates_tool_pair(messages, i, cutoff_index, tool_call_ids): + return False + + return True + + def _has_tool_calls(self, message: AnyMessage) -> bool: + """Check if message is an AI message with tool calls.""" + return ( + isinstance(message, AIMessage) and hasattr(message, "tool_calls") and message.tool_calls # type: ignore[return-value] + ) + + def _extract_tool_call_ids(self, ai_message: AIMessage) -> set[str]: + """Extract tool call IDs from an AI message.""" + tool_call_ids = set() + for tc in ai_message.tool_calls: + call_id = tc.get("id") if isinstance(tc, dict) else getattr(tc, "id", None) + if call_id is not None: + tool_call_ids.add(call_id) + return tool_call_ids + + def _cutoff_separates_tool_pair( + self, + messages: list[AnyMessage], + ai_message_index: int, + cutoff_index: int, + tool_call_ids: set[str], + ) -> bool: + """Check if cutoff separates an AI message from its corresponding tool messages.""" + for j in range(ai_message_index + 1, len(messages)): + message = messages[j] + if isinstance(message, ToolMessage) and message.tool_call_id in tool_call_ids: + ai_before_cutoff = ai_message_index < cutoff_index + tool_before_cutoff = j < cutoff_index + if ai_before_cutoff != tool_before_cutoff: + return True + return False + + def _create_summary(self, messages_to_summarize: list[AnyMessage]) -> str: + """Generate summary for the given messages.""" + if not messages_to_summarize: + return "No previous conversation history." + + trimmed_messages = self._trim_messages_for_summary(messages_to_summarize) + if not trimmed_messages: + return "Previous conversation was too long to summarize." + + try: + response = self.model.invoke(self.summary_prompt.format(messages=trimmed_messages)) + return cast("str", response.content).strip() + except Exception as e: # noqa: BLE001 + return f"Error generating summary: {e!s}" + + def _trim_messages_for_summary(self, messages: list[AnyMessage]) -> list[AnyMessage]: + """Trim messages to fit within summary generation limits.""" + try: + return trim_messages( + messages, + max_tokens=_DEFAULT_TRIM_TOKEN_LIMIT, + token_counter=self.token_counter, + start_on="human", + strategy="last", + allow_partial=True, + include_system=True, + ) + except Exception: # noqa: BLE001 + return messages[-_DEFAULT_FALLBACK_MESSAGE_COUNT:] diff --git a/libs/langchain_v1/langchain/agents/middleware/types.py b/libs/langchain_v1/langchain/agents/middleware/types.py new file mode 100644 index 00000000000..976d0c323b0 --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/types.py @@ -0,0 +1,78 @@ +"""Types for middleware and agents.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Annotated, Any, Generic, Literal, cast + +# needed as top level import for pydantic schema generation on AgentState +from langchain_core.messages import AnyMessage # noqa: TC002 +from langgraph.channels.ephemeral_value import EphemeralValue +from langgraph.graph.message import Messages, add_messages +from typing_extensions import NotRequired, Required, TypedDict, TypeVar + +if TYPE_CHECKING: + from langchain_core.language_models.chat_models import BaseChatModel + from langchain_core.tools import BaseTool + + from langchain.agents.structured_output import ResponseFormat + +JumpTo = Literal["tools", "model", "__end__"] +"""Destination to jump to when a middleware node returns.""" + +ResponseT = TypeVar("ResponseT") + + +@dataclass +class ModelRequest: + """Model request information for the agent.""" + + model: BaseChatModel + system_prompt: str | None + messages: list[AnyMessage] # excluding system prompt + tool_choice: Any | None + tools: list[BaseTool] + response_format: ResponseFormat | None + model_settings: dict[str, Any] = field(default_factory=dict) + + +class AgentState(TypedDict, Generic[ResponseT]): + """State schema for the agent.""" + + messages: Required[Annotated[list[AnyMessage], add_messages]] + model_request: NotRequired[Annotated[ModelRequest | None, EphemeralValue]] + jump_to: NotRequired[Annotated[JumpTo | None, EphemeralValue]] + response: NotRequired[ResponseT] + + +class PublicAgentState(TypedDict, Generic[ResponseT]): + """Input / output schema for the agent.""" + + messages: Required[Messages] + response: NotRequired[ResponseT] + + +StateT = TypeVar("StateT", bound=AgentState) + + +class AgentMiddleware(Generic[StateT]): + """Base middleware class for an agent. + + Subclass this and implement any of the defined methods to customize agent behavior between steps in the main agent loop. + """ + + state_schema: type[StateT] = cast("type[StateT]", AgentState) + """The schema for state passed to the middleware nodes.""" + + tools: list[BaseTool] + """Additional tools registered by the middleware.""" + + def before_model(self, state: StateT) -> dict[str, Any] | None: + """Logic to run before the model is called.""" + + def modify_model_request(self, request: ModelRequest, state: StateT) -> ModelRequest: # noqa: ARG002 + """Logic to modify request kwargs before the model is called.""" + return request + + def after_model(self, state: StateT) -> dict[str, Any] | None: + """Logic to run after the model is called.""" diff --git a/libs/langchain_v1/langchain/agents/middleware_agent.py b/libs/langchain_v1/langchain/agents/middleware_agent.py new file mode 100644 index 00000000000..ac210d3cacf --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware_agent.py @@ -0,0 +1,554 @@ +"""Middleware agent implementation.""" + +import itertools +from collections.abc import Callable, Sequence +from typing import Any, Union + +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_core.messages import AIMessage, AnyMessage, SystemMessage, ToolMessage +from langchain_core.runnables import Runnable +from langchain_core.tools import BaseTool +from langgraph.constants import END, START +from langgraph.graph.state import StateGraph +from langgraph.typing import ContextT +from typing_extensions import TypedDict, TypeVar + +from langchain.agents.middleware.types import ( + AgentMiddleware, + AgentState, + JumpTo, + ModelRequest, + PublicAgentState, +) + +# Import structured output classes from the old implementation +from langchain.agents.structured_output import ( + MultipleStructuredOutputsError, + OutputToolBinding, + ProviderStrategy, + ProviderStrategyBinding, + ResponseFormat, + StructuredOutputValidationError, + ToolStrategy, +) +from langchain.agents.tool_node import ToolNode +from langchain.chat_models import init_chat_model + +STRUCTURED_OUTPUT_ERROR_TEMPLATE = "Error: {error}\n Please fix your mistakes." + + +def _merge_state_schemas(schemas: list[type]) -> type: + """Merge multiple TypedDict schemas into a single schema with all fields.""" + if not schemas: + return AgentState + + all_annotations = {} + + for schema in schemas: + all_annotations.update(schema.__annotations__) + + return TypedDict("MergedState", all_annotations) # type: ignore[operator] + + +def _filter_state_for_schema(state: dict[str, Any], schema: type) -> dict[str, Any]: + """Filter state to only include fields defined in the given schema.""" + if not hasattr(schema, "__annotations__"): + return state + + schema_fields = set(schema.__annotations__.keys()) + return {k: v for k, v in state.items() if k in schema_fields} + + +def _supports_native_structured_output(model: Union[str, BaseChatModel]) -> bool: + """Check if a model supports native structured output.""" + model_name: str | None = None + if isinstance(model, str): + model_name = model + elif isinstance(model, BaseChatModel): + model_name = getattr(model, "model_name", None) + + return ( + "grok" in model_name.lower() + or any(part in model_name for part in ["gpt-5", "gpt-4.1", "gpt-oss", "o3-pro", "o3-mini"]) + if model_name + else False + ) + + +def _handle_structured_output_error( + exception: Exception, + response_format: ResponseFormat, +) -> tuple[bool, str]: + """Handle structured output error. Returns (should_retry, retry_tool_message).""" + if not isinstance(response_format, ToolStrategy): + return False, "" + + handle_errors = response_format.handle_errors + + if handle_errors is False: + return False, "" + if handle_errors is True: + return True, STRUCTURED_OUTPUT_ERROR_TEMPLATE.format(error=str(exception)) + if isinstance(handle_errors, str): + return True, handle_errors + if isinstance(handle_errors, type) and issubclass(handle_errors, Exception): + if isinstance(exception, handle_errors): + return True, STRUCTURED_OUTPUT_ERROR_TEMPLATE.format(error=str(exception)) + return False, "" + if isinstance(handle_errors, tuple): + if any(isinstance(exception, exc_type) for exc_type in handle_errors): + return True, STRUCTURED_OUTPUT_ERROR_TEMPLATE.format(error=str(exception)) + return False, "" + if callable(handle_errors): + # type narrowing not working appropriately w/ callable check, can fix later + return True, handle_errors(exception) # type: ignore[return-value,call-arg] + return False, "" + + +ResponseT = TypeVar("ResponseT") + + +def create_agent( # noqa: PLR0915 + *, + model: str | BaseChatModel, + tools: Sequence[BaseTool | Callable | dict[str, Any]] | ToolNode | None = None, + system_prompt: str | None = None, + middleware: Sequence[AgentMiddleware] = (), + response_format: ResponseFormat[ResponseT] | type[ResponseT] | None = None, + context_schema: type[ContextT] | None = None, +) -> StateGraph[ + AgentState[ResponseT], ContextT, PublicAgentState[ResponseT], PublicAgentState[ResponseT] +]: + """Create a middleware agent graph.""" + # init chat model + if isinstance(model, str): + model = init_chat_model(model) + + # Handle tools being None or empty + if tools is None: + tools = [] + + # Setup structured output + structured_output_tools: dict[str, OutputToolBinding] = {} + native_output_binding: ProviderStrategyBinding | None = None + + if response_format is not None: + if not isinstance(response_format, (ToolStrategy, ProviderStrategy)): + # Auto-detect strategy based on model capabilities + if _supports_native_structured_output(model): + response_format = ProviderStrategy(schema=response_format) + else: + response_format = ToolStrategy(schema=response_format) + + if isinstance(response_format, ToolStrategy): + # Setup tools strategy for structured output + for response_schema in response_format.schema_specs: + structured_tool_info = OutputToolBinding.from_schema_spec(response_schema) + structured_output_tools[structured_tool_info.tool.name] = structured_tool_info + elif isinstance(response_format, ProviderStrategy): + # Setup native strategy + native_output_binding = ProviderStrategyBinding.from_schema_spec( + response_format.schema_spec + ) + middleware_tools = [t for m in middleware for t in getattr(m, "tools", [])] + + # Setup tools + tool_node: ToolNode | None = None + if isinstance(tools, list): + # Extract builtin provider tools (dict format) + builtin_tools = [t for t in tools if isinstance(t, dict)] + regular_tools = [t for t in tools if not isinstance(t, dict)] + + # Add structured output tools to regular tools + structured_tools = [info.tool for info in structured_output_tools.values()] + all_tools = middleware_tools + regular_tools + structured_tools + + # Only create ToolNode if we have tools + tool_node = ToolNode(tools=all_tools) if all_tools else None + default_tools = regular_tools + builtin_tools + structured_tools + middleware_tools + elif isinstance(tools, ToolNode): + # tools is ToolNode or None + tool_node = tools + if tool_node: + default_tools = list(tool_node.tools_by_name.values()) + middleware_tools + # Update tool node to know about tools provided by middleware + all_tools = list(tool_node.tools_by_name.values()) + middleware_tools + tool_node = ToolNode(all_tools) + # Add structured output tools + for info in structured_output_tools.values(): + default_tools.append(info.tool) + else: + default_tools = ( + list(structured_output_tools.values()) if structured_output_tools else [] + ) + middleware_tools + + # validate middleware + assert len({m.__class__.__name__ for m in middleware}) == len(middleware), ( # noqa: S101 + "Please remove duplicate middleware instances." + ) + middleware_w_before = [ + m for m in middleware if m.__class__.before_model is not AgentMiddleware.before_model + ] + middleware_w_modify_model_request = [ + m + for m in middleware + if m.__class__.modify_model_request is not AgentMiddleware.modify_model_request + ] + middleware_w_after = [ + m for m in middleware if m.__class__.after_model is not AgentMiddleware.after_model + ] + + # Collect all middleware state schemas and create merged schema + merged_state_schema: type[AgentState] = _merge_state_schemas( + [m.state_schema for m in middleware] + ) + + # create graph, add nodes + graph = StateGraph( + merged_state_schema, + input_schema=PublicAgentState, + output_schema=PublicAgentState, + context_schema=context_schema, + ) + + def _prepare_model_request(state: dict[str, Any]) -> tuple[ModelRequest, list[AnyMessage]]: + """Prepare model request and messages.""" + request = state.get("model_request") or ModelRequest( + model=model, + tools=default_tools, + system_prompt=system_prompt, + response_format=response_format, + messages=state["messages"], + tool_choice=None, + ) + + # prepare messages + messages = request.messages + if request.system_prompt: + messages = [SystemMessage(request.system_prompt), *messages] + + return request, messages + + def _handle_model_output(state: dict[str, Any], output: AIMessage) -> dict[str, Any]: + """Handle model output including structured responses.""" + # Handle structured output with native strategy + if isinstance(response_format, ProviderStrategy): + if not output.tool_calls and native_output_binding: + structured_response = native_output_binding.parse(output) + return {"messages": [output], "response": structured_response} + if state.get("response") is not None: + return {"messages": [output], "response": None} + return {"messages": [output]} + + # Handle structured output with tools strategy + if ( + isinstance(response_format, ToolStrategy) + and isinstance(output, AIMessage) + and output.tool_calls + ): + structured_tool_calls = [ + tc for tc in output.tool_calls if tc["name"] in structured_output_tools + ] + + if structured_tool_calls: + exception: Exception | None = None + if len(structured_tool_calls) > 1: + # Handle multiple structured outputs error + tool_names = [tc["name"] for tc in structured_tool_calls] + exception = MultipleStructuredOutputsError(tool_names) + should_retry, error_message = _handle_structured_output_error( + exception, response_format + ) + if not should_retry: + raise exception + + # Add error messages and retry + tool_messages = [ + ToolMessage( + content=error_message, + tool_call_id=tc["id"], + name=tc["name"], + ) + for tc in structured_tool_calls + ] + return {"messages": [output, *tool_messages]} + + # Handle single structured output + tool_call = structured_tool_calls[0] + try: + structured_tool_binding = structured_output_tools[tool_call["name"]] + structured_response = structured_tool_binding.parse(tool_call["args"]) + + tool_message_content = ( + response_format.tool_message_content + if response_format.tool_message_content + else f"Returning structured response: {structured_response}" + ) + + return { + "messages": [ + output, + ToolMessage( + content=tool_message_content, + tool_call_id=tool_call["id"], + name=tool_call["name"], + ), + ], + "response": structured_response, + } + except Exception as exc: # noqa: BLE001 + exception = StructuredOutputValidationError(tool_call["name"], exc) + should_retry, error_message = _handle_structured_output_error( + exception, response_format + ) + if not should_retry: + raise exception + + return { + "messages": [ + output, + ToolMessage( + content=error_message, + tool_call_id=tool_call["id"], + name=tool_call["name"], + ), + ], + } + + # Standard response handling + if state.get("response") is not None: + return {"messages": [output], "response": None} + return {"messages": [output]} + + def _get_bound_model(request: ModelRequest) -> Runnable: + """Get the model with appropriate tool bindings.""" + if isinstance(response_format, ProviderStrategy): + # Use native structured output + kwargs = response_format.to_model_kwargs() + return request.model.bind_tools( + request.tools, strict=True, **kwargs, **request.model_settings + ) + if isinstance(response_format, ToolStrategy): + tool_choice = "any" if structured_output_tools else request.tool_choice + return request.model.bind_tools( + request.tools, tool_choice=tool_choice, **request.model_settings + ) + # Standard model binding + if request.tools: + return request.model.bind_tools( + request.tools, tool_choice=request.tool_choice, **request.model_settings + ) + return request.model.bind(**request.model_settings) + + def model_request(state: dict[str, Any]) -> dict[str, Any]: + """Sync model request handler with sequential middleware processing.""" + # Start with the base model request + request, messages = _prepare_model_request(state) + + # Apply modify_model_request middleware in sequence + for m in middleware_w_modify_model_request: + # Filter state to only include fields defined in this middleware's schema + filtered_state = _filter_state_for_schema(state, m.state_schema) + request = m.modify_model_request(request, filtered_state) + + # Get the bound model with the final request + model_ = _get_bound_model(request) + output = model_.invoke(messages) + return _handle_model_output(state, output) + + async def amodel_request(state: dict[str, Any]) -> dict[str, Any]: + """Async model request handler with sequential middleware processing.""" + # Start with the base model request + request, messages = _prepare_model_request(state) + + # Apply modify_model_request middleware in sequence + for m in middleware_w_modify_model_request: + # Filter state to only include fields defined in this middleware's schema + filtered_state = _filter_state_for_schema(state, m.state_schema) + request = m.modify_model_request(request, filtered_state) + + # Get the bound model with the final request + model_ = _get_bound_model(request) + output = await model_.ainvoke(messages) + return _handle_model_output(state, output) + + # Use sync or async based on model capabilities + from langgraph._internal._runnable import RunnableCallable + + graph.add_node("model_request", RunnableCallable(model_request, amodel_request)) + + # Only add tools node if we have tools + if tool_node is not None: + graph.add_node("tools", tool_node) + + # Add middleware nodes + for m in middleware: + if m.__class__.before_model is not AgentMiddleware.before_model: + graph.add_node( + f"{m.__class__.__name__}.before_model", + m.before_model, + input_schema=m.state_schema, + ) + + if m.__class__.after_model is not AgentMiddleware.after_model: + graph.add_node( + f"{m.__class__.__name__}.after_model", + m.after_model, + input_schema=m.state_schema, + ) + + # add start edge + first_node = ( + f"{middleware_w_before[0].__class__.__name__}.before_model" + if middleware_w_before + else "model_request" + ) + last_node = ( + f"{middleware_w_after[0].__class__.__name__}.after_model" + if middleware_w_after + else "model_request" + ) + graph.add_edge(START, first_node) + + # add conditional edges only if tools exist + if tool_node is not None: + graph.add_conditional_edges( + "tools", + _make_tools_to_model_edge(tool_node, first_node), + [first_node, END], + ) + graph.add_conditional_edges( + last_node, + _make_model_to_tools_edge(first_node, structured_output_tools), + [first_node, "tools", END], + ) + elif last_node == "model_request": + # If no tools, just go to END from model + graph.add_edge(last_node, END) + else: + # If after_model, then need to check for jump_to + _add_middleware_edge( + graph, + f"{middleware_w_after[0].__class__.__name__}.after_model", + END, + first_node, + tools_available=tool_node is not None, + ) + + # Add middleware edges (same as before) + if middleware_w_before: + for m1, m2 in itertools.pairwise(middleware_w_before): + _add_middleware_edge( + graph, + f"{m1.__class__.__name__}.before_model", + f"{m2.__class__.__name__}.before_model", + first_node, + tools_available=tool_node is not None, + ) + # Go directly to model_request after the last before_model + _add_middleware_edge( + graph, + f"{middleware_w_before[-1].__class__.__name__}.before_model", + "model_request", + first_node, + tools_available=tool_node is not None, + ) + + if middleware_w_after: + graph.add_edge("model_request", f"{middleware_w_after[-1].__class__.__name__}.after_model") + for idx in range(len(middleware_w_after) - 1, 0, -1): + m1 = middleware_w_after[idx] + m2 = middleware_w_after[idx - 1] + _add_middleware_edge( + graph, + f"{m1.__class__.__name__}.after_model", + f"{m2.__class__.__name__}.after_model", + first_node, + tools_available=tool_node is not None, + ) + + return graph + + +def _resolve_jump(jump_to: JumpTo | None, first_node: str) -> str | None: + if jump_to == "model": + return first_node + if jump_to: + return jump_to + return None + + +def _make_model_to_tools_edge( + first_node: str, structured_output_tools: dict[str, OutputToolBinding] +) -> Callable[[AgentState], str | None]: + def model_to_tools(state: AgentState) -> str | None: + if jump_to := state.get("jump_to"): + return _resolve_jump(jump_to, first_node) + + message = state["messages"][-1] + + # Check if this is a ToolMessage from structured output - if so, end + if isinstance(message, ToolMessage) and message.name in structured_output_tools: + return END + + # Check for tool calls + if isinstance(message, AIMessage) and message.tool_calls: + # If all tool calls are for structured output, don't go to tools + non_structured_calls = [ + tc for tc in message.tool_calls if tc["name"] not in structured_output_tools + ] + if non_structured_calls: + return "tools" + + return END + + return model_to_tools + + +def _make_tools_to_model_edge( + tool_node: ToolNode, next_node: str +) -> Callable[[AgentState], str | None]: + def tools_to_model(state: AgentState) -> str | None: + ai_message = [m for m in state["messages"] if isinstance(m, AIMessage)][-1] + if all( + tool_node.tools_by_name[c["name"]].return_direct + for c in ai_message.tool_calls + if c["name"] in tool_node.tools_by_name + ): + return END + + return next_node + + return tools_to_model + + +def _add_middleware_edge( + graph: StateGraph[AgentState, ContextT, PublicAgentState, PublicAgentState], + name: str, + default_destination: str, + model_destination: str, + tools_available: bool, # noqa: FBT001 +) -> None: + """Add an edge to the graph for a middleware node. + + Args: + graph: The graph to add the edge to. + method: The method to call for the middleware node. + name: The name of the middleware node. + default_destination: The default destination for the edge. + model_destination: The destination for the edge to the model. + tools_available: Whether tools are available for the edge to potentially route to. + """ + + def jump_edge(state: AgentState) -> str: + return _resolve_jump(state.get("jump_to"), model_destination) or default_destination + + destinations = [default_destination] + if default_destination != END: + destinations.append(END) + if tools_available: + destinations.append("tools") + if name != model_destination: + destinations.append(model_destination) + + graph.add_conditional_edges(name, jump_edge, destinations) diff --git a/libs/langchain_v1/langchain/agents/react_agent.py b/libs/langchain_v1/langchain/agents/react_agent.py index 5bce0f84c0d..2a637b5ad0b 100644 --- a/libs/langchain_v1/langchain/agents/react_agent.py +++ b/libs/langchain_v1/langchain/agents/react_agent.py @@ -45,6 +45,7 @@ from langgraph.typing import ContextT, StateT from pydantic import BaseModel from typing_extensions import NotRequired, TypedDict, TypeVar +from langchain.agents.middleware_agent import create_agent as create_middleware_agent from langchain.agents.structured_output import ( MultipleStructuredOutputsError, OutputToolBinding, @@ -66,6 +67,7 @@ if TYPE_CHECKING: from langchain.agents._internal._typing import ( SyncOrAsync, ) + from langchain.agents.types import AgentMiddleware StructuredResponseT = TypeVar("StructuredResponseT", default=None) @@ -908,6 +910,7 @@ def create_agent( # noqa: D417 ], tools: Union[Sequence[Union[BaseTool, Callable, dict[str, Any]]], ToolNode], *, + middleware: Sequence[AgentMiddleware] = (), prompt: Prompt | None = None, response_format: Union[ ToolStrategy[StructuredResponseT], @@ -1114,6 +1117,29 @@ def create_agent( # noqa: D417 print(chunk) ``` """ + if middleware: + assert isinstance(model, str | BaseChatModel) # noqa: S101 + assert isinstance(prompt, str | None) # noqa: S101 + assert not isinstance(response_format, tuple) # noqa: S101 + assert pre_model_hook is None # noqa: S101 + assert post_model_hook is None # noqa: S101 + assert state_schema is None # noqa: S101 + return create_middleware_agent( # type: ignore[return-value] + model=model, + tools=tools, + system_prompt=prompt, + middleware=middleware, + response_format=response_format, + context_schema=context_schema, + ).compile( + checkpointer=checkpointer, + store=store, + name=name, + interrupt_after=interrupt_after, + interrupt_before=interrupt_before, + debug=debug, + ) + # Handle deprecated config_schema parameter if (config_schema := deprecated_kwargs.pop("config_schema", MISSING)) is not MISSING: warn( diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index ca1ccd37a5c..be15eddabb2 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -9,12 +9,12 @@ requires-python = ">=3.10" dependencies = [ "langchain-core<2.0.0,>=0.3.75", "langchain-text-splitters<1.0.0,>=0.3.11", - "langgraph>=0.6.0", + "langgraph>=0.6.7", "pydantic>=2.7.4", ] name = "langchain" -version = "1.0.0a3" +version = "1.0.0a4" description = "Building applications with LLMs through composability" readme = "README.md" diff --git a/libs/langchain_v1/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr b/libs/langchain_v1/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr new file mode 100644 index 00000000000..c7ab09b722b --- /dev/null +++ b/libs/langchain_v1/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr @@ -0,0 +1,533 @@ +# serializer version: 1 +# name: test_create_agent_diagram + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + __end__([

__end__

]):::last + __start__ --> model_request; + model_request --> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.1 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopOne_before_model(NoopOne.before_model) + __end__([

__end__

]):::last + NoopOne_before_model -.-> __end__; + NoopOne_before_model -.-> model_request; + __start__ --> NoopOne_before_model; + model_request --> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.10 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopTen_before_model(NoopTen.before_model) + NoopTen_after_model(NoopTen.after_model) + __end__([

__end__

]):::last + NoopTen_after_model -.-> NoopTen_before_model; + NoopTen_after_model -.-> __end__; + NoopTen_before_model -.-> __end__; + NoopTen_before_model -.-> model_request; + __start__ --> NoopTen_before_model; + model_request --> NoopTen_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.11 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopTen_before_model(NoopTen.before_model) + NoopTen_after_model(NoopTen.after_model) + NoopEleven_before_model(NoopEleven.before_model) + NoopEleven_after_model(NoopEleven.after_model) + __end__([

__end__

]):::last + NoopEleven_after_model -.-> NoopTen_after_model; + NoopEleven_after_model -.-> NoopTen_before_model; + NoopEleven_after_model -.-> __end__; + NoopEleven_before_model -.-> NoopTen_before_model; + NoopEleven_before_model -.-> __end__; + NoopEleven_before_model -.-> model_request; + NoopTen_after_model -.-> NoopTen_before_model; + NoopTen_after_model -.-> __end__; + NoopTen_before_model -.-> NoopEleven_before_model; + NoopTen_before_model -.-> __end__; + __start__ --> NoopTen_before_model; + model_request --> NoopEleven_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.2 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopOne_before_model(NoopOne.before_model) + NoopTwo_before_model(NoopTwo.before_model) + __end__([

__end__

]):::last + NoopOne_before_model -.-> NoopTwo_before_model; + NoopOne_before_model -.-> __end__; + NoopTwo_before_model -.-> NoopOne_before_model; + NoopTwo_before_model -.-> __end__; + NoopTwo_before_model -.-> model_request; + __start__ --> NoopOne_before_model; + model_request --> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.3 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopOne_before_model(NoopOne.before_model) + NoopTwo_before_model(NoopTwo.before_model) + NoopThree_before_model(NoopThree.before_model) + __end__([

__end__

]):::last + NoopOne_before_model -.-> NoopTwo_before_model; + NoopOne_before_model -.-> __end__; + NoopThree_before_model -.-> NoopOne_before_model; + NoopThree_before_model -.-> __end__; + NoopThree_before_model -.-> model_request; + NoopTwo_before_model -.-> NoopOne_before_model; + NoopTwo_before_model -.-> NoopThree_before_model; + NoopTwo_before_model -.-> __end__; + __start__ --> NoopOne_before_model; + model_request --> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.4 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopFour_after_model(NoopFour.after_model) + __end__([

__end__

]):::last + NoopFour_after_model -.-> __end__; + NoopFour_after_model -.-> model_request; + __start__ --> model_request; + model_request --> NoopFour_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.5 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopFour_after_model(NoopFour.after_model) + NoopFive_after_model(NoopFive.after_model) + __end__([

__end__

]):::last + NoopFive_after_model -.-> NoopFour_after_model; + NoopFive_after_model -.-> __end__; + NoopFive_after_model -.-> model_request; + NoopFour_after_model -.-> __end__; + NoopFour_after_model -.-> model_request; + __start__ --> model_request; + model_request --> NoopFive_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.6 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopFour_after_model(NoopFour.after_model) + NoopFive_after_model(NoopFive.after_model) + NoopSix_after_model(NoopSix.after_model) + __end__([

__end__

]):::last + NoopFive_after_model -.-> NoopFour_after_model; + NoopFive_after_model -.-> __end__; + NoopFive_after_model -.-> model_request; + NoopFour_after_model -.-> __end__; + NoopFour_after_model -.-> model_request; + NoopSix_after_model -.-> NoopFive_after_model; + NoopSix_after_model -.-> __end__; + NoopSix_after_model -.-> model_request; + __start__ --> model_request; + model_request --> NoopSix_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.7 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + __end__([

__end__

]):::last + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_before_model -.-> __end__; + NoopSeven_before_model -.-> model_request; + __start__ --> NoopSeven_before_model; + model_request --> NoopSeven_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.8 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopEight_before_model -.-> model_request; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + __start__ --> NoopSeven_before_model; + model_request --> NoopEight_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_diagram.9 + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + NoopNine_before_model(NoopNine.before_model) + NoopNine_after_model(NoopNine.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_before_model -.-> NoopNine_before_model; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopNine_after_model -.-> NoopEight_after_model; + NoopNine_after_model -.-> NoopSeven_before_model; + NoopNine_after_model -.-> __end__; + NoopNine_before_model -.-> NoopSeven_before_model; + NoopNine_before_model -.-> __end__; + NoopNine_before_model -.-> model_request; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + __start__ --> NoopSeven_before_model; + model_request --> NoopNine_after_model; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_jump[memory] + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + tools(tools) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_after_model -.-> tools; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopEight_before_model -.-> model_request; + NoopEight_before_model -.-> tools; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_after_model -.-> tools; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + NoopSeven_before_model -.-> tools; + __start__ --> NoopSeven_before_model; + model_request --> NoopEight_after_model; + tools -.-> NoopSeven_before_model; + tools -.-> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_jump[postgres] + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + tools(tools) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_after_model -.-> tools; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopEight_before_model -.-> model_request; + NoopEight_before_model -.-> tools; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_after_model -.-> tools; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + NoopSeven_before_model -.-> tools; + __start__ --> NoopSeven_before_model; + model_request --> NoopEight_after_model; + tools -.-> NoopSeven_before_model; + tools -.-> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_jump[postgres_pipe] + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + tools(tools) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_after_model -.-> tools; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopEight_before_model -.-> model_request; + NoopEight_before_model -.-> tools; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_after_model -.-> tools; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + NoopSeven_before_model -.-> tools; + __start__ --> NoopSeven_before_model; + model_request --> NoopEight_after_model; + tools -.-> NoopSeven_before_model; + tools -.-> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_jump[postgres_pool] + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + tools(tools) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_after_model -.-> tools; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopEight_before_model -.-> model_request; + NoopEight_before_model -.-> tools; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_after_model -.-> tools; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + NoopSeven_before_model -.-> tools; + __start__ --> NoopSeven_before_model; + model_request --> NoopEight_after_model; + tools -.-> NoopSeven_before_model; + tools -.-> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- +# name: test_create_agent_jump[sqlite] + ''' + --- + config: + flowchart: + curve: linear + --- + graph TD; + __start__([

__start__

]):::first + model_request(model_request) + tools(tools) + NoopSeven_before_model(NoopSeven.before_model) + NoopSeven_after_model(NoopSeven.after_model) + NoopEight_before_model(NoopEight.before_model) + NoopEight_after_model(NoopEight.after_model) + __end__([

__end__

]):::last + NoopEight_after_model -.-> NoopSeven_after_model; + NoopEight_after_model -.-> NoopSeven_before_model; + NoopEight_after_model -.-> __end__; + NoopEight_after_model -.-> tools; + NoopEight_before_model -.-> NoopSeven_before_model; + NoopEight_before_model -.-> __end__; + NoopEight_before_model -.-> model_request; + NoopEight_before_model -.-> tools; + NoopSeven_after_model -.-> NoopSeven_before_model; + NoopSeven_after_model -.-> __end__; + NoopSeven_after_model -.-> tools; + NoopSeven_before_model -.-> NoopEight_before_model; + NoopSeven_before_model -.-> __end__; + NoopSeven_before_model -.-> tools; + __start__ --> NoopSeven_before_model; + model_request --> NoopEight_after_model; + tools -.-> NoopSeven_before_model; + tools -.-> __end__; + classDef default fill:#f2f0ff,line-height:1.2 + classDef first fill-opacity:0 + classDef last fill:#bfb6fc + + ''' +# --- diff --git a/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py b/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py new file mode 100644 index 00000000000..02956f612ee --- /dev/null +++ b/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py @@ -0,0 +1,712 @@ +import pytest +from typing import Any +from unittest.mock import patch + +from syrupy.assertion import SnapshotAssertion + +from langchain_core.language_models import BaseChatModel +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_core.messages import ( + AIMessage, + HumanMessage, + RemoveMessage, + ToolCall, + ToolMessage, +) +from langchain_core.tools import tool + +from langchain.agents.middleware_agent import create_agent +from langchain.agents.middleware.human_in_the_loop import HumanInTheLoopMiddleware +from langchain.agents.middleware.prompt_caching import AnthropicPromptCachingMiddleware +from langchain.agents.middleware.summarization import SummarizationMiddleware +from langchain.agents.middleware.types import AgentMiddleware, ModelRequest + +from langgraph.checkpoint.base import BaseCheckpointSaver +from langgraph.checkpoint.memory import InMemorySaver +from langgraph.constants import END +from langgraph.graph.message import REMOVE_ALL_MESSAGES +from langgraph.prebuilt.interrupt import ActionRequest, HumanInterruptConfig + +from .messages import _AnyIdHumanMessage, _AnyIdToolMessage +from .model import FakeToolCallingModel + + +def test_create_agent_diagram( + snapshot: SnapshotAssertion, +): + class NoopOne(AgentMiddleware): + def before_model(self, state): + pass + + class NoopTwo(AgentMiddleware): + def before_model(self, state): + pass + + class NoopThree(AgentMiddleware): + def before_model(self, state): + pass + + class NoopFour(AgentMiddleware): + def after_model(self, state): + pass + + class NoopFive(AgentMiddleware): + def after_model(self, state): + pass + + class NoopSix(AgentMiddleware): + def after_model(self, state): + pass + + class NoopSeven(AgentMiddleware): + def before_model(self, state): + pass + + def after_model(self, state): + pass + + class NoopEight(AgentMiddleware): + def before_model(self, state): + pass + + def after_model(self, state): + pass + + class NoopNine(AgentMiddleware): + def before_model(self, state): + pass + + def after_model(self, state): + pass + + class NoopTen(AgentMiddleware): + def before_model(self, state): + pass + + def modify_model_request(self, request, state): + pass + + def after_model(self, state): + pass + + class NoopEleven(AgentMiddleware): + def before_model(self, state): + pass + + def modify_model_request(self, request, state): + pass + + def after_model(self, state): + pass + + agent_zero = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + ) + + assert agent_zero.compile().get_graph().draw_mermaid() == snapshot + + agent_one = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopOne()], + ) + + assert agent_one.compile().get_graph().draw_mermaid() == snapshot + + agent_two = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopOne(), NoopTwo()], + ) + + assert agent_two.compile().get_graph().draw_mermaid() == snapshot + + agent_three = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopOne(), NoopTwo(), NoopThree()], + ) + + assert agent_three.compile().get_graph().draw_mermaid() == snapshot + + agent_four = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopFour()], + ) + + assert agent_four.compile().get_graph().draw_mermaid() == snapshot + + agent_five = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopFour(), NoopFive()], + ) + + assert agent_five.compile().get_graph().draw_mermaid() == snapshot + + agent_six = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopFour(), NoopFive(), NoopSix()], + ) + + assert agent_six.compile().get_graph().draw_mermaid() == snapshot + + agent_seven = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopSeven()], + ) + + assert agent_seven.compile().get_graph().draw_mermaid() == snapshot + + agent_eight = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopSeven(), NoopEight()], + ) + + assert agent_eight.compile().get_graph().draw_mermaid() == snapshot + + agent_nine = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopSeven(), NoopEight(), NoopNine()], + ) + + assert agent_nine.compile().get_graph().draw_mermaid() == snapshot + + agent_ten = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopTen()], + ) + + assert agent_ten.compile().get_graph().draw_mermaid() == snapshot + + agent_eleven = create_agent( + model=FakeToolCallingModel(), + tools=[], + system_prompt="You are a helpful assistant.", + middleware=[NoopTen(), NoopEleven()], + ) + + assert agent_eleven.compile().get_graph().draw_mermaid() == snapshot + + +def test_create_agent_invoke( + snapshot: SnapshotAssertion, + sync_checkpointer: BaseCheckpointSaver, +): + calls = [] + + class NoopSeven(AgentMiddleware): + def before_model(self, state): + calls.append("NoopSeven.before_model") + + def modify_model_request(self, request, state): + calls.append("NoopSeven.modify_model_request") + return request + + def after_model(self, state): + calls.append("NoopSeven.after_model") + + class NoopEight(AgentMiddleware): + def before_model(self, state): + calls.append("NoopEight.before_model") + + def modify_model_request(self, request, state): + calls.append("NoopEight.modify_model_request") + return request + + def after_model(self, state): + calls.append("NoopEight.after_model") + + @tool + def my_tool(input: str) -> str: + """A great tool""" + calls.append("my_tool") + return input.upper() + + agent_one = create_agent( + model=FakeToolCallingModel( + tool_calls=[ + [ + {"args": {"input": "yo"}, "id": "1", "name": "my_tool"}, + ], + [], + ] + ), + tools=[my_tool], + system_prompt="You are a helpful assistant.", + middleware=[NoopSeven(), NoopEight()], + ).compile(checkpointer=sync_checkpointer) + + thread1 = {"configurable": {"thread_id": "1"}} + assert agent_one.invoke({"messages": ["hello"]}, thread1) == { + "messages": [ + _AnyIdHumanMessage(content="hello"), + AIMessage( + content="You are a helpful assistant.-hello", + additional_kwargs={}, + response_metadata={}, + id="0", + tool_calls=[ + { + "name": "my_tool", + "args": {"input": "yo"}, + "id": "1", + "type": "tool_call", + } + ], + ), + _AnyIdToolMessage(content="YO", name="my_tool", tool_call_id="1"), + AIMessage( + content="You are a helpful assistant.-hello-You are a helpful assistant.-hello-YO", + additional_kwargs={}, + response_metadata={}, + id="1", + ), + ], + } + assert calls == [ + "NoopSeven.before_model", + "NoopEight.before_model", + "NoopSeven.modify_model_request", + "NoopEight.modify_model_request", + "NoopEight.after_model", + "NoopSeven.after_model", + "my_tool", + "NoopSeven.before_model", + "NoopEight.before_model", + "NoopSeven.modify_model_request", + "NoopEight.modify_model_request", + "NoopEight.after_model", + "NoopSeven.after_model", + ] + + +def test_create_agent_jump( + snapshot: SnapshotAssertion, + sync_checkpointer: BaseCheckpointSaver, +): + calls = [] + + class NoopSeven(AgentMiddleware): + def before_model(self, state): + calls.append("NoopSeven.before_model") + + def modify_model_request(self, request, state): + calls.append("NoopSeven.modify_model_request") + return request + + def after_model(self, state): + calls.append("NoopSeven.after_model") + + class NoopEight(AgentMiddleware): + def before_model(self, state) -> dict[str, Any]: + calls.append("NoopEight.before_model") + return {"jump_to": END} + + def modify_model_request(self, request, state) -> ModelRequest: + calls.append("NoopEight.modify_model_request") + return request + + def after_model(self, state): + calls.append("NoopEight.after_model") + + @tool + def my_tool(input: str) -> str: + """A great tool""" + calls.append("my_tool") + return input.upper() + + agent_one = create_agent( + model=FakeToolCallingModel( + tool_calls=[[ToolCall(id="1", name="my_tool", args={"input": "yo"})]], + ), + tools=[my_tool], + system_prompt="You are a helpful assistant.", + middleware=[NoopSeven(), NoopEight()], + ).compile(checkpointer=sync_checkpointer) + + if isinstance(sync_checkpointer, InMemorySaver): + assert agent_one.get_graph().draw_mermaid() == snapshot + + thread1 = {"configurable": {"thread_id": "1"}} + assert agent_one.invoke({"messages": []}, thread1) == {"messages": []} + assert calls == ["NoopSeven.before_model", "NoopEight.before_model"] + + +# Tests for HumanInTheLoopMiddleware +def test_human_in_the_loop_middleware_initialization() -> None: + """Test HumanInTheLoopMiddleware initialization.""" + tool_configs = { + "test_tool": HumanInterruptConfig( + allow_ignore=True, allow_respond=True, allow_edit=True, allow_accept=True + ) + } + + middleware = HumanInTheLoopMiddleware(tool_configs=tool_configs, message_prefix="Custom prefix") + + assert middleware.tool_configs == tool_configs + assert middleware.message_prefix == "Custom prefix" + + +def test_human_in_the_loop_middleware_no_interrupts_needed() -> None: + """Test HumanInTheLoopMiddleware when no interrupts are needed.""" + tool_configs = { + "test_tool": HumanInterruptConfig( + allow_ignore=True, allow_respond=True, allow_edit=True, allow_accept=True + ) + } + + middleware = HumanInTheLoopMiddleware(tool_configs=tool_configs) + + # Test with no messages + state: dict[str, Any] = {"messages": []} + result = middleware.after_model(state) + assert result is None + + # Test with message but no tool calls + state = {"messages": [HumanMessage(content="Hello"), AIMessage(content="Hi there")]} + result = middleware.after_model(state) + assert result is None + + # Test with tool calls that don't require interrupts + ai_message = AIMessage( + content="I'll help you", + tool_calls=[{"name": "other_tool", "args": {"input": "test"}, "id": "1"}], + ) + state = {"messages": [HumanMessage(content="Hello"), ai_message]} + result = middleware.after_model(state) + assert result is None + + +def test_human_in_the_loop_middleware_interrupt_responses() -> None: + """Test HumanInTheLoopMiddleware with different interrupt response types.""" + tool_configs = { + "test_tool": HumanInterruptConfig( + allow_ignore=True, allow_respond=True, allow_edit=True, allow_accept=True + ) + } + + middleware = HumanInTheLoopMiddleware(tool_configs=tool_configs) + + ai_message = AIMessage( + content="I'll help you", + tool_calls=[{"name": "test_tool", "args": {"input": "test"}, "id": "1"}], + ) + state = {"messages": [HumanMessage(content="Hello"), ai_message]} + + # Test accept response + def mock_accept(requests): + return [{"type": "accept", "args": None}] + + with patch("langchain.agents.middleware.human_in_the_loop.interrupt", side_effect=mock_accept): + result = middleware.after_model(state) + assert result is not None + assert result["messages"][0] == ai_message + assert result["messages"][0].tool_calls == ai_message.tool_calls + + # Test edit response + def mock_edit(requests): + return [ + {"type": "edit", "args": ActionRequest(action="test_tool", args={"input": "edited"})} + ] + + with patch("langchain.agents.middleware.human_in_the_loop.interrupt", side_effect=mock_edit): + result = middleware.after_model(state) + assert result is not None + assert result["messages"][0].tool_calls[0]["args"] == {"input": "edited"} + + # Test ignore response + def mock_ignore(requests): + return [{"type": "ignore", "args": None}] + + with patch("langchain.agents.middleware.human_in_the_loop.interrupt", side_effect=mock_ignore): + result = middleware.after_model(state) + assert result is not None + assert result["jump_to"] == "__end__" + + # Test response type + def mock_response(requests): + return [{"type": "response", "args": "Custom response"}] + + with patch( + "langchain.agents.middleware.human_in_the_loop.interrupt", side_effect=mock_response + ): + result = middleware.after_model(state) + assert result is not None + assert result["jump_to"] == "model" + assert result["messages"][0]["role"] == "tool" + assert result["messages"][0]["content"] == "Custom response" + + # Test unknown response type + def mock_unknown(requests): + return [{"type": "unknown", "args": None}] + + with patch("langchain.agents.middleware.human_in_the_loop.interrupt", side_effect=mock_unknown): + with pytest.raises(ValueError, match="Unknown response type: unknown"): + middleware.after_model(state) + + +# Tests for AnthropicPromptCachingMiddleware +def test_anthropic_prompt_caching_middleware_initialization() -> None: + """Test AnthropicPromptCachingMiddleware initialization.""" + # Test with custom values + middleware = AnthropicPromptCachingMiddleware( + type="ephemeral", ttl="1h", min_messages_to_cache=5 + ) + assert middleware.type == "ephemeral" + assert middleware.ttl == "1h" + assert middleware.min_messages_to_cache == 5 + + # Test with default values + middleware = AnthropicPromptCachingMiddleware() + assert middleware.type == "ephemeral" + assert middleware.ttl == "5m" + assert middleware.min_messages_to_cache == 0 + + +# Tests for SummarizationMiddleware +def test_summarization_middleware_initialization() -> None: + """Test SummarizationMiddleware initialization.""" + model = FakeToolCallingModel() + middleware = SummarizationMiddleware( + model=model, + max_tokens_before_summary=1000, + messages_to_keep=10, + summary_prompt="Custom prompt: {messages}", + summary_prefix="Custom prefix:", + ) + + assert middleware.model == model + assert middleware.max_tokens_before_summary == 1000 + assert middleware.messages_to_keep == 10 + assert middleware.summary_prompt == "Custom prompt: {messages}" + assert middleware.summary_prefix == "Custom prefix:" + + # Test with string model + with patch( + "langchain.agents.middleware.summarization.init_chat_model", + return_value=FakeToolCallingModel(), + ): + middleware = SummarizationMiddleware(model="fake-model") + assert isinstance(middleware.model, FakeToolCallingModel) + + +def test_summarization_middleware_no_summarization_cases() -> None: + """Test SummarizationMiddleware when summarization is not needed or disabled.""" + model = FakeToolCallingModel() + middleware = SummarizationMiddleware(model=model, max_tokens_before_summary=1000) + + # Test when summarization is disabled + middleware_disabled = SummarizationMiddleware(model=model, max_tokens_before_summary=None) + state = {"messages": [HumanMessage(content="Hello"), AIMessage(content="Hi")]} + result = middleware_disabled.before_model(state) + assert result is None + + # Test when token count is below threshold + def mock_token_counter(messages): + return 500 # Below threshold + + middleware.token_counter = mock_token_counter + result = middleware.before_model(state) + assert result is None + + +def test_summarization_middleware_helper_methods() -> None: + """Test SummarizationMiddleware helper methods.""" + model = FakeToolCallingModel() + middleware = SummarizationMiddleware(model=model, max_tokens_before_summary=1000) + + # Test message ID assignment + messages = [HumanMessage(content="Hello"), AIMessage(content="Hi")] + middleware._ensure_message_ids(messages) + for msg in messages: + assert msg.id is not None + + # Test message partitioning + messages = [ + HumanMessage(content="1"), + HumanMessage(content="2"), + HumanMessage(content="3"), + HumanMessage(content="4"), + HumanMessage(content="5"), + ] + to_summarize, preserved = middleware._partition_messages(messages, 2) + assert len(to_summarize) == 2 + assert len(preserved) == 3 + assert to_summarize == messages[:2] + assert preserved == messages[2:] + + # Test summary message building + summary = "This is a test summary" + new_messages = middleware._build_new_messages(summary) + assert len(new_messages) == 1 + assert isinstance(new_messages[0], HumanMessage) + assert "Here is a summary of the conversation to date:" in new_messages[0].content + assert summary in new_messages[0].content + + # Test tool call detection + ai_message_no_tools = AIMessage(content="Hello") + assert not middleware._has_tool_calls(ai_message_no_tools) + + ai_message_with_tools = AIMessage( + content="Hello", tool_calls=[{"name": "test", "args": {}, "id": "1"}] + ) + assert middleware._has_tool_calls(ai_message_with_tools) + + human_message = HumanMessage(content="Hello") + assert not middleware._has_tool_calls(human_message) + + +def test_summarization_middleware_tool_call_safety() -> None: + """Test SummarizationMiddleware tool call safety logic.""" + model = FakeToolCallingModel() + middleware = SummarizationMiddleware( + model=model, max_tokens_before_summary=1000, messages_to_keep=3 + ) + + # Test safe cutoff point detection with tool calls + messages = [ + HumanMessage(content="1"), + AIMessage(content="2", tool_calls=[{"name": "test", "args": {}, "id": "1"}]), + ToolMessage(content="3", tool_call_id="1"), + HumanMessage(content="4"), + ] + + # Safe cutoff (doesn't separate AI/Tool pair) + is_safe = middleware._is_safe_cutoff_point(messages, 0) + assert is_safe is True + + # Unsafe cutoff (separates AI/Tool pair) + is_safe = middleware._is_safe_cutoff_point(messages, 2) + assert is_safe is False + + # Test tool call ID extraction + ids = middleware._extract_tool_call_ids(messages[1]) + assert ids == {"1"} + + +def test_summarization_middleware_summary_creation() -> None: + """Test SummarizationMiddleware summary creation.""" + + class MockModel(BaseChatModel): + def invoke(self, prompt): + from langchain_core.messages import AIMessage + + return AIMessage(content="Generated summary") + + def _generate(self, messages, **kwargs): + from langchain_core.outputs import ChatResult, ChatGeneration + from langchain_core.messages import AIMessage + + return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))]) + + @property + def _llm_type(self): + return "mock" + + middleware = SummarizationMiddleware(model=MockModel(), max_tokens_before_summary=1000) + + # Test normal summary creation + messages = [HumanMessage(content="Hello"), AIMessage(content="Hi")] + summary = middleware._create_summary(messages) + assert summary == "Generated summary" + + # Test empty messages + summary = middleware._create_summary([]) + assert summary == "No previous conversation history." + + # Test error handling + class ErrorModel(BaseChatModel): + def invoke(self, prompt): + raise Exception("Model error") + + def _generate(self, messages, **kwargs): + from langchain_core.outputs import ChatResult, ChatGeneration + from langchain_core.messages import AIMessage + + return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))]) + + @property + def _llm_type(self): + return "mock" + + middleware_error = SummarizationMiddleware(model=ErrorModel(), max_tokens_before_summary=1000) + summary = middleware_error._create_summary(messages) + assert "Error generating summary: Model error" in summary + + +def test_summarization_middleware_full_workflow() -> None: + """Test SummarizationMiddleware complete summarization workflow.""" + + class MockModel(BaseChatModel): + def invoke(self, prompt): + from langchain_core.messages import AIMessage + + return AIMessage(content="Generated summary") + + def _generate(self, messages, **kwargs): + from langchain_core.outputs import ChatResult, ChatGeneration + from langchain_core.messages import AIMessage + + return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))]) + + @property + def _llm_type(self): + return "mock" + + middleware = SummarizationMiddleware( + model=MockModel(), max_tokens_before_summary=1000, messages_to_keep=2 + ) + + # Mock high token count to trigger summarization + def mock_token_counter(messages): + return 1500 # Above threshold + + middleware.token_counter = mock_token_counter + + messages = [ + HumanMessage(content="1"), + HumanMessage(content="2"), + HumanMessage(content="3"), + HumanMessage(content="4"), + HumanMessage(content="5"), + ] + + state = {"messages": messages} + result = middleware.before_model(state) + + assert result is not None + assert "messages" in result + assert len(result["messages"]) > 0 + + # Should have RemoveMessage for cleanup + assert isinstance(result["messages"][0], RemoveMessage) + assert result["messages"][0].id == REMOVE_ALL_MESSAGES + + # Should have summary message + summary_message = None + for msg in result["messages"]: + if isinstance(msg, HumanMessage) and "summary of the conversation" in msg.content: + summary_message = msg + break + + assert summary_message is not None + assert "Generated summary" in summary_message.content diff --git a/libs/langchain_v1/uv.lock b/libs/langchain_v1/uv.lock index 5cae5e0d6b3..9f7450a6d58 100644 --- a/libs/langchain_v1/uv.lock +++ b/libs/langchain_v1/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", @@ -131,7 +131,7 @@ wheels = [ [[package]] name = "anthropic" -version = "0.64.0" +version = "0.66.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -142,9 +142,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/4f/f2b880cba1a76f3acc7d5eb2ae217632eac1b8cef5ed3027493545c59eba/anthropic-0.64.0.tar.gz", hash = "sha256:3d496c91a63dff64f451b3e8e4b238a9640bf87b0c11d0b74ddc372ba5a3fe58", size = 427893, upload-time = "2025-08-13T17:09:49.915Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/50/daa51c035e6a941f7b8034705796c7643443a85f5381cb41a797757fc6d3/anthropic-0.66.0.tar.gz", hash = "sha256:5aa8b18da57dc27d83fc1d82c9fb860977e5adfae3e0c215d7ab2ebd70afb9cb", size = 436933, upload-time = "2025-09-03T14:55:40.879Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/b2/2d268bcd5d6441df9dc0ebebc67107657edb8b0150d3fda1a5b81d1bec45/anthropic-0.64.0-py3-none-any.whl", hash = "sha256:6f5f7d913a6a95eb7f8e1bda4e75f76670e8acd8d4cd965e02e2a256b0429dd1", size = 297244, upload-time = "2025-08-13T17:09:47.908Z" }, + { url = "https://files.pythonhosted.org/packages/00/6a/d4ec7de9cc88b9a39c74dab1db259203b29b17fc564ecd1f92991678bd1e/anthropic-0.66.0-py3-none-any.whl", hash = "sha256:67b8cd4486f3cdd09211598dc5325cc8e4e349c106a03041231d551603551c06", size = 308035, upload-time = "2025-09-03T14:55:39.109Z" }, ] [[package]] @@ -266,30 +266,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.40.18" +version = "1.40.25" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/36/35/a30dc21ca6582358e0ce963f38e85d42ea619f12e7be4101a834c21d749d/boto3-1.40.18.tar.gz", hash = "sha256:64301d39adecc154e3e595eaf0d4f28998ef0a5551f1d033aeac51a9e1a688e5", size = 111994, upload-time = "2025-08-26T19:21:38.61Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/36/de7e622fd7907faec3823eaee7299b55130f577a4ba609717a290e9f3897/boto3-1.40.25.tar.gz", hash = "sha256:debfa4b2c67492d53629a52c999d71cddc31041a8b62ca1a8b1fb60fb0712ee1", size = 111534, upload-time = "2025-09-05T19:23:21.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/b5/3fc1802eb24aef135c3ba69fff2a9bfcc6a7a8258fb396706b1a6a44de36/boto3-1.40.18-py3-none-any.whl", hash = "sha256:daa776ba1251a7458c9d6c7627873d0c2460c8e8272d35759065580e9193700a", size = 140076, upload-time = "2025-08-26T19:21:36.484Z" }, + { url = "https://files.pythonhosted.org/packages/c7/9a/6b280f01f5ec7e812ac8be9803bf52868b190e15c500bee3319d9d68eb34/boto3-1.40.25-py3-none-any.whl", hash = "sha256:d39bc3deb6780d910f00580837b720132055b0604769fd978780865ed3c019ea", size = 139325, upload-time = "2025-09-05T19:23:20.551Z" }, ] [[package]] name = "botocore" -version = "1.40.18" +version = "1.40.25" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/91/2e745382793fa7d30810a7d5ca3e05f6817b6db07601ca5aaab12720caf9/botocore-1.40.18.tar.gz", hash = "sha256:afd69bdadd8c55cc89d69de0799829e555193a352d87867f746e19020271cc0f", size = 14375007, upload-time = "2025-08-26T19:21:24.996Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/ba/7faa7e1061c2d2d60700815928ec0e5a7eeb83c5311126eccc6125e1797b/botocore-1.40.25.tar.gz", hash = "sha256:41fd186018a48dc517a4312a8d3085d548cb3fb1f463972134140bf7ee55a397", size = 14331329, upload-time = "2025-09-05T19:23:12.37Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/f5/bd57bf21fdcc4e500cc406ed2c296e626ddd160f0fee2a4932256e5d62d8/botocore-1.40.18-py3-none-any.whl", hash = "sha256:57025c46ca00cf8cec25de07a759521bfbfb3036a0f69b272654a354615dc45f", size = 14039935, upload-time = "2025-08-26T19:21:19.085Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/4c32b35109bc3f8f8ebe3d78f952d2bf702bacce975a45997cc268c11860/botocore-1.40.25-py3-none-any.whl", hash = "sha256:5603ea9955cd31974446f0b5688911a5dad71fbdfbf7457944cda8a83fcf2a9e", size = 14003384, upload-time = "2025-09-05T19:23:09.731Z" }, ] [[package]] @@ -554,87 +554,87 @@ wheels = [ [[package]] name = "coverage" -version = "7.10.5" +version = "7.10.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/61/83/153f54356c7c200013a752ce1ed5448573dca546ce125801afca9e1ac1a4/coverage-7.10.5.tar.gz", hash = "sha256:f2e57716a78bc3ae80b2207be0709a3b2b63b9f2dcf9740ee6ac03588a2015b6", size = 821662, upload-time = "2025-08-23T14:42:44.78Z" } +sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/70/e77b0061a6c7157bfce645c6b9a715a08d4c86b3360a7b3252818080b817/coverage-7.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c6a5c3414bfc7451b879141ce772c546985163cf553f08e0f135f0699a911801", size = 216774, upload-time = "2025-08-23T14:40:26.301Z" }, - { url = "https://files.pythonhosted.org/packages/91/08/2a79de5ecf37ee40f2d898012306f11c161548753391cec763f92647837b/coverage-7.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bc8e4d99ce82f1710cc3c125adc30fd1487d3cf6c2cd4994d78d68a47b16989a", size = 217175, upload-time = "2025-08-23T14:40:29.142Z" }, - { url = "https://files.pythonhosted.org/packages/64/57/0171d69a699690149a6ba6a4eb702814448c8d617cf62dbafa7ce6bfdf63/coverage-7.10.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:02252dc1216e512a9311f596b3169fad54abcb13827a8d76d5630c798a50a754", size = 243931, upload-time = "2025-08-23T14:40:30.735Z" }, - { url = "https://files.pythonhosted.org/packages/15/06/3a67662c55656702bd398a727a7f35df598eb11104fcb34f1ecbb070291a/coverage-7.10.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:73269df37883e02d460bee0cc16be90509faea1e3bd105d77360b512d5bb9c33", size = 245740, upload-time = "2025-08-23T14:40:32.302Z" }, - { url = "https://files.pythonhosted.org/packages/00/f4/f8763aabf4dc30ef0d0012522d312f0b7f9fede6246a1f27dbcc4a1e523c/coverage-7.10.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f8a81b0614642f91c9effd53eec284f965577591f51f547a1cbeb32035b4c2f", size = 247600, upload-time = "2025-08-23T14:40:33.66Z" }, - { url = "https://files.pythonhosted.org/packages/9c/31/6632219a9065e1b83f77eda116fed4c76fb64908a6a9feae41816dab8237/coverage-7.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6a29f8e0adb7f8c2b95fa2d4566a1d6e6722e0a637634c6563cb1ab844427dd9", size = 245640, upload-time = "2025-08-23T14:40:35.248Z" }, - { url = "https://files.pythonhosted.org/packages/6e/e2/3dba9b86037b81649b11d192bb1df11dde9a81013e434af3520222707bc8/coverage-7.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fcf6ab569436b4a647d4e91accba12509ad9f2554bc93d3aee23cc596e7f99c3", size = 243659, upload-time = "2025-08-23T14:40:36.815Z" }, - { url = "https://files.pythonhosted.org/packages/02/b9/57170bd9f3e333837fc24ecc88bc70fbc2eb7ccfd0876854b0c0407078c3/coverage-7.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:90dc3d6fb222b194a5de60af8d190bedeeddcbc7add317e4a3cd333ee6b7c879", size = 244537, upload-time = "2025-08-23T14:40:38.737Z" }, - { url = "https://files.pythonhosted.org/packages/b3/1c/93ac36ef1e8b06b8d5777393a3a40cb356f9f3dab980be40a6941e443588/coverage-7.10.5-cp310-cp310-win32.whl", hash = "sha256:414a568cd545f9dc75f0686a0049393de8098414b58ea071e03395505b73d7a8", size = 219285, upload-time = "2025-08-23T14:40:40.342Z" }, - { url = "https://files.pythonhosted.org/packages/30/95/23252277e6e5fe649d6cd3ed3f35d2307e5166de4e75e66aa7f432abc46d/coverage-7.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:e551f9d03347196271935fd3c0c165f0e8c049220280c1120de0084d65e9c7ff", size = 220185, upload-time = "2025-08-23T14:40:42.026Z" }, - { url = "https://files.pythonhosted.org/packages/cb/f2/336d34d2fc1291ca7c18eeb46f64985e6cef5a1a7ef6d9c23720c6527289/coverage-7.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c177e6ffe2ebc7c410785307758ee21258aa8e8092b44d09a2da767834f075f2", size = 216890, upload-time = "2025-08-23T14:40:43.627Z" }, - { url = "https://files.pythonhosted.org/packages/39/ea/92448b07cc1cf2b429d0ce635f59cf0c626a5d8de21358f11e92174ff2a6/coverage-7.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:14d6071c51ad0f703d6440827eaa46386169b5fdced42631d5a5ac419616046f", size = 217287, upload-time = "2025-08-23T14:40:45.214Z" }, - { url = "https://files.pythonhosted.org/packages/96/ba/ad5b36537c5179c808d0ecdf6e4aa7630b311b3c12747ad624dcd43a9b6b/coverage-7.10.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:61f78c7c3bc272a410c5ae3fde7792b4ffb4acc03d35a7df73ca8978826bb7ab", size = 247683, upload-time = "2025-08-23T14:40:46.791Z" }, - { url = "https://files.pythonhosted.org/packages/28/e5/fe3bbc8d097029d284b5fb305b38bb3404895da48495f05bff025df62770/coverage-7.10.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f39071caa126f69d63f99b324fb08c7b1da2ec28cbb1fe7b5b1799926492f65c", size = 249614, upload-time = "2025-08-23T14:40:48.082Z" }, - { url = "https://files.pythonhosted.org/packages/69/9c/a1c89a8c8712799efccb32cd0a1ee88e452f0c13a006b65bb2271f1ac767/coverage-7.10.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343a023193f04d46edc46b2616cdbee68c94dd10208ecd3adc56fcc54ef2baa1", size = 251719, upload-time = "2025-08-23T14:40:49.349Z" }, - { url = "https://files.pythonhosted.org/packages/e9/be/5576b5625865aa95b5633315f8f4142b003a70c3d96e76f04487c3b5cc95/coverage-7.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:585ffe93ae5894d1ebdee69fc0b0d4b7c75d8007983692fb300ac98eed146f78", size = 249411, upload-time = "2025-08-23T14:40:50.624Z" }, - { url = "https://files.pythonhosted.org/packages/94/0a/e39a113d4209da0dbbc9385608cdb1b0726a4d25f78672dc51c97cfea80f/coverage-7.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0ef4e66f006ed181df29b59921bd8fc7ed7cd6a9289295cd8b2824b49b570df", size = 247466, upload-time = "2025-08-23T14:40:52.362Z" }, - { url = "https://files.pythonhosted.org/packages/40/cb/aebb2d8c9e3533ee340bea19b71c5b76605a0268aa49808e26fe96ec0a07/coverage-7.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eb7b0bbf7cc1d0453b843eca7b5fa017874735bef9bfdfa4121373d2cc885ed6", size = 248104, upload-time = "2025-08-23T14:40:54.064Z" }, - { url = "https://files.pythonhosted.org/packages/08/e6/26570d6ccce8ff5de912cbfd268e7f475f00597cb58da9991fa919c5e539/coverage-7.10.5-cp311-cp311-win32.whl", hash = "sha256:1d043a8a06987cc0c98516e57c4d3fc2c1591364831e9deb59c9e1b4937e8caf", size = 219327, upload-time = "2025-08-23T14:40:55.424Z" }, - { url = "https://files.pythonhosted.org/packages/79/79/5f48525e366e518b36e66167e3b6e5db6fd54f63982500c6a5abb9d3dfbd/coverage-7.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:fefafcca09c3ac56372ef64a40f5fe17c5592fab906e0fdffd09543f3012ba50", size = 220213, upload-time = "2025-08-23T14:40:56.724Z" }, - { url = "https://files.pythonhosted.org/packages/40/3c/9058128b7b0bf333130c320b1eb1ae485623014a21ee196d68f7737f8610/coverage-7.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:7e78b767da8b5fc5b2faa69bb001edafcd6f3995b42a331c53ef9572c55ceb82", size = 218893, upload-time = "2025-08-23T14:40:58.011Z" }, - { url = "https://files.pythonhosted.org/packages/27/8e/40d75c7128f871ea0fd829d3e7e4a14460cad7c3826e3b472e6471ad05bd/coverage-7.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c2d05c7e73c60a4cecc7d9b60dbfd603b4ebc0adafaef371445b47d0f805c8a9", size = 217077, upload-time = "2025-08-23T14:40:59.329Z" }, - { url = "https://files.pythonhosted.org/packages/18/a8/f333f4cf3fb5477a7f727b4d603a2eb5c3c5611c7fe01329c2e13b23b678/coverage-7.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:32ddaa3b2c509778ed5373b177eb2bf5662405493baeff52278a0b4f9415188b", size = 217310, upload-time = "2025-08-23T14:41:00.628Z" }, - { url = "https://files.pythonhosted.org/packages/ec/2c/fbecd8381e0a07d1547922be819b4543a901402f63930313a519b937c668/coverage-7.10.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dd382410039fe062097aa0292ab6335a3f1e7af7bba2ef8d27dcda484918f20c", size = 248802, upload-time = "2025-08-23T14:41:02.012Z" }, - { url = "https://files.pythonhosted.org/packages/3f/bc/1011da599b414fb6c9c0f34086736126f9ff71f841755786a6b87601b088/coverage-7.10.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7fa22800f3908df31cea6fb230f20ac49e343515d968cc3a42b30d5c3ebf9b5a", size = 251550, upload-time = "2025-08-23T14:41:03.438Z" }, - { url = "https://files.pythonhosted.org/packages/4c/6f/b5c03c0c721c067d21bc697accc3642f3cef9f087dac429c918c37a37437/coverage-7.10.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f366a57ac81f5e12797136552f5b7502fa053c861a009b91b80ed51f2ce651c6", size = 252684, upload-time = "2025-08-23T14:41:04.85Z" }, - { url = "https://files.pythonhosted.org/packages/f9/50/d474bc300ebcb6a38a1047d5c465a227605d6473e49b4e0d793102312bc5/coverage-7.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1dc8f1980a272ad4a6c84cba7981792344dad33bf5869361576b7aef42733a", size = 250602, upload-time = "2025-08-23T14:41:06.719Z" }, - { url = "https://files.pythonhosted.org/packages/4a/2d/548c8e04249cbba3aba6bd799efdd11eee3941b70253733f5d355d689559/coverage-7.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2285c04ee8676f7938b02b4936d9b9b672064daab3187c20f73a55f3d70e6b4a", size = 248724, upload-time = "2025-08-23T14:41:08.429Z" }, - { url = "https://files.pythonhosted.org/packages/e2/96/a7c3c0562266ac39dcad271d0eec8fc20ab576e3e2f64130a845ad2a557b/coverage-7.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2492e4dd9daab63f5f56286f8a04c51323d237631eb98505d87e4c4ff19ec34", size = 250158, upload-time = "2025-08-23T14:41:09.749Z" }, - { url = "https://files.pythonhosted.org/packages/f3/75/74d4be58c70c42ef0b352d597b022baf12dbe2b43e7cb1525f56a0fb1d4b/coverage-7.10.5-cp312-cp312-win32.whl", hash = "sha256:38a9109c4ee8135d5df5505384fc2f20287a47ccbe0b3f04c53c9a1989c2bbaf", size = 219493, upload-time = "2025-08-23T14:41:11.095Z" }, - { url = "https://files.pythonhosted.org/packages/4f/08/364e6012d1d4d09d1e27437382967efed971d7613f94bca9add25f0c1f2b/coverage-7.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:6b87f1ad60b30bc3c43c66afa7db6b22a3109902e28c5094957626a0143a001f", size = 220302, upload-time = "2025-08-23T14:41:12.449Z" }, - { url = "https://files.pythonhosted.org/packages/db/d5/7c8a365e1f7355c58af4fe5faf3f90cc8e587590f5854808d17ccb4e7077/coverage-7.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:672a6c1da5aea6c629819a0e1461e89d244f78d7b60c424ecf4f1f2556c041d8", size = 218936, upload-time = "2025-08-23T14:41:13.872Z" }, - { url = "https://files.pythonhosted.org/packages/9f/08/4166ecfb60ba011444f38a5a6107814b80c34c717bc7a23be0d22e92ca09/coverage-7.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ef3b83594d933020f54cf65ea1f4405d1f4e41a009c46df629dd964fcb6e907c", size = 217106, upload-time = "2025-08-23T14:41:15.268Z" }, - { url = "https://files.pythonhosted.org/packages/25/d7/b71022408adbf040a680b8c64bf6ead3be37b553e5844f7465643979f7ca/coverage-7.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b96bfdf7c0ea9faebce088a3ecb2382819da4fbc05c7b80040dbc428df6af44", size = 217353, upload-time = "2025-08-23T14:41:16.656Z" }, - { url = "https://files.pythonhosted.org/packages/74/68/21e0d254dbf8972bb8dd95e3fe7038f4be037ff04ba47d6d1b12b37510ba/coverage-7.10.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:63df1fdaffa42d914d5c4d293e838937638bf75c794cf20bee12978fc8c4e3bc", size = 248350, upload-time = "2025-08-23T14:41:18.128Z" }, - { url = "https://files.pythonhosted.org/packages/90/65/28752c3a896566ec93e0219fc4f47ff71bd2b745f51554c93e8dcb659796/coverage-7.10.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8002dc6a049aac0e81ecec97abfb08c01ef0c1fbf962d0c98da3950ace89b869", size = 250955, upload-time = "2025-08-23T14:41:19.577Z" }, - { url = "https://files.pythonhosted.org/packages/a5/eb/ca6b7967f57f6fef31da8749ea20417790bb6723593c8cd98a987be20423/coverage-7.10.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:63d4bb2966d6f5f705a6b0c6784c8969c468dbc4bcf9d9ded8bff1c7e092451f", size = 252230, upload-time = "2025-08-23T14:41:20.959Z" }, - { url = "https://files.pythonhosted.org/packages/bc/29/17a411b2a2a18f8b8c952aa01c00f9284a1fbc677c68a0003b772ea89104/coverage-7.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1f672efc0731a6846b157389b6e6d5d5e9e59d1d1a23a5c66a99fd58339914d5", size = 250387, upload-time = "2025-08-23T14:41:22.644Z" }, - { url = "https://files.pythonhosted.org/packages/c7/89/97a9e271188c2fbb3db82235c33980bcbc733da7da6065afbaa1d685a169/coverage-7.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3f39cef43d08049e8afc1fde4a5da8510fc6be843f8dea350ee46e2a26b2f54c", size = 248280, upload-time = "2025-08-23T14:41:24.061Z" }, - { url = "https://files.pythonhosted.org/packages/d1/c6/0ad7d0137257553eb4706b4ad6180bec0a1b6a648b092c5bbda48d0e5b2c/coverage-7.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2968647e3ed5a6c019a419264386b013979ff1fb67dd11f5c9886c43d6a31fc2", size = 249894, upload-time = "2025-08-23T14:41:26.165Z" }, - { url = "https://files.pythonhosted.org/packages/84/56/fb3aba936addb4c9e5ea14f5979393f1c2466b4c89d10591fd05f2d6b2aa/coverage-7.10.5-cp313-cp313-win32.whl", hash = "sha256:0d511dda38595b2b6934c2b730a1fd57a3635c6aa2a04cb74714cdfdd53846f4", size = 219536, upload-time = "2025-08-23T14:41:27.694Z" }, - { url = "https://files.pythonhosted.org/packages/fc/54/baacb8f2f74431e3b175a9a2881feaa8feb6e2f187a0e7e3046f3c7742b2/coverage-7.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:9a86281794a393513cf117177fd39c796b3f8e3759bb2764259a2abba5cce54b", size = 220330, upload-time = "2025-08-23T14:41:29.081Z" }, - { url = "https://files.pythonhosted.org/packages/64/8a/82a3788f8e31dee51d350835b23d480548ea8621f3effd7c3ba3f7e5c006/coverage-7.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:cebd8e906eb98bb09c10d1feed16096700b1198d482267f8bf0474e63a7b8d84", size = 218961, upload-time = "2025-08-23T14:41:30.511Z" }, - { url = "https://files.pythonhosted.org/packages/d8/a1/590154e6eae07beee3b111cc1f907c30da6fc8ce0a83ef756c72f3c7c748/coverage-7.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0520dff502da5e09d0d20781df74d8189ab334a1e40d5bafe2efaa4158e2d9e7", size = 217819, upload-time = "2025-08-23T14:41:31.962Z" }, - { url = "https://files.pythonhosted.org/packages/0d/ff/436ffa3cfc7741f0973c5c89405307fe39b78dcf201565b934e6616fc4ad/coverage-7.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d9cd64aca68f503ed3f1f18c7c9174cbb797baba02ca8ab5112f9d1c0328cd4b", size = 218040, upload-time = "2025-08-23T14:41:33.472Z" }, - { url = "https://files.pythonhosted.org/packages/a0/ca/5787fb3d7820e66273913affe8209c534ca11241eb34ee8c4fd2aaa9dd87/coverage-7.10.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0913dd1613a33b13c4f84aa6e3f4198c1a21ee28ccb4f674985c1f22109f0aae", size = 259374, upload-time = "2025-08-23T14:41:34.914Z" }, - { url = "https://files.pythonhosted.org/packages/b5/89/21af956843896adc2e64fc075eae3c1cadb97ee0a6960733e65e696f32dd/coverage-7.10.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1b7181c0feeb06ed8a02da02792f42f829a7b29990fef52eff257fef0885d760", size = 261551, upload-time = "2025-08-23T14:41:36.333Z" }, - { url = "https://files.pythonhosted.org/packages/e1/96/390a69244ab837e0ac137989277879a084c786cf036c3c4a3b9637d43a89/coverage-7.10.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36d42b7396b605f774d4372dd9c49bed71cbabce4ae1ccd074d155709dd8f235", size = 263776, upload-time = "2025-08-23T14:41:38.25Z" }, - { url = "https://files.pythonhosted.org/packages/00/32/cfd6ae1da0a521723349f3129b2455832fc27d3f8882c07e5b6fefdd0da2/coverage-7.10.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b4fdc777e05c4940b297bf47bf7eedd56a39a61dc23ba798e4b830d585486ca5", size = 261326, upload-time = "2025-08-23T14:41:40.343Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c4/bf8d459fb4ce2201e9243ce6c015936ad283a668774430a3755f467b39d1/coverage-7.10.5-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:42144e8e346de44a6f1dbd0a56575dd8ab8dfa7e9007da02ea5b1c30ab33a7db", size = 259090, upload-time = "2025-08-23T14:41:42.106Z" }, - { url = "https://files.pythonhosted.org/packages/f4/5d/a234f7409896468e5539d42234016045e4015e857488b0b5b5f3f3fa5f2b/coverage-7.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:66c644cbd7aed8fe266d5917e2c9f65458a51cfe5eeff9c05f15b335f697066e", size = 260217, upload-time = "2025-08-23T14:41:43.591Z" }, - { url = "https://files.pythonhosted.org/packages/f3/ad/87560f036099f46c2ddd235be6476dd5c1d6be6bb57569a9348d43eeecea/coverage-7.10.5-cp313-cp313t-win32.whl", hash = "sha256:2d1b73023854068c44b0c554578a4e1ef1b050ed07cf8b431549e624a29a66ee", size = 220194, upload-time = "2025-08-23T14:41:45.051Z" }, - { url = "https://files.pythonhosted.org/packages/36/a8/04a482594fdd83dc677d4a6c7e2d62135fff5a1573059806b8383fad9071/coverage-7.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:54a1532c8a642d8cc0bd5a9a51f5a9dcc440294fd06e9dda55e743c5ec1a8f14", size = 221258, upload-time = "2025-08-23T14:41:46.44Z" }, - { url = "https://files.pythonhosted.org/packages/eb/ad/7da28594ab66fe2bc720f1bc9b131e62e9b4c6e39f044d9a48d18429cc21/coverage-7.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:74d5b63fe3f5f5d372253a4ef92492c11a4305f3550631beaa432fc9df16fcff", size = 219521, upload-time = "2025-08-23T14:41:47.882Z" }, - { url = "https://files.pythonhosted.org/packages/d3/7f/c8b6e4e664b8a95254c35a6c8dd0bf4db201ec681c169aae2f1256e05c85/coverage-7.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:68c5e0bc5f44f68053369fa0d94459c84548a77660a5f2561c5e5f1e3bed7031", size = 217090, upload-time = "2025-08-23T14:41:49.327Z" }, - { url = "https://files.pythonhosted.org/packages/44/74/3ee14ede30a6e10a94a104d1d0522d5fb909a7c7cac2643d2a79891ff3b9/coverage-7.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cf33134ffae93865e32e1e37df043bef15a5e857d8caebc0099d225c579b0fa3", size = 217365, upload-time = "2025-08-23T14:41:50.796Z" }, - { url = "https://files.pythonhosted.org/packages/41/5f/06ac21bf87dfb7620d1f870dfa3c2cae1186ccbcdc50b8b36e27a0d52f50/coverage-7.10.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ad8fa9d5193bafcf668231294241302b5e683a0518bf1e33a9a0dfb142ec3031", size = 248413, upload-time = "2025-08-23T14:41:52.5Z" }, - { url = "https://files.pythonhosted.org/packages/21/bc/cc5bed6e985d3a14228539631573f3863be6a2587381e8bc5fdf786377a1/coverage-7.10.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:146fa1531973d38ab4b689bc764592fe6c2f913e7e80a39e7eeafd11f0ef6db2", size = 250943, upload-time = "2025-08-23T14:41:53.922Z" }, - { url = "https://files.pythonhosted.org/packages/8d/43/6a9fc323c2c75cd80b18d58db4a25dc8487f86dd9070f9592e43e3967363/coverage-7.10.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6013a37b8a4854c478d3219ee8bc2392dea51602dd0803a12d6f6182a0061762", size = 252301, upload-time = "2025-08-23T14:41:56.528Z" }, - { url = "https://files.pythonhosted.org/packages/69/7c/3e791b8845f4cd515275743e3775adb86273576596dc9f02dca37357b4f2/coverage-7.10.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:eb90fe20db9c3d930fa2ad7a308207ab5b86bf6a76f54ab6a40be4012d88fcae", size = 250302, upload-time = "2025-08-23T14:41:58.171Z" }, - { url = "https://files.pythonhosted.org/packages/5c/bc/5099c1e1cb0c9ac6491b281babea6ebbf999d949bf4aa8cdf4f2b53505e8/coverage-7.10.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:384b34482272e960c438703cafe63316dfbea124ac62006a455c8410bf2a2262", size = 248237, upload-time = "2025-08-23T14:41:59.703Z" }, - { url = "https://files.pythonhosted.org/packages/7e/51/d346eb750a0b2f1e77f391498b753ea906fde69cc11e4b38dca28c10c88c/coverage-7.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:467dc74bd0a1a7de2bedf8deaf6811f43602cb532bd34d81ffd6038d6d8abe99", size = 249726, upload-time = "2025-08-23T14:42:01.343Z" }, - { url = "https://files.pythonhosted.org/packages/a3/85/eebcaa0edafe427e93286b94f56ea7e1280f2c49da0a776a6f37e04481f9/coverage-7.10.5-cp314-cp314-win32.whl", hash = "sha256:556d23d4e6393ca898b2e63a5bca91e9ac2d5fb13299ec286cd69a09a7187fde", size = 219825, upload-time = "2025-08-23T14:42:03.263Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f7/6d43e037820742603f1e855feb23463979bf40bd27d0cde1f761dcc66a3e/coverage-7.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:f4446a9547681533c8fa3e3c6cf62121eeee616e6a92bd9201c6edd91beffe13", size = 220618, upload-time = "2025-08-23T14:42:05.037Z" }, - { url = "https://files.pythonhosted.org/packages/4a/b0/ed9432e41424c51509d1da603b0393404b828906236fb87e2c8482a93468/coverage-7.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:5e78bd9cf65da4c303bf663de0d73bf69f81e878bf72a94e9af67137c69b9fe9", size = 219199, upload-time = "2025-08-23T14:42:06.662Z" }, - { url = "https://files.pythonhosted.org/packages/2f/54/5a7ecfa77910f22b659c820f67c16fc1e149ed132ad7117f0364679a8fa9/coverage-7.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:5661bf987d91ec756a47c7e5df4fbcb949f39e32f9334ccd3f43233bbb65e508", size = 217833, upload-time = "2025-08-23T14:42:08.262Z" }, - { url = "https://files.pythonhosted.org/packages/4e/0e/25672d917cc57857d40edf38f0b867fb9627115294e4f92c8fcbbc18598d/coverage-7.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a46473129244db42a720439a26984f8c6f834762fc4573616c1f37f13994b357", size = 218048, upload-time = "2025-08-23T14:42:10.247Z" }, - { url = "https://files.pythonhosted.org/packages/cb/7c/0b2b4f1c6f71885d4d4b2b8608dcfc79057adb7da4143eb17d6260389e42/coverage-7.10.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1f64b8d3415d60f24b058b58d859e9512624bdfa57a2d1f8aff93c1ec45c429b", size = 259549, upload-time = "2025-08-23T14:42:11.811Z" }, - { url = "https://files.pythonhosted.org/packages/94/73/abb8dab1609abec7308d83c6aec547944070526578ee6c833d2da9a0ad42/coverage-7.10.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:44d43de99a9d90b20e0163f9770542357f58860a26e24dc1d924643bd6aa7cb4", size = 261715, upload-time = "2025-08-23T14:42:13.505Z" }, - { url = "https://files.pythonhosted.org/packages/0b/d1/abf31de21ec92731445606b8d5e6fa5144653c2788758fcf1f47adb7159a/coverage-7.10.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a931a87e5ddb6b6404e65443b742cb1c14959622777f2a4efd81fba84f5d91ba", size = 263969, upload-time = "2025-08-23T14:42:15.422Z" }, - { url = "https://files.pythonhosted.org/packages/9c/b3/ef274927f4ebede96056173b620db649cc9cb746c61ffc467946b9d0bc67/coverage-7.10.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f9559b906a100029274448f4c8b8b0a127daa4dade5661dfd821b8c188058842", size = 261408, upload-time = "2025-08-23T14:42:16.971Z" }, - { url = "https://files.pythonhosted.org/packages/20/fc/83ca2812be616d69b4cdd4e0c62a7bc526d56875e68fd0f79d47c7923584/coverage-7.10.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b08801e25e3b4526ef9ced1aa29344131a8f5213c60c03c18fe4c6170ffa2874", size = 259168, upload-time = "2025-08-23T14:42:18.512Z" }, - { url = "https://files.pythonhosted.org/packages/fc/4f/e0779e5716f72d5c9962e709d09815d02b3b54724e38567308304c3fc9df/coverage-7.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ed9749bb8eda35f8b636fb7632f1c62f735a236a5d4edadd8bbcc5ea0542e732", size = 260317, upload-time = "2025-08-23T14:42:20.005Z" }, - { url = "https://files.pythonhosted.org/packages/2b/fe/4247e732f2234bb5eb9984a0888a70980d681f03cbf433ba7b48f08ca5d5/coverage-7.10.5-cp314-cp314t-win32.whl", hash = "sha256:609b60d123fc2cc63ccee6d17e4676699075db72d14ac3c107cc4976d516f2df", size = 220600, upload-time = "2025-08-23T14:42:22.027Z" }, - { url = "https://files.pythonhosted.org/packages/a7/a0/f294cff6d1034b87839987e5b6ac7385bec599c44d08e0857ac7f164ad0c/coverage-7.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:0666cf3d2c1626b5a3463fd5b05f5e21f99e6aec40a3192eee4d07a15970b07f", size = 221714, upload-time = "2025-08-23T14:42:23.616Z" }, - { url = "https://files.pythonhosted.org/packages/23/18/fa1afdc60b5528d17416df440bcbd8fd12da12bfea9da5b6ae0f7a37d0f7/coverage-7.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:bc85eb2d35e760120540afddd3044a5bf69118a91a296a8b3940dfc4fdcfe1e2", size = 219735, upload-time = "2025-08-23T14:42:25.156Z" }, - { url = "https://files.pythonhosted.org/packages/08/b6/fff6609354deba9aeec466e4bcaeb9d1ed3e5d60b14b57df2a36fb2273f2/coverage-7.10.5-py3-none-any.whl", hash = "sha256:0be24d35e4db1d23d0db5c0f6a74a962e2ec83c426b5cac09f4234aadef38e4a", size = 208736, upload-time = "2025-08-23T14:42:43.145Z" }, + { url = "https://files.pythonhosted.org/packages/a8/1d/2e64b43d978b5bd184e0756a41415597dfef30fcbd90b747474bd749d45f/coverage-7.10.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70e7bfbd57126b5554aa482691145f798d7df77489a177a6bef80de78860a356", size = 217025, upload-time = "2025-08-29T15:32:57.169Z" }, + { url = "https://files.pythonhosted.org/packages/23/62/b1e0f513417c02cc10ef735c3ee5186df55f190f70498b3702d516aad06f/coverage-7.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e41be6f0f19da64af13403e52f2dec38bbc2937af54df8ecef10850ff8d35301", size = 217419, upload-time = "2025-08-29T15:32:59.908Z" }, + { url = "https://files.pythonhosted.org/packages/e7/16/b800640b7a43e7c538429e4d7223e0a94fd72453a1a048f70bf766f12e96/coverage-7.10.6-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c61fc91ab80b23f5fddbee342d19662f3d3328173229caded831aa0bd7595460", size = 244180, upload-time = "2025-08-29T15:33:01.608Z" }, + { url = "https://files.pythonhosted.org/packages/fb/6f/5e03631c3305cad187eaf76af0b559fff88af9a0b0c180d006fb02413d7a/coverage-7.10.6-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10356fdd33a7cc06e8051413140bbdc6f972137508a3572e3f59f805cd2832fd", size = 245992, upload-time = "2025-08-29T15:33:03.239Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a1/f30ea0fb400b080730125b490771ec62b3375789f90af0bb68bfb8a921d7/coverage-7.10.6-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80b1695cf7c5ebe7b44bf2521221b9bb8cdf69b1f24231149a7e3eb1ae5fa2fb", size = 247851, upload-time = "2025-08-29T15:33:04.603Z" }, + { url = "https://files.pythonhosted.org/packages/02/8e/cfa8fee8e8ef9a6bb76c7bef039f3302f44e615d2194161a21d3d83ac2e9/coverage-7.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2e4c33e6378b9d52d3454bd08847a8651f4ed23ddbb4a0520227bd346382bbc6", size = 245891, upload-time = "2025-08-29T15:33:06.176Z" }, + { url = "https://files.pythonhosted.org/packages/93/a9/51be09b75c55c4f6c16d8d73a6a1d46ad764acca0eab48fa2ffaef5958fe/coverage-7.10.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c8a3ec16e34ef980a46f60dc6ad86ec60f763c3f2fa0db6d261e6e754f72e945", size = 243909, upload-time = "2025-08-29T15:33:07.74Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a6/ba188b376529ce36483b2d585ca7bdac64aacbe5aa10da5978029a9c94db/coverage-7.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7d79dabc0a56f5af990cc6da9ad1e40766e82773c075f09cc571e2076fef882e", size = 244786, upload-time = "2025-08-29T15:33:08.965Z" }, + { url = "https://files.pythonhosted.org/packages/d0/4c/37ed872374a21813e0d3215256180c9a382c3f5ced6f2e5da0102fc2fd3e/coverage-7.10.6-cp310-cp310-win32.whl", hash = "sha256:86b9b59f2b16e981906e9d6383eb6446d5b46c278460ae2c36487667717eccf1", size = 219521, upload-time = "2025-08-29T15:33:10.599Z" }, + { url = "https://files.pythonhosted.org/packages/8e/36/9311352fdc551dec5b973b61f4e453227ce482985a9368305880af4f85dd/coverage-7.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:e132b9152749bd33534e5bd8565c7576f135f157b4029b975e15ee184325f528", size = 220417, upload-time = "2025-08-29T15:33:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f", size = 217129, upload-time = "2025-08-29T15:33:13.575Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc", size = 217532, upload-time = "2025-08-29T15:33:14.872Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a", size = 247931, upload-time = "2025-08-29T15:33:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a", size = 249864, upload-time = "2025-08-29T15:33:17.434Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62", size = 251969, upload-time = "2025-08-29T15:33:18.822Z" }, + { url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153", size = 249659, upload-time = "2025-08-29T15:33:20.407Z" }, + { url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5", size = 247714, upload-time = "2025-08-29T15:33:21.751Z" }, + { url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619", size = 248351, upload-time = "2025-08-29T15:33:23.105Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl", hash = "sha256:e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba", size = 219562, upload-time = "2025-08-29T15:33:24.717Z" }, + { url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e", size = 220453, upload-time = "2025-08-29T15:33:26.482Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c", size = 219127, upload-time = "2025-08-29T15:33:27.777Z" }, + { url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea", size = 217324, upload-time = "2025-08-29T15:33:29.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634", size = 217560, upload-time = "2025-08-29T15:33:30.748Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6", size = 249053, upload-time = "2025-08-29T15:33:32.041Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9", size = 251802, upload-time = "2025-08-29T15:33:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c", size = 252935, upload-time = "2025-08-29T15:33:34.909Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a", size = 250855, upload-time = "2025-08-29T15:33:36.922Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5", size = 248974, upload-time = "2025-08-29T15:33:38.175Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972", size = 250409, upload-time = "2025-08-29T15:33:39.447Z" }, + { url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl", hash = "sha256:a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d", size = 219724, upload-time = "2025-08-29T15:33:41.172Z" }, + { url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629", size = 220536, upload-time = "2025-08-29T15:33:42.524Z" }, + { url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80", size = 219171, upload-time = "2025-08-29T15:33:43.974Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, + { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, + { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, + { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, + { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, + { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, + { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, + { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, + { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, + { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, + { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, + { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, + { url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e", size = 217331, upload-time = "2025-08-29T15:34:20.846Z" }, + { url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb", size = 217607, upload-time = "2025-08-29T15:34:22.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034", size = 248663, upload-time = "2025-08-29T15:34:24.425Z" }, + { url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1", size = 251197, upload-time = "2025-08-29T15:34:25.906Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a", size = 252551, upload-time = "2025-08-29T15:34:27.337Z" }, + { url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb", size = 250553, upload-time = "2025-08-29T15:34:29.065Z" }, + { url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d", size = 248486, upload-time = "2025-08-29T15:34:30.897Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747", size = 249981, upload-time = "2025-08-29T15:34:32.365Z" }, + { url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl", hash = "sha256:6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5", size = 220054, upload-time = "2025-08-29T15:34:34.124Z" }, + { url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713", size = 220851, upload-time = "2025-08-29T15:34:35.651Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32", size = 219429, upload-time = "2025-08-29T15:34:37.16Z" }, + { url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65", size = 218080, upload-time = "2025-08-29T15:34:38.919Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6", size = 218293, upload-time = "2025-08-29T15:34:40.425Z" }, + { url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0", size = 259800, upload-time = "2025-08-29T15:34:41.996Z" }, + { url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e", size = 261965, upload-time = "2025-08-29T15:34:43.61Z" }, + { url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5", size = 264220, upload-time = "2025-08-29T15:34:45.387Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7", size = 261660, upload-time = "2025-08-29T15:34:47.288Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5", size = 259417, upload-time = "2025-08-29T15:34:48.779Z" }, + { url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0", size = 260567, upload-time = "2025-08-29T15:34:50.718Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl", hash = "sha256:441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7", size = 220831, upload-time = "2025-08-29T15:34:52.653Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930", size = 221950, upload-time = "2025-08-29T15:34:54.212Z" }, + { url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b", size = 219969, upload-time = "2025-08-29T15:34:55.83Z" }, + { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, ] [package.optional-dependencies] @@ -644,49 +644,49 @@ toml = [ [[package]] name = "cryptography" -version = "45.0.6" +version = "45.0.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d6/0d/d13399c94234ee8f3df384819dc67e0c5ce215fb751d567a55a1f4b028c7/cryptography-45.0.6.tar.gz", hash = "sha256:5c966c732cf6e4a276ce83b6e4c729edda2df6929083a952cc7da973c539c719", size = 744949, upload-time = "2025-08-05T23:59:27.93Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/35/c495bffc2056f2dadb32434f1feedd79abde2a7f8363e1974afa9c33c7e2/cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971", size = 744980, upload-time = "2025-09-01T11:15:03.146Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/29/2793d178d0eda1ca4a09a7c4e09a5185e75738cc6d526433e8663b460ea6/cryptography-45.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:048e7ad9e08cf4c0ab07ff7f36cc3115924e22e2266e034450a890d9e312dd74", size = 7042702, upload-time = "2025-08-05T23:58:23.464Z" }, - { url = "https://files.pythonhosted.org/packages/b3/b6/cabd07410f222f32c8d55486c464f432808abaa1f12af9afcbe8f2f19030/cryptography-45.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:44647c5d796f5fc042bbc6d61307d04bf29bccb74d188f18051b635f20a9c75f", size = 4206483, upload-time = "2025-08-05T23:58:27.132Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9e/f9c7d36a38b1cfeb1cc74849aabe9bf817990f7603ff6eb485e0d70e0b27/cryptography-45.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e40b80ecf35ec265c452eea0ba94c9587ca763e739b8e559c128d23bff7ebbbf", size = 4429679, upload-time = "2025-08-05T23:58:29.152Z" }, - { url = "https://files.pythonhosted.org/packages/9c/2a/4434c17eb32ef30b254b9e8b9830cee4e516f08b47fdd291c5b1255b8101/cryptography-45.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:00e8724bdad672d75e6f069b27970883179bd472cd24a63f6e620ca7e41cc0c5", size = 4210553, upload-time = "2025-08-05T23:58:30.596Z" }, - { url = "https://files.pythonhosted.org/packages/ef/1d/09a5df8e0c4b7970f5d1f3aff1b640df6d4be28a64cae970d56c6cf1c772/cryptography-45.0.6-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a3085d1b319d35296176af31c90338eeb2ddac8104661df79f80e1d9787b8b2", size = 3894499, upload-time = "2025-08-05T23:58:32.03Z" }, - { url = "https://files.pythonhosted.org/packages/79/62/120842ab20d9150a9d3a6bdc07fe2870384e82f5266d41c53b08a3a96b34/cryptography-45.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1b7fa6a1c1188c7ee32e47590d16a5a0646270921f8020efc9a511648e1b2e08", size = 4458484, upload-time = "2025-08-05T23:58:33.526Z" }, - { url = "https://files.pythonhosted.org/packages/fd/80/1bc3634d45ddfed0871bfba52cf8f1ad724761662a0c792b97a951fb1b30/cryptography-45.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:275ba5cc0d9e320cd70f8e7b96d9e59903c815ca579ab96c1e37278d231fc402", size = 4210281, upload-time = "2025-08-05T23:58:35.445Z" }, - { url = "https://files.pythonhosted.org/packages/7d/fe/ffb12c2d83d0ee625f124880a1f023b5878f79da92e64c37962bbbe35f3f/cryptography-45.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f4028f29a9f38a2025abedb2e409973709c660d44319c61762202206ed577c42", size = 4456890, upload-time = "2025-08-05T23:58:36.923Z" }, - { url = "https://files.pythonhosted.org/packages/8c/8e/b3f3fe0dc82c77a0deb5f493b23311e09193f2268b77196ec0f7a36e3f3e/cryptography-45.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ee411a1b977f40bd075392c80c10b58025ee5c6b47a822a33c1198598a7a5f05", size = 4333247, upload-time = "2025-08-05T23:58:38.781Z" }, - { url = "https://files.pythonhosted.org/packages/b3/a6/c3ef2ab9e334da27a1d7b56af4a2417d77e7806b2e0f90d6267ce120d2e4/cryptography-45.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e2a21a8eda2d86bb604934b6b37691585bd095c1f788530c1fcefc53a82b3453", size = 4565045, upload-time = "2025-08-05T23:58:40.415Z" }, - { url = "https://files.pythonhosted.org/packages/31/c3/77722446b13fa71dddd820a5faab4ce6db49e7e0bf8312ef4192a3f78e2f/cryptography-45.0.6-cp311-abi3-win32.whl", hash = "sha256:d063341378d7ee9c91f9d23b431a3502fc8bfacd54ef0a27baa72a0843b29159", size = 2928923, upload-time = "2025-08-05T23:58:41.919Z" }, - { url = "https://files.pythonhosted.org/packages/38/63/a025c3225188a811b82932a4dcc8457a26c3729d81578ccecbcce2cb784e/cryptography-45.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:833dc32dfc1e39b7376a87b9a6a4288a10aae234631268486558920029b086ec", size = 3403805, upload-time = "2025-08-05T23:58:43.792Z" }, - { url = "https://files.pythonhosted.org/packages/5b/af/bcfbea93a30809f126d51c074ee0fac5bd9d57d068edf56c2a73abedbea4/cryptography-45.0.6-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:3436128a60a5e5490603ab2adbabc8763613f638513ffa7d311c900a8349a2a0", size = 7020111, upload-time = "2025-08-05T23:58:45.316Z" }, - { url = "https://files.pythonhosted.org/packages/98/c6/ea5173689e014f1a8470899cd5beeb358e22bb3cf5a876060f9d1ca78af4/cryptography-45.0.6-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0d9ef57b6768d9fa58e92f4947cea96ade1233c0e236db22ba44748ffedca394", size = 4198169, upload-time = "2025-08-05T23:58:47.121Z" }, - { url = "https://files.pythonhosted.org/packages/ba/73/b12995edc0c7e2311ffb57ebd3b351f6b268fed37d93bfc6f9856e01c473/cryptography-45.0.6-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea3c42f2016a5bbf71825537c2ad753f2870191134933196bee408aac397b3d9", size = 4421273, upload-time = "2025-08-05T23:58:48.557Z" }, - { url = "https://files.pythonhosted.org/packages/f7/6e/286894f6f71926bc0da67408c853dd9ba953f662dcb70993a59fd499f111/cryptography-45.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:20ae4906a13716139d6d762ceb3e0e7e110f7955f3bc3876e3a07f5daadec5f3", size = 4199211, upload-time = "2025-08-05T23:58:50.139Z" }, - { url = "https://files.pythonhosted.org/packages/de/34/a7f55e39b9623c5cb571d77a6a90387fe557908ffc44f6872f26ca8ae270/cryptography-45.0.6-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dac5ec199038b8e131365e2324c03d20e97fe214af051d20c49db129844e8b3", size = 3883732, upload-time = "2025-08-05T23:58:52.253Z" }, - { url = "https://files.pythonhosted.org/packages/f9/b9/c6d32edbcba0cd9f5df90f29ed46a65c4631c4fbe11187feb9169c6ff506/cryptography-45.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f878a34b90d688982e43f4b700408b478102dd58b3e39de21b5ebf6509c301", size = 4450655, upload-time = "2025-08-05T23:58:53.848Z" }, - { url = "https://files.pythonhosted.org/packages/77/2d/09b097adfdee0227cfd4c699b3375a842080f065bab9014248933497c3f9/cryptography-45.0.6-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5bd6020c80c5b2b2242d6c48487d7b85700f5e0038e67b29d706f98440d66eb5", size = 4198956, upload-time = "2025-08-05T23:58:55.209Z" }, - { url = "https://files.pythonhosted.org/packages/55/66/061ec6689207d54effdff535bbdf85cc380d32dd5377173085812565cf38/cryptography-45.0.6-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:eccddbd986e43014263eda489abbddfbc287af5cddfd690477993dbb31e31016", size = 4449859, upload-time = "2025-08-05T23:58:56.639Z" }, - { url = "https://files.pythonhosted.org/packages/41/ff/e7d5a2ad2d035e5a2af116e1a3adb4d8fcd0be92a18032917a089c6e5028/cryptography-45.0.6-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:550ae02148206beb722cfe4ef0933f9352bab26b087af00e48fdfb9ade35c5b3", size = 4320254, upload-time = "2025-08-05T23:58:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/82/27/092d311af22095d288f4db89fcaebadfb2f28944f3d790a4cf51fe5ddaeb/cryptography-45.0.6-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5b64e668fc3528e77efa51ca70fadcd6610e8ab231e3e06ae2bab3b31c2b8ed9", size = 4554815, upload-time = "2025-08-05T23:59:00.283Z" }, - { url = "https://files.pythonhosted.org/packages/7e/01/aa2f4940262d588a8fdf4edabe4cda45854d00ebc6eaac12568b3a491a16/cryptography-45.0.6-cp37-abi3-win32.whl", hash = "sha256:780c40fb751c7d2b0c6786ceee6b6f871e86e8718a8ff4bc35073ac353c7cd02", size = 2912147, upload-time = "2025-08-05T23:59:01.716Z" }, - { url = "https://files.pythonhosted.org/packages/0a/bc/16e0276078c2de3ceef6b5a34b965f4436215efac45313df90d55f0ba2d2/cryptography-45.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:20d15aed3ee522faac1a39fbfdfee25d17b1284bafd808e1640a74846d7c4d1b", size = 3390459, upload-time = "2025-08-05T23:59:03.358Z" }, - { url = "https://files.pythonhosted.org/packages/56/d2/4482d97c948c029be08cb29854a91bd2ae8da7eb9c4152461f1244dcea70/cryptography-45.0.6-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:705bb7c7ecc3d79a50f236adda12ca331c8e7ecfbea51edd931ce5a7a7c4f012", size = 3576812, upload-time = "2025-08-05T23:59:04.833Z" }, - { url = "https://files.pythonhosted.org/packages/ec/24/55fc238fcaa122855442604b8badb2d442367dfbd5a7ca4bb0bd346e263a/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:826b46dae41a1155a0c0e66fafba43d0ede1dc16570b95e40c4d83bfcf0a451d", size = 4141694, upload-time = "2025-08-05T23:59:06.66Z" }, - { url = "https://files.pythonhosted.org/packages/f9/7e/3ea4fa6fbe51baf3903806a0241c666b04c73d2358a3ecce09ebee8b9622/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cc4d66f5dc4dc37b89cfef1bd5044387f7a1f6f0abb490815628501909332d5d", size = 4375010, upload-time = "2025-08-05T23:59:08.14Z" }, - { url = "https://files.pythonhosted.org/packages/50/42/ec5a892d82d2a2c29f80fc19ced4ba669bca29f032faf6989609cff1f8dc/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f68f833a9d445cc49f01097d95c83a850795921b3f7cc6488731e69bde3288da", size = 4141377, upload-time = "2025-08-05T23:59:09.584Z" }, - { url = "https://files.pythonhosted.org/packages/e7/d7/246c4c973a22b9c2931999da953a2c19cae7c66b9154c2d62ffed811225e/cryptography-45.0.6-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:3b5bf5267e98661b9b888a9250d05b063220dfa917a8203744454573c7eb79db", size = 4374609, upload-time = "2025-08-05T23:59:11.923Z" }, - { url = "https://files.pythonhosted.org/packages/78/6d/c49ccf243f0a1b0781c2a8de8123ee552f0c8a417c6367a24d2ecb7c11b3/cryptography-45.0.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2384f2ab18d9be88a6e4f8972923405e2dbb8d3e16c6b43f15ca491d7831bd18", size = 3322156, upload-time = "2025-08-05T23:59:13.597Z" }, - { url = "https://files.pythonhosted.org/packages/61/69/c252de4ec047ba2f567ecb53149410219577d408c2aea9c989acae7eafce/cryptography-45.0.6-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fc022c1fa5acff6def2fc6d7819bbbd31ccddfe67d075331a65d9cfb28a20983", size = 3584669, upload-time = "2025-08-05T23:59:15.431Z" }, - { url = "https://files.pythonhosted.org/packages/e3/fe/deea71e9f310a31fe0a6bfee670955152128d309ea2d1c79e2a5ae0f0401/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3de77e4df42ac8d4e4d6cdb342d989803ad37707cf8f3fbf7b088c9cbdd46427", size = 4153022, upload-time = "2025-08-05T23:59:16.954Z" }, - { url = "https://files.pythonhosted.org/packages/60/45/a77452f5e49cb580feedba6606d66ae7b82c128947aa754533b3d1bd44b0/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:599c8d7df950aa68baa7e98f7b73f4f414c9f02d0e8104a30c0182a07732638b", size = 4386802, upload-time = "2025-08-05T23:59:18.55Z" }, - { url = "https://files.pythonhosted.org/packages/a3/b9/a2f747d2acd5e3075fdf5c145c7c3568895daaa38b3b0c960ef830db6cdc/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:31a2b9a10530a1cb04ffd6aa1cd4d3be9ed49f7d77a4dafe198f3b382f41545c", size = 4152706, upload-time = "2025-08-05T23:59:20.044Z" }, - { url = "https://files.pythonhosted.org/packages/81/ec/381b3e8d0685a3f3f304a382aa3dfce36af2d76467da0fd4bb21ddccc7b2/cryptography-45.0.6-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:e5b3dda1b00fb41da3af4c5ef3f922a200e33ee5ba0f0bc9ecf0b0c173958385", size = 4386740, upload-time = "2025-08-05T23:59:21.525Z" }, - { url = "https://files.pythonhosted.org/packages/0a/76/cf8d69da8d0b5ecb0db406f24a63a3f69ba5e791a11b782aeeefef27ccbb/cryptography-45.0.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:629127cfdcdc6806dfe234734d7cb8ac54edaf572148274fa377a7d3405b0043", size = 3331874, upload-time = "2025-08-05T23:59:23.017Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/925c0ac74362172ae4516000fe877912e33b5983df735ff290c653de4913/cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee", size = 7041105, upload-time = "2025-09-01T11:13:59.684Z" }, + { url = "https://files.pythonhosted.org/packages/fc/63/43641c5acce3a6105cf8bd5baeceeb1846bb63067d26dae3e5db59f1513a/cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6", size = 4205799, upload-time = "2025-09-01T11:14:02.517Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/c238dd9107f10bfde09a4d1c52fd38828b1aa353ced11f358b5dd2507d24/cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339", size = 4430504, upload-time = "2025-09-01T11:14:04.522Z" }, + { url = "https://files.pythonhosted.org/packages/62/62/24203e7cbcc9bd7c94739428cd30680b18ae6b18377ae66075c8e4771b1b/cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8", size = 4209542, upload-time = "2025-09-01T11:14:06.309Z" }, + { url = "https://files.pythonhosted.org/packages/cd/e3/e7de4771a08620eef2389b86cd87a2c50326827dea5528feb70595439ce4/cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf", size = 3889244, upload-time = "2025-09-01T11:14:08.152Z" }, + { url = "https://files.pythonhosted.org/packages/96/b8/bca71059e79a0bb2f8e4ec61d9c205fbe97876318566cde3b5092529faa9/cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513", size = 4461975, upload-time = "2025-09-01T11:14:09.755Z" }, + { url = "https://files.pythonhosted.org/packages/58/67/3f5b26937fe1218c40e95ef4ff8d23c8dc05aa950d54200cc7ea5fb58d28/cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3", size = 4209082, upload-time = "2025-09-01T11:14:11.229Z" }, + { url = "https://files.pythonhosted.org/packages/0e/e4/b3e68a4ac363406a56cf7b741eeb80d05284d8c60ee1a55cdc7587e2a553/cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3", size = 4460397, upload-time = "2025-09-01T11:14:12.924Z" }, + { url = "https://files.pythonhosted.org/packages/22/49/2c93f3cd4e3efc8cb22b02678c1fad691cff9dd71bb889e030d100acbfe0/cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6", size = 4337244, upload-time = "2025-09-01T11:14:14.431Z" }, + { url = "https://files.pythonhosted.org/packages/04/19/030f400de0bccccc09aa262706d90f2ec23d56bc4eb4f4e8268d0ddf3fb8/cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd", size = 4568862, upload-time = "2025-09-01T11:14:16.185Z" }, + { url = "https://files.pythonhosted.org/packages/29/56/3034a3a353efa65116fa20eb3c990a8c9f0d3db4085429040a7eef9ada5f/cryptography-45.0.7-cp311-abi3-win32.whl", hash = "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8", size = 2936578, upload-time = "2025-09-01T11:14:17.638Z" }, + { url = "https://files.pythonhosted.org/packages/b3/61/0ab90f421c6194705a99d0fa9f6ee2045d916e4455fdbb095a9c2c9a520f/cryptography-45.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443", size = 3405400, upload-time = "2025-09-01T11:14:18.958Z" }, + { url = "https://files.pythonhosted.org/packages/63/e8/c436233ddf19c5f15b25ace33979a9dd2e7aa1a59209a0ee8554179f1cc0/cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2", size = 7021824, upload-time = "2025-09-01T11:14:20.954Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4c/8f57f2500d0ccd2675c5d0cc462095adf3faa8c52294ba085c036befb901/cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691", size = 4202233, upload-time = "2025-09-01T11:14:22.454Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ac/59b7790b4ccaed739fc44775ce4645c9b8ce54cbec53edf16c74fd80cb2b/cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59", size = 4423075, upload-time = "2025-09-01T11:14:24.287Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/d4f07ea21434bf891faa088a6ac15d6d98093a66e75e30ad08e88aa2b9ba/cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4", size = 4204517, upload-time = "2025-09-01T11:14:25.679Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ac/924a723299848b4c741c1059752c7cfe09473b6fd77d2920398fc26bfb53/cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3", size = 3882893, upload-time = "2025-09-01T11:14:27.1Z" }, + { url = "https://files.pythonhosted.org/packages/83/dc/4dab2ff0a871cc2d81d3ae6d780991c0192b259c35e4d83fe1de18b20c70/cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1", size = 4450132, upload-time = "2025-09-01T11:14:28.58Z" }, + { url = "https://files.pythonhosted.org/packages/12/dd/b2882b65db8fc944585d7fb00d67cf84a9cef4e77d9ba8f69082e911d0de/cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27", size = 4204086, upload-time = "2025-09-01T11:14:30.572Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fa/1d5745d878048699b8eb87c984d4ccc5da4f5008dfd3ad7a94040caca23a/cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17", size = 4449383, upload-time = "2025-09-01T11:14:32.046Z" }, + { url = "https://files.pythonhosted.org/packages/36/8b/fc61f87931bc030598e1876c45b936867bb72777eac693e905ab89832670/cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b", size = 4332186, upload-time = "2025-09-01T11:14:33.95Z" }, + { url = "https://files.pythonhosted.org/packages/0b/11/09700ddad7443ccb11d674efdbe9a832b4455dc1f16566d9bd3834922ce5/cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c", size = 4561639, upload-time = "2025-09-01T11:14:35.343Z" }, + { url = "https://files.pythonhosted.org/packages/71/ed/8f4c1337e9d3b94d8e50ae0b08ad0304a5709d483bfcadfcc77a23dbcb52/cryptography-45.0.7-cp37-abi3-win32.whl", hash = "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5", size = 2926552, upload-time = "2025-09-01T11:14:36.929Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ff/026513ecad58dacd45d1d24ebe52b852165a26e287177de1d545325c0c25/cryptography-45.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90", size = 3392742, upload-time = "2025-09-01T11:14:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/13/3e/e42f1528ca1ea82256b835191eab1be014e0f9f934b60d98b0be8a38ed70/cryptography-45.0.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:de58755d723e86175756f463f2f0bddd45cc36fbd62601228a3f8761c9f58252", size = 3572442, upload-time = "2025-09-01T11:14:39.836Z" }, + { url = "https://files.pythonhosted.org/packages/59/aa/e947693ab08674a2663ed2534cd8d345cf17bf6a1facf99273e8ec8986dc/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083", size = 4142233, upload-time = "2025-09-01T11:14:41.305Z" }, + { url = "https://files.pythonhosted.org/packages/24/06/09b6f6a2fc43474a32b8fe259038eef1500ee3d3c141599b57ac6c57612c/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130", size = 4376202, upload-time = "2025-09-01T11:14:43.047Z" }, + { url = "https://files.pythonhosted.org/packages/00/f2/c166af87e95ce6ae6d38471a7e039d3a0549c2d55d74e059680162052824/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4", size = 4141900, upload-time = "2025-09-01T11:14:45.089Z" }, + { url = "https://files.pythonhosted.org/packages/16/b9/e96e0b6cb86eae27ea51fa8a3151535a18e66fe7c451fa90f7f89c85f541/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141", size = 4375562, upload-time = "2025-09-01T11:14:47.166Z" }, + { url = "https://files.pythonhosted.org/packages/36/d0/36e8ee39274e9d77baf7d0dafda680cba6e52f3936b846f0d56d64fec915/cryptography-45.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c13b1e3afd29a5b3b2656257f14669ca8fa8d7956d509926f0b130b600b50ab7", size = 3322781, upload-time = "2025-09-01T11:14:48.747Z" }, + { url = "https://files.pythonhosted.org/packages/99/4e/49199a4c82946938a3e05d2e8ad9482484ba48bbc1e809e3d506c686d051/cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde", size = 3584634, upload-time = "2025-09-01T11:14:50.593Z" }, + { url = "https://files.pythonhosted.org/packages/16/ce/5f6ff59ea9c7779dba51b84871c19962529bdcc12e1a6ea172664916c550/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34", size = 4149533, upload-time = "2025-09-01T11:14:52.091Z" }, + { url = "https://files.pythonhosted.org/packages/ce/13/b3cfbd257ac96da4b88b46372e662009b7a16833bfc5da33bb97dd5631ae/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9", size = 4385557, upload-time = "2025-09-01T11:14:53.551Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c5/8c59d6b7c7b439ba4fc8d0cab868027fd095f215031bc123c3a070962912/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae", size = 4149023, upload-time = "2025-09-01T11:14:55.022Z" }, + { url = "https://files.pythonhosted.org/packages/55/32/05385c86d6ca9ab0b4d5bb442d2e3d85e727939a11f3e163fc776ce5eb40/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b", size = 4385722, upload-time = "2025-09-01T11:14:57.319Z" }, + { url = "https://files.pythonhosted.org/packages/23/87/7ce86f3fa14bc11a5a48c30d8103c26e09b6465f8d8e9d74cf7a0714f043/cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63", size = 3332908, upload-time = "2025-09-01T11:14:58.78Z" }, ] [[package]] @@ -858,11 +858,11 @@ wheels = [ [[package]] name = "fsspec" -version = "2025.7.0" +version = "2025.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/02/0835e6ab9cfc03916fe3f78c0956cfcdb6ff2669ffa6651065d5ebf7fc98/fsspec-2025.7.0.tar.gz", hash = "sha256:786120687ffa54b8283d942929540d8bc5ccfa820deb555a2b5d0ed2b737bf58", size = 304432, upload-time = "2025-07-15T16:05:21.19Z" } +sdist = { url = "https://files.pythonhosted.org/packages/de/e0/bab50af11c2d75c9c4a2a26a5254573c0bd97cea152254401510950486fa/fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19", size = 304847, upload-time = "2025-09-02T19:10:49.215Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/e0/014d5d9d7a4564cf1c40b5039bc882db69fd881111e03ab3657ac0b218e2/fsspec-2025.7.0-py3-none-any.whl", hash = "sha256:8b012e39f63c7d5f10474de957f3ab793b47b45ae7d39f2fb735f8bbe25c0e21", size = 199597, upload-time = "2025-07-15T16:05:19.529Z" }, + { url = "https://files.pythonhosted.org/packages/47/71/70db47e4f6ce3e5c37a607355f80da8860a33226be640226ac52cb05ef2e/fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7", size = 199289, upload-time = "2025-09-02T19:10:47.708Z" }, ] [[package]] @@ -931,7 +931,7 @@ wheels = [ [[package]] name = "google-cloud-aiplatform" -version = "1.110.0" +version = "1.111.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "docstring-parser" }, @@ -948,9 +948,9 @@ dependencies = [ { name = "shapely" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/a4/af1052083e715f4f47b81b9f8139fe188c666f8512f9ca5188b3363797a6/google_cloud_aiplatform-1.110.0.tar.gz", hash = "sha256:e77a0d8fb4f58f4cae2e6bea12e63ef277ecceba23ab38d2a3a5c20022e6a6b5", size = 9525223, upload-time = "2025-08-18T23:07:49.545Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/db/def79d3cbf2b502864f8ab18d0094f437edc5c2e5db5994bd10a16e813d4/google_cloud_aiplatform-1.111.0.tar.gz", hash = "sha256:80b07186419970fb1e39e2728e7aa2402a8753c1041ec5117677f489202c91d4", size = 9604280, upload-time = "2025-08-27T02:57:57.243Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/9f/79d9734841b36459c0f3ba288827e8c0ec78b10950bc86cb78f53eb0f0bd/google_cloud_aiplatform-1.110.0-py2.py3-none-any.whl", hash = "sha256:c4e4f0a45845daeadba1e60706dfd1f1cd579336e3140e4ab4fb48507b25c2fe", size = 7916508, upload-time = "2025-08-18T23:07:46.707Z" }, + { url = "https://files.pythonhosted.org/packages/f9/27/492c171ccdaa56a409c9d50f4126170cfa779d0a976cb2d561f30d03146f/google_cloud_aiplatform-1.111.0-py2.py3-none-any.whl", hash = "sha256:a38796050b7d427fbf1f7d6d6e1d5069abe9a1fd948e3193250f68ccd67388f5", size = 7995239, upload-time = "2025-08-27T02:57:53.766Z" }, ] [[package]] @@ -1054,7 +1054,7 @@ wheels = [ [[package]] name = "google-genai" -version = "1.31.0" +version = "1.33.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1066,9 +1066,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e0/1b/da30fa6e2966942d7028a58eb7aa7d04544dcc3aa66194365b2e0adac570/google_genai-1.31.0.tar.gz", hash = "sha256:8572b47aa684357c3e5e10d290ec772c65414114939e3ad2955203e27cd2fcbc", size = 233482, upload-time = "2025-08-18T23:40:21.733Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/506221067750087ba1346f0a31f6e1714fda4b612d45a54cd2164750e05a/google_genai-1.33.0.tar.gz", hash = "sha256:7d3a5ebad712d95a0d1775842505886eb43cc52f9f478aa4ab0e2d25412499a2", size = 241006, upload-time = "2025-09-03T22:54:10.662Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/27/1525bc9cbec58660f0842ebcbfe910a1dde908c2672373804879666e0bb8/google_genai-1.31.0-py3-none-any.whl", hash = "sha256:5c6959bcf862714e8ed0922db3aaf41885bacf6318751b3421bf1e459f78892f", size = 231876, upload-time = "2025-08-18T23:40:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/43/8e/55052fe488d6604309b425360beb72e6d65f11fa4cc1cdde17ccfe93e1bc/google_genai-1.33.0-py3-none-any.whl", hash = "sha256:1710e958af0a0f3d19521fabbefd86b22d1f212376103f18fed11c9d96fa48e8", size = 241753, upload-time = "2025-09-03T22:54:08.789Z" }, ] [[package]] @@ -1102,7 +1102,7 @@ grpc = [ [[package]] name = "groq" -version = "0.31.0" +version = "0.31.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1112,9 +1112,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/a2/77fd1460e7d55859219223719aa44ae8902a3a1ad333cd5faf330eb0b894/groq-0.31.0.tar.gz", hash = "sha256:182252e9bf0d696df607c137cbafa851d2c84aaf94bcfe9165c0bc231043490c", size = 136237, upload-time = "2025-08-05T23:14:01.183Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/e9/f5d523ae8c78aa375addf44d1f64206271d43e6b42d4e5ce3dc76563a75b/groq-0.31.1.tar.gz", hash = "sha256:4d611e0100cb22732c43b53af37933a1b8a5c5a18fa96132fee14e6c15d737e6", size = 141400, upload-time = "2025-09-04T18:01:06.056Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/f8/14672d69a91495f43462c5490067eeafc30346e81bda1a62848e897f9bc3/groq-0.31.0-py3-none-any.whl", hash = "sha256:5e3c7ec9728b7cccf913da982a9b5ebb46dc18a070b35e12a3d6a1e12d6b0f7f", size = 131365, upload-time = "2025-08-05T23:13:59.768Z" }, + { url = "https://files.pythonhosted.org/packages/d6/7d/877dbef7d72efacc657777b2e7897baa7cc7fcd0905f1b4a6423269e12a1/groq-0.31.1-py3-none-any.whl", hash = "sha256:536bd5dd6267dea5b3710e41094c0479748da2d155b9e073650e94b7fb2d71e8", size = 134903, upload-time = "2025-09-04T18:01:04.029Z" }, ] [[package]] @@ -1204,17 +1204,17 @@ wheels = [ [[package]] name = "hf-xet" -version = "1.1.8" +version = "1.1.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7a/49/91010b59debc7c862a5fd426d343134dd9a68778dbe570234b6495a4e204/hf_xet-1.1.8.tar.gz", hash = "sha256:62a0043e441753bbc446dcb5a3fe40a4d03f5fb9f13589ef1df9ab19252beb53", size = 484065, upload-time = "2025-08-18T22:01:03.584Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/0f/5b60fc28ee7f8cc17a5114a584fd6b86e11c3e0a6e142a7f97a161e9640a/hf_xet-1.1.9.tar.gz", hash = "sha256:c99073ce404462e909f1d5839b2d14a3827b8fe75ed8aed551ba6609c026c803", size = 484242, upload-time = "2025-08-27T23:05:19.441Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/91/5814db3a0d4a65fb6a87f0931ae28073b87f06307701fe66e7c41513bfb4/hf_xet-1.1.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:3d5f82e533fc51c7daad0f9b655d9c7811b5308e5890236828bd1dd3ed8fea74", size = 2752357, upload-time = "2025-08-18T22:00:58.777Z" }, - { url = "https://files.pythonhosted.org/packages/70/72/ce898516e97341a7a9d450609e130e108643389110261eaee6deb1ba8545/hf_xet-1.1.8-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:8e2dba5896bca3ab61d0bef4f01a1647004de59640701b37e37eaa57087bbd9d", size = 2613142, upload-time = "2025-08-18T22:00:57.252Z" }, - { url = "https://files.pythonhosted.org/packages/b7/d6/13af5f916cef795ac2b5e4cc1de31f2e0e375f4475d50799915835f301c2/hf_xet-1.1.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfe5700bc729be3d33d4e9a9b5cc17a951bf8c7ada7ba0c9198a6ab2053b7453", size = 3175859, upload-time = "2025-08-18T22:00:55.978Z" }, - { url = "https://files.pythonhosted.org/packages/4c/ed/34a193c9d1d72b7c3901b3b5153b1be9b2736b832692e1c3f167af537102/hf_xet-1.1.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:09e86514c3c4284ed8a57d6b0f3d089f9836a0af0a1ceb3c9dd664f1f3eaefef", size = 3074178, upload-time = "2025-08-18T22:00:54.147Z" }, - { url = "https://files.pythonhosted.org/packages/4a/1b/de6817b4bf65385280252dff5c9cceeedfbcb27ddb93923639323c1034a4/hf_xet-1.1.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4a9b99ab721d385b83f4fc8ee4e0366b0b59dce03b5888a86029cc0ca634efbf", size = 3238122, upload-time = "2025-08-18T22:01:00.546Z" }, - { url = "https://files.pythonhosted.org/packages/b7/13/874c85c7ed519ec101deb654f06703d9e5e68d34416730f64c4755ada36a/hf_xet-1.1.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:25b9d43333bbef39aeae1616789ec329c21401a7fe30969d538791076227b591", size = 3344325, upload-time = "2025-08-18T22:01:02.013Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d3/0aaf279f4f3dea58e99401b92c31c0f752924ba0e6c7d7bb07b1dbd7f35e/hf_xet-1.1.8-cp37-abi3-win_amd64.whl", hash = "sha256:4171f31d87b13da4af1ed86c98cf763292e4720c088b4957cf9d564f92904ca9", size = 2801689, upload-time = "2025-08-18T22:01:04.81Z" }, + { url = "https://files.pythonhosted.org/packages/de/12/56e1abb9a44cdef59a411fe8a8673313195711b5ecce27880eb9c8fa90bd/hf_xet-1.1.9-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:a3b6215f88638dd7a6ff82cb4e738dcbf3d863bf667997c093a3c990337d1160", size = 2762553, upload-time = "2025-08-27T23:05:15.153Z" }, + { url = "https://files.pythonhosted.org/packages/3a/e6/2d0d16890c5f21b862f5df3146519c182e7f0ae49b4b4bf2bd8a40d0b05e/hf_xet-1.1.9-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:9b486de7a64a66f9a172f4b3e0dfe79c9f0a93257c501296a2521a13495a698a", size = 2623216, upload-time = "2025-08-27T23:05:13.778Z" }, + { url = "https://files.pythonhosted.org/packages/81/42/7e6955cf0621e87491a1fb8cad755d5c2517803cea174229b0ec00ff0166/hf_xet-1.1.9-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c5a840c2c4e6ec875ed13703a60e3523bc7f48031dfd750923b2a4d1a5fc3c", size = 3186789, upload-time = "2025-08-27T23:05:12.368Z" }, + { url = "https://files.pythonhosted.org/packages/df/8b/759233bce05457f5f7ec062d63bbfd2d0c740b816279eaaa54be92aa452a/hf_xet-1.1.9-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:96a6139c9e44dad1c52c52520db0fffe948f6bce487cfb9d69c125f254bb3790", size = 3088747, upload-time = "2025-08-27T23:05:10.439Z" }, + { url = "https://files.pythonhosted.org/packages/6c/3c/28cc4db153a7601a996985bcb564f7b8f5b9e1a706c7537aad4b4809f358/hf_xet-1.1.9-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ad1022e9a998e784c97b2173965d07fe33ee26e4594770b7785a8cc8f922cd95", size = 3251429, upload-time = "2025-08-27T23:05:16.471Z" }, + { url = "https://files.pythonhosted.org/packages/84/17/7caf27a1d101bfcb05be85850d4aa0a265b2e1acc2d4d52a48026ef1d299/hf_xet-1.1.9-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:86754c2d6d5afb11b0a435e6e18911a4199262fe77553f8c50d75e21242193ea", size = 3354643, upload-time = "2025-08-27T23:05:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/cd/50/0c39c9eed3411deadcc98749a6699d871b822473f55fe472fad7c01ec588/hf_xet-1.1.9-cp37-abi3-win_amd64.whl", hash = "sha256:5aad3933de6b725d61d51034e04174ed1dce7a57c63d530df0014dea15a40127", size = 2804797, upload-time = "2025-08-27T23:05:20.77Z" }, ] [[package]] @@ -1431,7 +1431,7 @@ wheels = [ [[package]] name = "langchain" -version = "1.0.0a3" +version = "1.0.0a4" source = { editable = "." } dependencies = [ { name = "langchain-core" }, @@ -1541,7 +1541,7 @@ requires-dist = [ { name = "langchain-text-splitters", editable = "../text-splitters" }, { name = "langchain-together", marker = "extra == 'together'" }, { name = "langchain-xai", marker = "extra == 'xai'" }, - { name = "langgraph", specifier = ">=0.6.0" }, + { name = "langgraph", specifier = ">=0.6.7" }, { name = "pydantic", specifier = ">=2.7.4" }, ] provides-extras = ["anthropic", "openai", "azure-ai", "google-vertexai", "google-genai", "fireworks", "ollama", "together", "mistralai", "huggingface", "groq", "aws", "deepseek", "xai", "perplexity"] @@ -1716,7 +1716,7 @@ wheels = [ [[package]] name = "langchain-google-genai" -version = "2.1.9" +version = "2.1.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filetype" }, @@ -1724,9 +1724,9 @@ dependencies = [ { name = "langchain-core" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/24/4ad44e9a8ad25682c22b56f0b665eb6d87090f2360355b48095e285a7810/langchain_google_genai-2.1.9.tar.gz", hash = "sha256:cd5d6f644b8dac3e312e30101bb97541aab240e82678e87a4df039ee1dc77531", size = 45866, upload-time = "2025-08-04T18:51:51.42Z" } +sdist = { url = "https://files.pythonhosted.org/packages/28/c9/1808edc6e4835a4f596701d84b4a6b6c295e6875186adfbbeeeba9004469/langchain_google_genai-2.1.10.tar.gz", hash = "sha256:3d091aa61284d7256b2887966e806689adce35e55bc46f705162e5ede8aacda9", size = 45898, upload-time = "2025-08-27T06:15:11.406Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/d8/e1162835d5d6eefaae341c2d1cf750ab53222a421252346905187e53b8a2/langchain_google_genai-2.1.9-py3-none-any.whl", hash = "sha256:8d3aab59706b8f8920a22bcfd63c5000ce430fe61db6ecdec262977d1a0be5b8", size = 49381, upload-time = "2025-08-04T18:51:50.51Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/957c7e6c362b7cdf1d709c0190035c0c843a3d2e225e40a2b80cca75fd3c/langchain_google_genai-2.1.10-py3-none-any.whl", hash = "sha256:247e38908d6b37fb4c4892ca09ae224c7510158b54b0582a9f39a7ddf37a0e2c", size = 49408, upload-time = "2025-08-27T06:15:10.458Z" }, ] [[package]] @@ -2005,7 +2005,7 @@ wheels = [ [[package]] name = "langgraph" -version = "0.6.6" +version = "0.6.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, @@ -2015,9 +2015,9 @@ dependencies = [ { name = "pydantic" }, { name = "xxhash" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/02/2b/59f0b2985467ec84b006dd41ec31c0aae43a7f16722d5514292500b871c9/langgraph-0.6.6.tar.gz", hash = "sha256:e7d3cefacf356f8c01721b166b67b3bf581659d5361a3530f59ecd9b8448eca7", size = 465452, upload-time = "2025-08-20T04:02:13.915Z" } +sdist = { url = "https://files.pythonhosted.org/packages/56/85/36feb25062da40ca395f6c44d0232a672842e5421885101f6faf4670b670/langgraph-0.6.7.tar.gz", hash = "sha256:ba7fd17b8220142d6a4269b6038f2b3dcbcef42cd5ecf4a4c8d9b60b010830a6", size = 465534, upload-time = "2025-09-07T16:49:42.895Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/ef/81fce0a80925cd89987aa641ff01573e3556a24f2d205112862a69df7fd3/langgraph-0.6.6-py3-none-any.whl", hash = "sha256:a2283a5236abba6c8307c1a485c04e8a0f0ffa2be770878782a7bf2deb8d7954", size = 153274, upload-time = "2025-08-20T04:02:12.251Z" }, + { url = "https://files.pythonhosted.org/packages/67/06/f440922a58204dbfd10f7fdda0de0325529a159e9dc3d1038afe4b431a49/langgraph-0.6.7-py3-none-any.whl", hash = "sha256:c724dd8c24806b70faf4903e8e20c0234f8c0a356e0e96a88035cbecca9df2cf", size = 153329, upload-time = "2025-09-07T16:49:40.45Z" }, ] [[package]] @@ -2048,20 +2048,20 @@ wheels = [ [[package]] name = "langgraph-sdk" -version = "0.2.3" +version = "0.2.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, { name = "orjson" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/50/1f5e4d129e3969973674db01bf5dcb85e2233e5e4fdffa53eefff1399902/langgraph_sdk-0.2.3.tar.gz", hash = "sha256:17398aeae0f937cae1c8eb9027ada2969abdb50fe8ed3246c78f543b679cf959", size = 78468, upload-time = "2025-08-21T23:01:06.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/35/a1caf4fdb725adec30f1e9562f218524a92d8b675deb97be653687f086ee/langgraph_sdk-0.2.6.tar.gz", hash = "sha256:7db27cd86d1231fa614823ff416fcd2541b5565ad78ae950f31ae96d7af7c519", size = 80346, upload-time = "2025-09-04T01:51:11.262Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/51/e6e3eb6b3cbad394d00cad128155781bc01e672ff01c5fc1c8a627b35a92/langgraph_sdk-0.2.3-py3-none-any.whl", hash = "sha256:059edfe2f62708c2e54239e170f5a33f796d456dbdbde64276c16cac8b97ba99", size = 52603, upload-time = "2025-08-21T23:01:05.379Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d2/c5fac919601b27a0af5df0bde46e7f1361d5e04505e404b75bed45d21fc8/langgraph_sdk-0.2.6-py3-none-any.whl", hash = "sha256:477216b573b8177bbd849f4c754782a81279fbbd88bfadfeda44422d14b18b08", size = 54565, upload-time = "2025-09-04T01:51:10.044Z" }, ] [[package]] name = "langsmith" -version = "0.4.18" +version = "0.4.25" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -2072,9 +2072,9 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/65/4e79ad22cc12b31a87bdcf96b1ca5ddabe42a8494eda20e124d044d5562e/langsmith-0.4.18.tar.gz", hash = "sha256:c1340371119f66b7c506810c5998db3669cd04f018a276288d80b91169a68ccc", size = 931753, upload-time = "2025-08-26T17:00:05.901Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/84/2f01d51a557d14a9a5590c32de5dde3b466b00a55521450c2c9e77ffa438/langsmith-0.4.25.tar.gz", hash = "sha256:56f0c45810384fba37582ca17fdbcf6ead51934d26d72672e5a810452c0d4ae3", size = 940274, upload-time = "2025-09-04T23:59:33.97Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/73/91a506e17bb1bc6d20c2c04cf7b459dc58951bfbfe7f97f2c952646b4500/langsmith-0.4.18-py3-none-any.whl", hash = "sha256:ad63154f503678356aadf5b999f40393b4bbd332aee2d04cde3e431c61f2e1c2", size = 376444, upload-time = "2025-08-26T17:00:03.564Z" }, + { url = "https://files.pythonhosted.org/packages/a5/85/8a5ca8f6044bd74acd0d364878b459d84ec460cf40aec17ed9cd5716e908/langsmith-0.4.25-py3-none-any.whl", hash = "sha256:adb61784ff58e65f0290ba45770626219fb06a776e69fbcf98aec580478b4686", size = 379416, upload-time = "2025-09-04T23:59:31.72Z" }, ] [[package]] @@ -2462,7 +2462,7 @@ wheels = [ [[package]] name = "openai" -version = "1.105.0" +version = "1.106.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -2474,9 +2474,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6f/a9/c8c2dea8066a8f3079f69c242f7d0d75aaad4c4c3431da5b0df22a24e75d/openai-1.105.0.tar.gz", hash = "sha256:a68a47adce0506d34def22dd78a42cbb6cfecae1cf6a5fe37f38776d32bbb514", size = 557265, upload-time = "2025-09-03T14:14:08.586Z" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b6/1aff7d6b8e9f0c3ac26bfbb57b9861a6711d5d60bd7dd5f7eebbf80509b7/openai-1.106.1.tar.gz", hash = "sha256:5f575967e3a05555825c43829cdcd50be6e49ab6a3e5262f0937a3f791f917f1", size = 561095, upload-time = "2025-09-04T18:17:15.303Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/01/186845829d3a3609bb5b474067959076244dd62540d3e336797319b13924/openai-1.105.0-py3-none-any.whl", hash = "sha256:3ad7635132b0705769ccae31ca7319f59ec0c7d09e94e5e713ce2d130e5b021f", size = 928203, upload-time = "2025-09-03T14:14:06.842Z" }, + { url = "https://files.pythonhosted.org/packages/00/e1/47887212baa7bc0532880d33d5eafbdb46fcc4b53789b903282a74a85b5b/openai-1.106.1-py3-none-any.whl", hash = "sha256:bfdef37c949f80396c59f2c17e0eda35414979bc07ef3379596a93c9ed044f3a", size = 930768, upload-time = "2025-09-04T18:17:13.349Z" }, ] [[package]] @@ -3061,7 +3061,7 @@ crypto = [ [[package]] name = "pytest" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -3072,9 +3072,9 @@ dependencies = [ { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] @@ -3127,28 +3127,28 @@ wheels = [ [[package]] name = "pytest-cov" -version = "6.2.1" +version = "6.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } +sdist = { url = "https://files.pythonhosted.org/packages/30/4c/f883ab8f0daad69f47efdf95f55a66b51a8b939c430dadce0611508d9e99/pytest_cov-6.3.0.tar.gz", hash = "sha256:35c580e7800f87ce892e687461166e1ac2bcb8fb9e13aea79032518d6e503ff2", size = 70398, upload-time = "2025-09-06T15:40:14.361Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl", hash = "sha256:440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749", size = 25115, upload-time = "2025-09-06T15:40:12.44Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.1" +version = "3.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/99/3323ee5c16b3637b4d941c362182d3e749c11e400bea31018c42219f3a98/pytest_mock-3.15.0.tar.gz", hash = "sha256:ab896bd190316b9d5d87b277569dfcdf718b2d049a2ccff5f7aca279c002a1cf", size = 33838, upload-time = "2025-09-04T20:57:48.679Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b3/7fefc43fb706380144bcd293cc6e446e6f637ddfa8b83f48d1734156b529/pytest_mock-3.15.0-py3-none-any.whl", hash = "sha256:ef2219485fb1bd256b00e7ad7466ce26729b30eadfc7cbcdb4fa9a92ca68db6f", size = 10050, upload-time = "2025-09-04T20:57:47.274Z" }, ] [[package]] @@ -3269,81 +3269,81 @@ wheels = [ [[package]] name = "regex" -version = "2025.7.34" +version = "2025.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/de/e13fa6dc61d78b30ba47481f99933a3b49a57779d625c392d8036770a60d/regex-2025.7.34.tar.gz", hash = "sha256:9ead9765217afd04a86822dfcd4ed2747dfe426e887da413b15ff0ac2457e21a", size = 400714, upload-time = "2025-07-31T00:21:16.262Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/5a/4c63457fbcaf19d138d72b2e9b39405954f98c0349b31c601bfcb151582c/regex-2025.9.1.tar.gz", hash = "sha256:88ac07b38d20b54d79e704e38aa3bd2c0f8027432164226bdee201a1c0c9c9ff", size = 400852, upload-time = "2025-09-01T22:10:10.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/d2/0a44a9d92370e5e105f16669acf801b215107efea9dea4317fe96e9aad67/regex-2025.7.34-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d856164d25e2b3b07b779bfed813eb4b6b6ce73c2fd818d46f47c1eb5cd79bd6", size = 484591, upload-time = "2025-07-31T00:18:46.675Z" }, - { url = "https://files.pythonhosted.org/packages/2e/b1/00c4f83aa902f1048495de9f2f33638ce970ce1cf9447b477d272a0e22bb/regex-2025.7.34-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d15a9da5fad793e35fb7be74eec450d968e05d2e294f3e0e77ab03fa7234a83", size = 289293, upload-time = "2025-07-31T00:18:53.069Z" }, - { url = "https://files.pythonhosted.org/packages/f3/b0/5bc5c8ddc418e8be5530b43ae1f7c9303f43aeff5f40185c4287cf6732f2/regex-2025.7.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:95b4639c77d414efa93c8de14ce3f7965a94d007e068a94f9d4997bb9bd9c81f", size = 285932, upload-time = "2025-07-31T00:18:54.673Z" }, - { url = "https://files.pythonhosted.org/packages/46/c7/a1a28d050b23665a5e1eeb4d7f13b83ea86f0bc018da7b8f89f86ff7f094/regex-2025.7.34-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7de1ceed5a5f84f342ba4a9f4ae589524adf9744b2ee61b5da884b5b659834", size = 780361, upload-time = "2025-07-31T00:18:56.13Z" }, - { url = "https://files.pythonhosted.org/packages/cb/0d/82e7afe7b2c9fe3d488a6ab6145d1d97e55f822dfb9b4569aba2497e3d09/regex-2025.7.34-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02e5860a250cd350c4933cf376c3bc9cb28948e2c96a8bc042aee7b985cfa26f", size = 849176, upload-time = "2025-07-31T00:18:57.483Z" }, - { url = "https://files.pythonhosted.org/packages/bf/16/3036e16903d8194f1490af457a7e33b06d9e9edd9576b1fe6c7ac660e9ed/regex-2025.7.34-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a5966220b9a1a88691282b7e4350e9599cf65780ca60d914a798cb791aa1177", size = 897222, upload-time = "2025-07-31T00:18:58.721Z" }, - { url = "https://files.pythonhosted.org/packages/5a/c2/010e089ae00d31418e7d2c6601760eea1957cde12be719730c7133b8c165/regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48fb045bbd4aab2418dc1ba2088a5e32de4bfe64e1457b948bb328a8dc2f1c2e", size = 789831, upload-time = "2025-07-31T00:19:00.436Z" }, - { url = "https://files.pythonhosted.org/packages/dd/86/b312b7bf5c46d21dbd9a3fdc4a80fde56ea93c9c0b89cf401879635e094d/regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:20ff8433fa45e131f7316594efe24d4679c5449c0ca69d91c2f9d21846fdf064", size = 780665, upload-time = "2025-07-31T00:19:01.828Z" }, - { url = "https://files.pythonhosted.org/packages/40/e5/674b82bfff112c820b09e3c86a423d4a568143ede7f8440fdcbce259e895/regex-2025.7.34-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c436fd1e95c04c19039668cfb548450a37c13f051e8659f40aed426e36b3765f", size = 773511, upload-time = "2025-07-31T00:19:03.654Z" }, - { url = "https://files.pythonhosted.org/packages/2d/18/39e7c578eb6cf1454db2b64e4733d7e4f179714867a75d84492ec44fa9b2/regex-2025.7.34-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0b85241d3cfb9f8a13cefdfbd58a2843f208f2ed2c88181bf84e22e0c7fc066d", size = 843990, upload-time = "2025-07-31T00:19:05.61Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d9/522a6715aefe2f463dc60c68924abeeb8ab6893f01adf5720359d94ede8c/regex-2025.7.34-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:075641c94126b064c65ab86e7e71fc3d63e7ff1bea1fb794f0773c97cdad3a03", size = 834676, upload-time = "2025-07-31T00:19:07.023Z" }, - { url = "https://files.pythonhosted.org/packages/59/53/c4d5284cb40543566542e24f1badc9f72af68d01db21e89e36e02292eee0/regex-2025.7.34-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:70645cad3407d103d1dbcb4841839d2946f7d36cf38acbd40120fee1682151e5", size = 778420, upload-time = "2025-07-31T00:19:08.511Z" }, - { url = "https://files.pythonhosted.org/packages/ea/4a/b779a7707d4a44a7e6ee9d0d98e40b2a4de74d622966080e9c95e25e2d24/regex-2025.7.34-cp310-cp310-win32.whl", hash = "sha256:3b836eb4a95526b263c2a3359308600bd95ce7848ebd3c29af0c37c4f9627cd3", size = 263999, upload-time = "2025-07-31T00:19:10.072Z" }, - { url = "https://files.pythonhosted.org/packages/ef/6e/33c7583f5427aa039c28bff7f4103c2de5b6aa5b9edc330c61ec576b1960/regex-2025.7.34-cp310-cp310-win_amd64.whl", hash = "sha256:cbfaa401d77334613cf434f723c7e8ba585df162be76474bccc53ae4e5520b3a", size = 276023, upload-time = "2025-07-31T00:19:11.34Z" }, - { url = "https://files.pythonhosted.org/packages/9f/fc/00b32e0ac14213d76d806d952826402b49fd06d42bfabacdf5d5d016bc47/regex-2025.7.34-cp310-cp310-win_arm64.whl", hash = "sha256:bca11d3c38a47c621769433c47f364b44e8043e0de8e482c5968b20ab90a3986", size = 268357, upload-time = "2025-07-31T00:19:12.729Z" }, - { url = "https://files.pythonhosted.org/packages/0d/85/f497b91577169472f7c1dc262a5ecc65e39e146fc3a52c571e5daaae4b7d/regex-2025.7.34-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da304313761b8500b8e175eb2040c4394a875837d5635f6256d6fa0377ad32c8", size = 484594, upload-time = "2025-07-31T00:19:13.927Z" }, - { url = "https://files.pythonhosted.org/packages/1c/c5/ad2a5c11ce9e6257fcbfd6cd965d07502f6054aaa19d50a3d7fd991ec5d1/regex-2025.7.34-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:35e43ebf5b18cd751ea81455b19acfdec402e82fe0dc6143edfae4c5c4b3909a", size = 289294, upload-time = "2025-07-31T00:19:15.395Z" }, - { url = "https://files.pythonhosted.org/packages/8e/01/83ffd9641fcf5e018f9b51aa922c3e538ac9439424fda3df540b643ecf4f/regex-2025.7.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96bbae4c616726f4661fe7bcad5952e10d25d3c51ddc388189d8864fbc1b3c68", size = 285933, upload-time = "2025-07-31T00:19:16.704Z" }, - { url = "https://files.pythonhosted.org/packages/77/20/5edab2e5766f0259bc1da7381b07ce6eb4401b17b2254d02f492cd8a81a8/regex-2025.7.34-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9feab78a1ffa4f2b1e27b1bcdaad36f48c2fed4870264ce32f52a393db093c78", size = 792335, upload-time = "2025-07-31T00:19:18.561Z" }, - { url = "https://files.pythonhosted.org/packages/30/bd/744d3ed8777dce8487b2606b94925e207e7c5931d5870f47f5b643a4580a/regex-2025.7.34-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f14b36e6d4d07f1a5060f28ef3b3561c5d95eb0651741474ce4c0a4c56ba8719", size = 858605, upload-time = "2025-07-31T00:19:20.204Z" }, - { url = "https://files.pythonhosted.org/packages/99/3d/93754176289718d7578c31d151047e7b8acc7a8c20e7706716f23c49e45e/regex-2025.7.34-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85c3a958ef8b3d5079c763477e1f09e89d13ad22198a37e9d7b26b4b17438b33", size = 905780, upload-time = "2025-07-31T00:19:21.876Z" }, - { url = "https://files.pythonhosted.org/packages/ee/2e/c689f274a92deffa03999a430505ff2aeace408fd681a90eafa92fdd6930/regex-2025.7.34-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37555e4ae0b93358fa7c2d240a4291d4a4227cc7c607d8f85596cdb08ec0a083", size = 798868, upload-time = "2025-07-31T00:19:23.222Z" }, - { url = "https://files.pythonhosted.org/packages/0d/9e/39673688805d139b33b4a24851a71b9978d61915c4d72b5ffda324d0668a/regex-2025.7.34-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee38926f31f1aa61b0232a3a11b83461f7807661c062df9eb88769d86e6195c3", size = 781784, upload-time = "2025-07-31T00:19:24.59Z" }, - { url = "https://files.pythonhosted.org/packages/18/bd/4c1cab12cfabe14beaa076523056b8ab0c882a8feaf0a6f48b0a75dab9ed/regex-2025.7.34-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a664291c31cae9c4a30589bd8bc2ebb56ef880c9c6264cb7643633831e606a4d", size = 852837, upload-time = "2025-07-31T00:19:25.911Z" }, - { url = "https://files.pythonhosted.org/packages/cb/21/663d983cbb3bba537fc213a579abbd0f263fb28271c514123f3c547ab917/regex-2025.7.34-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f3e5c1e0925e77ec46ddc736b756a6da50d4df4ee3f69536ffb2373460e2dafd", size = 844240, upload-time = "2025-07-31T00:19:27.688Z" }, - { url = "https://files.pythonhosted.org/packages/8e/2d/9beeeb913bc5d32faa913cf8c47e968da936af61ec20af5d269d0f84a100/regex-2025.7.34-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d428fc7731dcbb4e2ffe43aeb8f90775ad155e7db4347a639768bc6cd2df881a", size = 787139, upload-time = "2025-07-31T00:19:29.475Z" }, - { url = "https://files.pythonhosted.org/packages/eb/f5/9b9384415fdc533551be2ba805dd8c4621873e5df69c958f403bfd3b2b6e/regex-2025.7.34-cp311-cp311-win32.whl", hash = "sha256:e154a7ee7fa18333ad90b20e16ef84daaeac61877c8ef942ec8dfa50dc38b7a1", size = 264019, upload-time = "2025-07-31T00:19:31.129Z" }, - { url = "https://files.pythonhosted.org/packages/18/9d/e069ed94debcf4cc9626d652a48040b079ce34c7e4fb174f16874958d485/regex-2025.7.34-cp311-cp311-win_amd64.whl", hash = "sha256:24257953d5c1d6d3c129ab03414c07fc1a47833c9165d49b954190b2b7f21a1a", size = 276047, upload-time = "2025-07-31T00:19:32.497Z" }, - { url = "https://files.pythonhosted.org/packages/fd/cf/3bafbe9d1fd1db77355e7fbbbf0d0cfb34501a8b8e334deca14f94c7b315/regex-2025.7.34-cp311-cp311-win_arm64.whl", hash = "sha256:3157aa512b9e606586900888cd469a444f9b898ecb7f8931996cb715f77477f0", size = 268362, upload-time = "2025-07-31T00:19:34.094Z" }, - { url = "https://files.pythonhosted.org/packages/ff/f0/31d62596c75a33f979317658e8d261574785c6cd8672c06741ce2e2e2070/regex-2025.7.34-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7f7211a746aced993bef487de69307a38c5ddd79257d7be83f7b202cb59ddb50", size = 485492, upload-time = "2025-07-31T00:19:35.57Z" }, - { url = "https://files.pythonhosted.org/packages/d8/16/b818d223f1c9758c3434be89aa1a01aae798e0e0df36c1f143d1963dd1ee/regex-2025.7.34-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fb31080f2bd0681484b275461b202b5ad182f52c9ec606052020fe13eb13a72f", size = 290000, upload-time = "2025-07-31T00:19:37.175Z" }, - { url = "https://files.pythonhosted.org/packages/cd/70/69506d53397b4bd6954061bae75677ad34deb7f6ca3ba199660d6f728ff5/regex-2025.7.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0200a5150c4cf61e407038f4b4d5cdad13e86345dac29ff9dab3d75d905cf130", size = 286072, upload-time = "2025-07-31T00:19:38.612Z" }, - { url = "https://files.pythonhosted.org/packages/b0/73/536a216d5f66084fb577bb0543b5cb7de3272eb70a157f0c3a542f1c2551/regex-2025.7.34-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:739a74970e736df0773788377969c9fea3876c2fc13d0563f98e5503e5185f46", size = 797341, upload-time = "2025-07-31T00:19:40.119Z" }, - { url = "https://files.pythonhosted.org/packages/26/af/733f8168449e56e8f404bb807ea7189f59507cbea1b67a7bbcd92f8bf844/regex-2025.7.34-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4fef81b2f7ea6a2029161ed6dea9ae13834c28eb5a95b8771828194a026621e4", size = 862556, upload-time = "2025-07-31T00:19:41.556Z" }, - { url = "https://files.pythonhosted.org/packages/19/dd/59c464d58c06c4f7d87de4ab1f590e430821345a40c5d345d449a636d15f/regex-2025.7.34-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea74cf81fe61a7e9d77989050d0089a927ab758c29dac4e8e1b6c06fccf3ebf0", size = 910762, upload-time = "2025-07-31T00:19:43Z" }, - { url = "https://files.pythonhosted.org/packages/37/a8/b05ccf33ceca0815a1e253693b2c86544932ebcc0049c16b0fbdf18b688b/regex-2025.7.34-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e4636a7f3b65a5f340ed9ddf53585c42e3ff37101d383ed321bfe5660481744b", size = 801892, upload-time = "2025-07-31T00:19:44.645Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9a/b993cb2e634cc22810afd1652dba0cae156c40d4864285ff486c73cd1996/regex-2025.7.34-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cef962d7834437fe8d3da6f9bfc6f93f20f218266dcefec0560ed7765f5fe01", size = 786551, upload-time = "2025-07-31T00:19:46.127Z" }, - { url = "https://files.pythonhosted.org/packages/2d/79/7849d67910a0de4e26834b5bb816e028e35473f3d7ae563552ea04f58ca2/regex-2025.7.34-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:cbe1698e5b80298dbce8df4d8d1182279fbdaf1044e864cbc9d53c20e4a2be77", size = 856457, upload-time = "2025-07-31T00:19:47.562Z" }, - { url = "https://files.pythonhosted.org/packages/91/c6/de516bc082524b27e45cb4f54e28bd800c01efb26d15646a65b87b13a91e/regex-2025.7.34-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:32b9f9bcf0f605eb094b08e8da72e44badabb63dde6b83bd530580b488d1c6da", size = 848902, upload-time = "2025-07-31T00:19:49.312Z" }, - { url = "https://files.pythonhosted.org/packages/7d/22/519ff8ba15f732db099b126f039586bd372da6cd4efb810d5d66a5daeda1/regex-2025.7.34-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:524c868ba527eab4e8744a9287809579f54ae8c62fbf07d62aacd89f6026b282", size = 788038, upload-time = "2025-07-31T00:19:50.794Z" }, - { url = "https://files.pythonhosted.org/packages/3f/7d/aabb467d8f57d8149895d133c88eb809a1a6a0fe262c1d508eb9dfabb6f9/regex-2025.7.34-cp312-cp312-win32.whl", hash = "sha256:d600e58ee6d036081c89696d2bdd55d507498a7180df2e19945c6642fac59588", size = 264417, upload-time = "2025-07-31T00:19:52.292Z" }, - { url = "https://files.pythonhosted.org/packages/3b/39/bd922b55a4fc5ad5c13753274e5b536f5b06ec8eb9747675668491c7ab7a/regex-2025.7.34-cp312-cp312-win_amd64.whl", hash = "sha256:9a9ab52a466a9b4b91564437b36417b76033e8778e5af8f36be835d8cb370d62", size = 275387, upload-time = "2025-07-31T00:19:53.593Z" }, - { url = "https://files.pythonhosted.org/packages/f7/3c/c61d2fdcecb754a40475a3d1ef9a000911d3e3fc75c096acf44b0dfb786a/regex-2025.7.34-cp312-cp312-win_arm64.whl", hash = "sha256:c83aec91af9c6fbf7c743274fd952272403ad9a9db05fe9bfc9df8d12b45f176", size = 268482, upload-time = "2025-07-31T00:19:55.183Z" }, - { url = "https://files.pythonhosted.org/packages/15/16/b709b2119975035169a25aa8e4940ca177b1a2e25e14f8d996d09130368e/regex-2025.7.34-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c3c9740a77aeef3f5e3aaab92403946a8d34437db930a0280e7e81ddcada61f5", size = 485334, upload-time = "2025-07-31T00:19:56.58Z" }, - { url = "https://files.pythonhosted.org/packages/94/a6/c09136046be0595f0331bc58a0e5f89c2d324cf734e0b0ec53cf4b12a636/regex-2025.7.34-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:69ed3bc611540f2ea70a4080f853741ec698be556b1df404599f8724690edbcd", size = 289942, upload-time = "2025-07-31T00:19:57.943Z" }, - { url = "https://files.pythonhosted.org/packages/36/91/08fc0fd0f40bdfb0e0df4134ee37cfb16e66a1044ac56d36911fd01c69d2/regex-2025.7.34-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d03c6f9dcd562c56527c42b8530aad93193e0b3254a588be1f2ed378cdfdea1b", size = 285991, upload-time = "2025-07-31T00:19:59.837Z" }, - { url = "https://files.pythonhosted.org/packages/be/2f/99dc8f6f756606f0c214d14c7b6c17270b6bbe26d5c1f05cde9dbb1c551f/regex-2025.7.34-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6164b1d99dee1dfad33f301f174d8139d4368a9fb50bf0a3603b2eaf579963ad", size = 797415, upload-time = "2025-07-31T00:20:01.668Z" }, - { url = "https://files.pythonhosted.org/packages/62/cf/2fcdca1110495458ba4e95c52ce73b361cf1cafd8a53b5c31542cde9a15b/regex-2025.7.34-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1e4f4f62599b8142362f164ce776f19d79bdd21273e86920a7b604a4275b4f59", size = 862487, upload-time = "2025-07-31T00:20:03.142Z" }, - { url = "https://files.pythonhosted.org/packages/90/38/899105dd27fed394e3fae45607c1983e138273ec167e47882fc401f112b9/regex-2025.7.34-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72a26dcc6a59c057b292f39d41465d8233a10fd69121fa24f8f43ec6294e5415", size = 910717, upload-time = "2025-07-31T00:20:04.727Z" }, - { url = "https://files.pythonhosted.org/packages/ee/f6/4716198dbd0bcc9c45625ac4c81a435d1c4d8ad662e8576dac06bab35b17/regex-2025.7.34-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5273fddf7a3e602695c92716c420c377599ed3c853ea669c1fe26218867002f", size = 801943, upload-time = "2025-07-31T00:20:07.1Z" }, - { url = "https://files.pythonhosted.org/packages/40/5d/cff8896d27e4e3dd11dd72ac78797c7987eb50fe4debc2c0f2f1682eb06d/regex-2025.7.34-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c1844be23cd40135b3a5a4dd298e1e0c0cb36757364dd6cdc6025770363e06c1", size = 786664, upload-time = "2025-07-31T00:20:08.818Z" }, - { url = "https://files.pythonhosted.org/packages/10/29/758bf83cf7b4c34f07ac3423ea03cee3eb3176941641e4ccc05620f6c0b8/regex-2025.7.34-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dde35e2afbbe2272f8abee3b9fe6772d9b5a07d82607b5788e8508974059925c", size = 856457, upload-time = "2025-07-31T00:20:10.328Z" }, - { url = "https://files.pythonhosted.org/packages/d7/30/c19d212b619963c5b460bfed0ea69a092c6a43cba52a973d46c27b3e2975/regex-2025.7.34-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f6e8e7af516a7549412ce57613e859c3be27d55341a894aacaa11703a4c31a", size = 849008, upload-time = "2025-07-31T00:20:11.823Z" }, - { url = "https://files.pythonhosted.org/packages/9e/b8/3c35da3b12c87e3cc00010ef6c3a4ae787cff0bc381aa3d251def219969a/regex-2025.7.34-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:469142fb94a869beb25b5f18ea87646d21def10fbacb0bcb749224f3509476f0", size = 788101, upload-time = "2025-07-31T00:20:13.729Z" }, - { url = "https://files.pythonhosted.org/packages/47/80/2f46677c0b3c2b723b2c358d19f9346e714113865da0f5f736ca1a883bde/regex-2025.7.34-cp313-cp313-win32.whl", hash = "sha256:da7507d083ee33ccea1310447410c27ca11fb9ef18c95899ca57ff60a7e4d8f1", size = 264401, upload-time = "2025-07-31T00:20:15.233Z" }, - { url = "https://files.pythonhosted.org/packages/be/fa/917d64dd074682606a003cba33585c28138c77d848ef72fc77cbb1183849/regex-2025.7.34-cp313-cp313-win_amd64.whl", hash = "sha256:9d644de5520441e5f7e2db63aec2748948cc39ed4d7a87fd5db578ea4043d997", size = 275368, upload-time = "2025-07-31T00:20:16.711Z" }, - { url = "https://files.pythonhosted.org/packages/65/cd/f94383666704170a2154a5df7b16be28f0c27a266bffcd843e58bc84120f/regex-2025.7.34-cp313-cp313-win_arm64.whl", hash = "sha256:7bf1c5503a9f2cbd2f52d7e260acb3131b07b6273c470abb78568174fe6bde3f", size = 268482, upload-time = "2025-07-31T00:20:18.189Z" }, - { url = "https://files.pythonhosted.org/packages/ac/23/6376f3a23cf2f3c00514b1cdd8c990afb4dfbac3cb4a68b633c6b7e2e307/regex-2025.7.34-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:8283afe7042d8270cecf27cca558873168e771183d4d593e3c5fe5f12402212a", size = 485385, upload-time = "2025-07-31T00:20:19.692Z" }, - { url = "https://files.pythonhosted.org/packages/73/5b/6d4d3a0b4d312adbfd6d5694c8dddcf1396708976dd87e4d00af439d962b/regex-2025.7.34-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6c053f9647e3421dd2f5dff8172eb7b4eec129df9d1d2f7133a4386319b47435", size = 289788, upload-time = "2025-07-31T00:20:21.941Z" }, - { url = "https://files.pythonhosted.org/packages/92/71/5862ac9913746e5054d01cb9fb8125b3d0802c0706ef547cae1e7f4428fa/regex-2025.7.34-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a16dd56bbcb7d10e62861c3cd000290ddff28ea142ffb5eb3470f183628011ac", size = 286136, upload-time = "2025-07-31T00:20:26.146Z" }, - { url = "https://files.pythonhosted.org/packages/27/df/5b505dc447eb71278eba10d5ec940769ca89c1af70f0468bfbcb98035dc2/regex-2025.7.34-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69c593ff5a24c0d5c1112b0df9b09eae42b33c014bdca7022d6523b210b69f72", size = 797753, upload-time = "2025-07-31T00:20:27.919Z" }, - { url = "https://files.pythonhosted.org/packages/86/38/3e3dc953d13998fa047e9a2414b556201dbd7147034fbac129392363253b/regex-2025.7.34-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98d0ce170fcde1a03b5df19c5650db22ab58af375aaa6ff07978a85c9f250f0e", size = 863263, upload-time = "2025-07-31T00:20:29.803Z" }, - { url = "https://files.pythonhosted.org/packages/68/e5/3ff66b29dde12f5b874dda2d9dec7245c2051f2528d8c2a797901497f140/regex-2025.7.34-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d72765a4bff8c43711d5b0f5b452991a9947853dfa471972169b3cc0ba1d0751", size = 910103, upload-time = "2025-07-31T00:20:31.313Z" }, - { url = "https://files.pythonhosted.org/packages/9e/fe/14176f2182125977fba3711adea73f472a11f3f9288c1317c59cd16ad5e6/regex-2025.7.34-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4494f8fd95a77eb434039ad8460e64d57baa0434f1395b7da44015bef650d0e4", size = 801709, upload-time = "2025-07-31T00:20:33.323Z" }, - { url = "https://files.pythonhosted.org/packages/5a/0d/80d4e66ed24f1ba876a9e8e31b709f9fd22d5c266bf5f3ab3c1afe683d7d/regex-2025.7.34-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4f42b522259c66e918a0121a12429b2abcf696c6f967fa37bdc7b72e61469f98", size = 786726, upload-time = "2025-07-31T00:20:35.252Z" }, - { url = "https://files.pythonhosted.org/packages/12/75/c3ebb30e04a56c046f5c85179dc173818551037daae2c0c940c7b19152cb/regex-2025.7.34-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:aaef1f056d96a0a5d53ad47d019d5b4c66fe4be2da87016e0d43b7242599ffc7", size = 857306, upload-time = "2025-07-31T00:20:37.12Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b2/a4dc5d8b14f90924f27f0ac4c4c4f5e195b723be98adecc884f6716614b6/regex-2025.7.34-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:656433e5b7dccc9bc0da6312da8eb897b81f5e560321ec413500e5367fcd5d47", size = 848494, upload-time = "2025-07-31T00:20:38.818Z" }, - { url = "https://files.pythonhosted.org/packages/0d/21/9ac6e07a4c5e8646a90b56b61f7e9dac11ae0747c857f91d3d2bc7c241d9/regex-2025.7.34-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e91eb2c62c39705e17b4d42d4b86c4e86c884c0d15d9c5a47d0835f8387add8e", size = 787850, upload-time = "2025-07-31T00:20:40.478Z" }, - { url = "https://files.pythonhosted.org/packages/be/6c/d51204e28e7bc54f9a03bb799b04730d7e54ff2718862b8d4e09e7110a6a/regex-2025.7.34-cp314-cp314-win32.whl", hash = "sha256:f978ddfb6216028c8f1d6b0f7ef779949498b64117fc35a939022f67f810bdcb", size = 269730, upload-time = "2025-07-31T00:20:42.253Z" }, - { url = "https://files.pythonhosted.org/packages/74/52/a7e92d02fa1fdef59d113098cb9f02c5d03289a0e9f9e5d4d6acccd10677/regex-2025.7.34-cp314-cp314-win_amd64.whl", hash = "sha256:4b7dc33b9b48fb37ead12ffc7bdb846ac72f99a80373c4da48f64b373a7abeae", size = 278640, upload-time = "2025-07-31T00:20:44.42Z" }, - { url = "https://files.pythonhosted.org/packages/d1/78/a815529b559b1771080faa90c3ab401730661f99d495ab0071649f139ebd/regex-2025.7.34-cp314-cp314-win_arm64.whl", hash = "sha256:4b8c4d39f451e64809912c82392933d80fe2e4a87eeef8859fcc5380d0173c64", size = 271757, upload-time = "2025-07-31T00:20:46.355Z" }, + { url = "https://files.pythonhosted.org/packages/46/c1/ed9ef923156105a78aa004f9390e5dd87eadc29f5ca8840f172cadb638de/regex-2025.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5aa2a6a73bf218515484b36a0d20c6ad9dc63f6339ff6224147b0e2c095ee55", size = 484813, upload-time = "2025-09-01T22:07:45.528Z" }, + { url = "https://files.pythonhosted.org/packages/05/de/97957618a774c67f892609eee2fafe3e30703fbbba66de5e6b79d7196dbc/regex-2025.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8c2ff5c01d5e47ad5fc9d31bcd61e78c2fa0068ed00cab86b7320214446da766", size = 288981, upload-time = "2025-09-01T22:07:48.464Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b0/441afadd0a6ffccbd58a9663e5bdd182daa237893e5f8ceec6ff9df4418a/regex-2025.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d49dc84e796b666181de8a9973284cad6616335f01b52bf099643253094920fc", size = 286608, upload-time = "2025-09-01T22:07:50.484Z" }, + { url = "https://files.pythonhosted.org/packages/6e/cf/d89aecaf17e999ab11a3ef73fc9ab8b64f4e156f121250ef84340b35338d/regex-2025.9.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9914fe1040874f83c15fcea86d94ea54091b0666eab330aaab69e30d106aabe", size = 780459, upload-time = "2025-09-01T22:07:52.34Z" }, + { url = "https://files.pythonhosted.org/packages/f6/05/05884594a9975a29597917bbdd6837f7b97e8ac23faf22d628aa781e58f7/regex-2025.9.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e71bceb3947362ec5eabd2ca0870bb78eae4edfc60c6c21495133c01b6cd2df4", size = 849276, upload-time = "2025-09-01T22:07:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/8c/8d/2b3067506838d02096bf107beb129b2ce328cdf776d6474b7f542c0a7bfd/regex-2025.9.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67a74456f410fe5e869239ee7a5423510fe5121549af133809d9591a8075893f", size = 897320, upload-time = "2025-09-01T22:07:56.129Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b3/0f9f7766e980b900df0ba9901b52871a2e4203698fb35cdebd219240d5f7/regex-2025.9.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c3b96ed0223b32dbdc53a83149b6de7ca3acd5acd9c8e64b42a166228abe29c", size = 789931, upload-time = "2025-09-01T22:07:57.834Z" }, + { url = "https://files.pythonhosted.org/packages/47/9f/7b2f29c8f8b698eb44be5fc68e8b9c8d32e99635eac5defc98de114e9f35/regex-2025.9.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:113d5aa950f428faf46fd77d452df62ebb4cc6531cb619f6cc30a369d326bfbd", size = 780764, upload-time = "2025-09-01T22:07:59.413Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ac/56176caa86155c14462531eb0a4ddc450d17ba8875001122b3b7c0cb01bf/regex-2025.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fcdeb38de4f7f3d69d798f4f371189061446792a84e7c92b50054c87aae9c07c", size = 773610, upload-time = "2025-09-01T22:08:01.042Z" }, + { url = "https://files.pythonhosted.org/packages/39/e8/9d6b9bd43998268a9de2f35602077519cacc9cb149f7381758cf8f502ba7/regex-2025.9.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4bcdff370509164b67a6c8ec23c9fb40797b72a014766fdc159bb809bd74f7d8", size = 844090, upload-time = "2025-09-01T22:08:02.94Z" }, + { url = "https://files.pythonhosted.org/packages/fd/92/d89743b089005cae4cb81cc2fe177e180b7452e60f29de53af34349640f8/regex-2025.9.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:7383efdf6e8e8c61d85e00cfb2e2e18da1a621b8bfb4b0f1c2747db57b942b8f", size = 834775, upload-time = "2025-09-01T22:08:04.781Z" }, + { url = "https://files.pythonhosted.org/packages/01/8f/86a3e0aaa89295d2a3445bb238e56369963ef6b02a5b4aa3362f4e687413/regex-2025.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1ec2bd3bdf0f73f7e9f48dca550ba7d973692d5e5e9a90ac42cc5f16c4432d8b", size = 778521, upload-time = "2025-09-01T22:08:06.596Z" }, + { url = "https://files.pythonhosted.org/packages/3e/df/72072acb370ee8577c255717f8a58264f1d0de40aa3c9e6ebd5271cac633/regex-2025.9.1-cp310-cp310-win32.whl", hash = "sha256:9627e887116c4e9c0986d5c3b4f52bcfe3df09850b704f62ec3cbf177a0ae374", size = 264105, upload-time = "2025-09-01T22:08:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/97/73/fb82faaf0375aeaa1bb675008246c79b6779fa5688585a35327610ea0e2e/regex-2025.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:94533e32dc0065eca43912ee6649c90ea0681d59f56d43c45b5bcda9a740b3dd", size = 276131, upload-time = "2025-09-01T22:08:10.156Z" }, + { url = "https://files.pythonhosted.org/packages/d3/3a/77d7718a2493e54725494f44da1a1e55704743dc4b8fabe5b0596f7b8014/regex-2025.9.1-cp310-cp310-win_arm64.whl", hash = "sha256:a874a61bb580d48642ffd338570ee24ab13fa023779190513fcacad104a6e251", size = 268462, upload-time = "2025-09-01T22:08:11.651Z" }, + { url = "https://files.pythonhosted.org/packages/06/4d/f741543c0c59f96c6625bc6c11fea1da2e378b7d293ffff6f318edc0ce14/regex-2025.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e5bcf112b09bfd3646e4db6bf2e598534a17d502b0c01ea6550ba4eca780c5e6", size = 484811, upload-time = "2025-09-01T22:08:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bd/27e73e92635b6fbd51afc26a414a3133243c662949cd1cda677fe7bb09bd/regex-2025.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:67a0295a3c31d675a9ee0238d20238ff10a9a2fdb7a1323c798fc7029578b15c", size = 288977, upload-time = "2025-09-01T22:08:14.499Z" }, + { url = "https://files.pythonhosted.org/packages/eb/7d/7dc0c6efc8bc93cd6e9b947581f5fde8a5dbaa0af7c4ec818c5729fdc807/regex-2025.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea8267fbadc7d4bd7c1301a50e85c2ff0de293ff9452a1a9f8d82c6cafe38179", size = 286606, upload-time = "2025-09-01T22:08:15.881Z" }, + { url = "https://files.pythonhosted.org/packages/d1/01/9b5c6dd394f97c8f2c12f6e8f96879c9ac27292a718903faf2e27a0c09f6/regex-2025.9.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6aeff21de7214d15e928fb5ce757f9495214367ba62875100d4c18d293750cc1", size = 792436, upload-time = "2025-09-01T22:08:17.38Z" }, + { url = "https://files.pythonhosted.org/packages/fc/24/b7430cfc6ee34bbb3db6ff933beb5e7692e5cc81e8f6f4da63d353566fb0/regex-2025.9.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d89f1bbbbbc0885e1c230f7770d5e98f4f00b0ee85688c871d10df8b184a6323", size = 858705, upload-time = "2025-09-01T22:08:19.037Z" }, + { url = "https://files.pythonhosted.org/packages/d6/98/155f914b4ea6ae012663188545c4f5216c11926d09b817127639d618b003/regex-2025.9.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca3affe8ddea498ba9d294ab05f5f2d3b5ad5d515bc0d4a9016dd592a03afe52", size = 905881, upload-time = "2025-09-01T22:08:20.377Z" }, + { url = "https://files.pythonhosted.org/packages/8a/a7/a470e7bc8259c40429afb6d6a517b40c03f2f3e455c44a01abc483a1c512/regex-2025.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:91892a7a9f0a980e4c2c85dd19bc14de2b219a3a8867c4b5664b9f972dcc0c78", size = 798968, upload-time = "2025-09-01T22:08:22.081Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fa/33f6fec4d41449fea5f62fdf5e46d668a1c046730a7f4ed9f478331a8e3a/regex-2025.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e1cb40406f4ae862710615f9f636c1e030fd6e6abe0e0f65f6a695a2721440c6", size = 781884, upload-time = "2025-09-01T22:08:23.832Z" }, + { url = "https://files.pythonhosted.org/packages/42/de/2b45f36ab20da14eedddf5009d370625bc5942d9953fa7e5037a32d66843/regex-2025.9.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:94f6cff6f7e2149c7e6499a6ecd4695379eeda8ccbccb9726e8149f2fe382e92", size = 852935, upload-time = "2025-09-01T22:08:25.536Z" }, + { url = "https://files.pythonhosted.org/packages/1e/f9/878f4fc92c87e125e27aed0f8ee0d1eced9b541f404b048f66f79914475a/regex-2025.9.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6c0226fb322b82709e78c49cc33484206647f8a39954d7e9de1567f5399becd0", size = 844340, upload-time = "2025-09-01T22:08:27.141Z" }, + { url = "https://files.pythonhosted.org/packages/90/c2/5b6f2bce6ece5f8427c718c085eca0de4bbb4db59f54db77aa6557aef3e9/regex-2025.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a12f59c7c380b4fcf7516e9cbb126f95b7a9518902bcf4a852423ff1dcd03e6a", size = 787238, upload-time = "2025-09-01T22:08:28.75Z" }, + { url = "https://files.pythonhosted.org/packages/47/66/1ef1081c831c5b611f6f55f6302166cfa1bc9574017410ba5595353f846a/regex-2025.9.1-cp311-cp311-win32.whl", hash = "sha256:49865e78d147a7a4f143064488da5d549be6bfc3f2579e5044cac61f5c92edd4", size = 264118, upload-time = "2025-09-01T22:08:30.388Z" }, + { url = "https://files.pythonhosted.org/packages/ad/e0/8adc550d7169df1d6b9be8ff6019cda5291054a0107760c2f30788b6195f/regex-2025.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:d34b901f6f2f02ef60f4ad3855d3a02378c65b094efc4b80388a3aeb700a5de7", size = 276151, upload-time = "2025-09-01T22:08:32.073Z" }, + { url = "https://files.pythonhosted.org/packages/cb/bd/46fef29341396d955066e55384fb93b0be7d64693842bf4a9a398db6e555/regex-2025.9.1-cp311-cp311-win_arm64.whl", hash = "sha256:47d7c2dab7e0b95b95fd580087b6ae196039d62306a592fa4e162e49004b6299", size = 268460, upload-time = "2025-09-01T22:08:33.281Z" }, + { url = "https://files.pythonhosted.org/packages/39/ef/a0372febc5a1d44c1be75f35d7e5aff40c659ecde864d7fa10e138f75e74/regex-2025.9.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:84a25164bd8dcfa9f11c53f561ae9766e506e580b70279d05a7946510bdd6f6a", size = 486317, upload-time = "2025-09-01T22:08:34.529Z" }, + { url = "https://files.pythonhosted.org/packages/b5/25/d64543fb7eb41a1024786d518cc57faf1ce64aa6e9ddba097675a0c2f1d2/regex-2025.9.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:645e88a73861c64c1af558dd12294fb4e67b5c1eae0096a60d7d8a2143a611c7", size = 289698, upload-time = "2025-09-01T22:08:36.162Z" }, + { url = "https://files.pythonhosted.org/packages/d8/dc/fbf31fc60be317bd9f6f87daa40a8a9669b3b392aa8fe4313df0a39d0722/regex-2025.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:10a450cba5cd5409526ee1d4449f42aad38dd83ac6948cbd6d7f71ca7018f7db", size = 287242, upload-time = "2025-09-01T22:08:37.794Z" }, + { url = "https://files.pythonhosted.org/packages/0f/74/f933a607a538f785da5021acf5323961b4620972e2c2f1f39b6af4b71db7/regex-2025.9.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9dc5991592933a4192c166eeb67b29d9234f9c86344481173d1bc52f73a7104", size = 797441, upload-time = "2025-09-01T22:08:39.108Z" }, + { url = "https://files.pythonhosted.org/packages/89/d0/71fc49b4f20e31e97f199348b8c4d6e613e7b6a54a90eb1b090c2b8496d7/regex-2025.9.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a32291add816961aab472f4fad344c92871a2ee33c6c219b6598e98c1f0108f2", size = 862654, upload-time = "2025-09-01T22:08:40.586Z" }, + { url = "https://files.pythonhosted.org/packages/59/05/984edce1411a5685ba9abbe10d42cdd9450aab4a022271f9585539788150/regex-2025.9.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:588c161a68a383478e27442a678e3b197b13c5ba51dbba40c1ccb8c4c7bee9e9", size = 910862, upload-time = "2025-09-01T22:08:42.416Z" }, + { url = "https://files.pythonhosted.org/packages/b2/02/5c891bb5fe0691cc1bad336e3a94b9097fbcf9707ec8ddc1dce9f0397289/regex-2025.9.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47829ffaf652f30d579534da9085fe30c171fa2a6744a93d52ef7195dc38218b", size = 801991, upload-time = "2025-09-01T22:08:44.072Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ae/fd10d6ad179910f7a1b3e0a7fde1ef8bb65e738e8ac4fd6ecff3f52252e4/regex-2025.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e978e5a35b293ea43f140c92a3269b6ab13fe0a2bf8a881f7ac740f5a6ade85", size = 786651, upload-time = "2025-09-01T22:08:46.079Z" }, + { url = "https://files.pythonhosted.org/packages/30/cf/9d686b07bbc5bf94c879cc168db92542d6bc9fb67088d03479fef09ba9d3/regex-2025.9.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf09903e72411f4bf3ac1eddd624ecfd423f14b2e4bf1c8b547b72f248b7bf7", size = 856556, upload-time = "2025-09-01T22:08:48.376Z" }, + { url = "https://files.pythonhosted.org/packages/91/9d/302f8a29bb8a49528abbab2d357a793e2a59b645c54deae0050f8474785b/regex-2025.9.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d016b0f77be63e49613c9e26aaf4a242f196cd3d7a4f15898f5f0ab55c9b24d2", size = 849001, upload-time = "2025-09-01T22:08:50.067Z" }, + { url = "https://files.pythonhosted.org/packages/93/fa/b4c6dbdedc85ef4caec54c817cd5f4418dbfa2453214119f2538082bf666/regex-2025.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:656563e620de6908cd1c9d4f7b9e0777e3341ca7db9d4383bcaa44709c90281e", size = 788138, upload-time = "2025-09-01T22:08:51.933Z" }, + { url = "https://files.pythonhosted.org/packages/4a/1b/91ee17a3cbf87f81e8c110399279d0e57f33405468f6e70809100f2ff7d8/regex-2025.9.1-cp312-cp312-win32.whl", hash = "sha256:df33f4ef07b68f7ab637b1dbd70accbf42ef0021c201660656601e8a9835de45", size = 264524, upload-time = "2025-09-01T22:08:53.75Z" }, + { url = "https://files.pythonhosted.org/packages/92/28/6ba31cce05b0f1ec6b787921903f83bd0acf8efde55219435572af83c350/regex-2025.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:5aba22dfbc60cda7c0853516104724dc904caa2db55f2c3e6e984eb858d3edf3", size = 275489, upload-time = "2025-09-01T22:08:55.037Z" }, + { url = "https://files.pythonhosted.org/packages/bd/ed/ea49f324db00196e9ef7fe00dd13c6164d5173dd0f1bbe495e61bb1fb09d/regex-2025.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:ec1efb4c25e1849c2685fa95da44bfde1b28c62d356f9c8d861d4dad89ed56e9", size = 268589, upload-time = "2025-09-01T22:08:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/98/25/b2959ce90c6138c5142fe5264ee1f9b71a0c502ca4c7959302a749407c79/regex-2025.9.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bc6834727d1b98d710a63e6c823edf6ffbf5792eba35d3fa119531349d4142ef", size = 485932, upload-time = "2025-09-01T22:08:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/49/2e/6507a2a85f3f2be6643438b7bd976e67ad73223692d6988eb1ff444106d3/regex-2025.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c3dc05b6d579875719bccc5f3037b4dc80433d64e94681a0061845bd8863c025", size = 289568, upload-time = "2025-09-01T22:08:59.258Z" }, + { url = "https://files.pythonhosted.org/packages/c7/d8/de4a4b57215d99868f1640e062a7907e185ec7476b4b689e2345487c1ff4/regex-2025.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22213527df4c985ec4a729b055a8306272d41d2f45908d7bacb79be0fa7a75ad", size = 286984, upload-time = "2025-09-01T22:09:00.835Z" }, + { url = "https://files.pythonhosted.org/packages/03/15/e8cb403403a57ed316e80661db0e54d7aa2efcd85cb6156f33cc18746922/regex-2025.9.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8e3f6e3c5a5a1adc3f7ea1b5aec89abfc2f4fbfba55dafb4343cd1d084f715b2", size = 797514, upload-time = "2025-09-01T22:09:02.538Z" }, + { url = "https://files.pythonhosted.org/packages/e4/26/2446f2b9585fed61faaa7e2bbce3aca7dd8df6554c32addee4c4caecf24a/regex-2025.9.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bcb89c02a0d6c2bec9b0bb2d8c78782699afe8434493bfa6b4021cc51503f249", size = 862586, upload-time = "2025-09-01T22:09:04.322Z" }, + { url = "https://files.pythonhosted.org/packages/fd/b8/82ffbe9c0992c31bbe6ae1c4b4e21269a5df2559102b90543c9b56724c3c/regex-2025.9.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b0e2f95413eb0c651cd1516a670036315b91b71767af83bc8525350d4375ccba", size = 910815, upload-time = "2025-09-01T22:09:05.978Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d8/7303ea38911759c1ee30cc5bc623ee85d3196b733c51fd6703c34290a8d9/regex-2025.9.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a41dc039e1c97d3c2ed3e26523f748e58c4de3ea7a31f95e1cf9ff973fff5a", size = 802042, upload-time = "2025-09-01T22:09:07.865Z" }, + { url = "https://files.pythonhosted.org/packages/fc/0e/6ad51a55ed4b5af512bb3299a05d33309bda1c1d1e1808fa869a0bed31bc/regex-2025.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f0b4258b161094f66857a26ee938d3fe7b8a5063861e44571215c44fbf0e5df", size = 786764, upload-time = "2025-09-01T22:09:09.362Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d5/394e3ffae6baa5a9217bbd14d96e0e5da47bb069d0dbb8278e2681a2b938/regex-2025.9.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bf70e18ac390e6977ea7e56f921768002cb0fa359c4199606c7219854ae332e0", size = 856557, upload-time = "2025-09-01T22:09:11.129Z" }, + { url = "https://files.pythonhosted.org/packages/cd/80/b288d3910c41194ad081b9fb4b371b76b0bbfdce93e7709fc98df27b37dc/regex-2025.9.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b84036511e1d2bb0a4ff1aec26951caa2dea8772b223c9e8a19ed8885b32dbac", size = 849108, upload-time = "2025-09-01T22:09:12.877Z" }, + { url = "https://files.pythonhosted.org/packages/d1/cd/5ec76bf626d0d5abdc277b7a1734696f5f3d14fbb4a3e2540665bc305d85/regex-2025.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c2e05dcdfe224047f2a59e70408274c325d019aad96227ab959403ba7d58d2d7", size = 788201, upload-time = "2025-09-01T22:09:14.561Z" }, + { url = "https://files.pythonhosted.org/packages/b5/36/674672f3fdead107565a2499f3007788b878188acec6d42bc141c5366c2c/regex-2025.9.1-cp313-cp313-win32.whl", hash = "sha256:3b9a62107a7441b81ca98261808fed30ae36ba06c8b7ee435308806bd53c1ed8", size = 264508, upload-time = "2025-09-01T22:09:16.193Z" }, + { url = "https://files.pythonhosted.org/packages/83/ad/931134539515eb64ce36c24457a98b83c1b2e2d45adf3254b94df3735a76/regex-2025.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:b38afecc10c177eb34cfae68d669d5161880849ba70c05cbfbe409f08cc939d7", size = 275469, upload-time = "2025-09-01T22:09:17.462Z" }, + { url = "https://files.pythonhosted.org/packages/24/8c/96d34e61c0e4e9248836bf86d69cb224fd222f270fa9045b24e218b65604/regex-2025.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:ec329890ad5e7ed9fc292858554d28d58d56bf62cf964faf0aa57964b21155a0", size = 268586, upload-time = "2025-09-01T22:09:18.948Z" }, + { url = "https://files.pythonhosted.org/packages/21/b1/453cbea5323b049181ec6344a803777914074b9726c9c5dc76749966d12d/regex-2025.9.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:72fb7a016467d364546f22b5ae86c45680a4e0de6b2a6f67441d22172ff641f1", size = 486111, upload-time = "2025-09-01T22:09:20.734Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0e/92577f197bd2f7652c5e2857f399936c1876978474ecc5b068c6d8a79c86/regex-2025.9.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c9527fa74eba53f98ad86be2ba003b3ebe97e94b6eb2b916b31b5f055622ef03", size = 289520, upload-time = "2025-09-01T22:09:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/af/c6/b472398116cca7ea5a6c4d5ccd0fc543f7fd2492cb0c48d2852a11972f73/regex-2025.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c905d925d194c83a63f92422af7544ec188301451b292c8b487f0543726107ca", size = 287215, upload-time = "2025-09-01T22:09:23.657Z" }, + { url = "https://files.pythonhosted.org/packages/cf/11/f12ecb0cf9ca792a32bb92f758589a84149017467a544f2f6bfb45c0356d/regex-2025.9.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:74df7c74a63adcad314426b1f4ea6054a5ab25d05b0244f0c07ff9ce640fa597", size = 797855, upload-time = "2025-09-01T22:09:25.197Z" }, + { url = "https://files.pythonhosted.org/packages/46/88/bbb848f719a540fb5997e71310f16f0b33a92c5d4b4d72d4311487fff2a3/regex-2025.9.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4f6e935e98ea48c7a2e8be44494de337b57a204470e7f9c9c42f912c414cd6f5", size = 863363, upload-time = "2025-09-01T22:09:26.705Z" }, + { url = "https://files.pythonhosted.org/packages/54/a9/2321eb3e2838f575a78d48e03c1e83ea61bd08b74b7ebbdeca8abc50fc25/regex-2025.9.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4a62d033cd9ebefc7c5e466731a508dfabee827d80b13f455de68a50d3c2543d", size = 910202, upload-time = "2025-09-01T22:09:28.906Z" }, + { url = "https://files.pythonhosted.org/packages/33/07/d1d70835d7d11b7e126181f316f7213c4572ecf5c5c97bdbb969fb1f38a2/regex-2025.9.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef971ebf2b93bdc88d8337238be4dfb851cc97ed6808eb04870ef67589415171", size = 801808, upload-time = "2025-09-01T22:09:30.733Z" }, + { url = "https://files.pythonhosted.org/packages/13/d1/29e4d1bed514ef2bf3a4ead3cb8bb88ca8af94130239a4e68aa765c35b1c/regex-2025.9.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d936a1db208bdca0eca1f2bb2c1ba1d8370b226785c1e6db76e32a228ffd0ad5", size = 786824, upload-time = "2025-09-01T22:09:32.61Z" }, + { url = "https://files.pythonhosted.org/packages/33/27/20d8ccb1bee460faaa851e6e7cc4cfe852a42b70caa1dca22721ba19f02f/regex-2025.9.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:7e786d9e4469698fc63815b8de08a89165a0aa851720eb99f5e0ea9d51dd2b6a", size = 857406, upload-time = "2025-09-01T22:09:34.117Z" }, + { url = "https://files.pythonhosted.org/packages/74/fe/60c6132262dc36430d51e0c46c49927d113d3a38c1aba6a26c7744c84cf3/regex-2025.9.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6b81d7dbc5466ad2c57ce3a0ddb717858fe1a29535c8866f8514d785fdb9fc5b", size = 848593, upload-time = "2025-09-01T22:09:35.598Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ae/2d4ff915622fabbef1af28387bf71e7f2f4944a348b8460d061e85e29bf0/regex-2025.9.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cd4890e184a6feb0ef195338a6ce68906a8903a0f2eb7e0ab727dbc0a3156273", size = 787951, upload-time = "2025-09-01T22:09:37.139Z" }, + { url = "https://files.pythonhosted.org/packages/85/37/dc127703a9e715a284cc2f7dbdd8a9776fd813c85c126eddbcbdd1ca5fec/regex-2025.9.1-cp314-cp314-win32.whl", hash = "sha256:34679a86230e46164c9e0396b56cab13c0505972343880b9e705083cc5b8ec86", size = 269833, upload-time = "2025-09-01T22:09:39.245Z" }, + { url = "https://files.pythonhosted.org/packages/83/bf/4bed4d3d0570e16771defd5f8f15f7ea2311edcbe91077436d6908956c4a/regex-2025.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:a1196e530a6bfa5f4bde029ac5b0295a6ecfaaffbfffede4bbaf4061d9455b70", size = 278742, upload-time = "2025-09-01T22:09:40.651Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3e/7d7ac6fd085023312421e0d69dfabdfb28e116e513fadbe9afe710c01893/regex-2025.9.1-cp314-cp314-win_arm64.whl", hash = "sha256:f46d525934871ea772930e997d577d48c6983e50f206ff7b66d4ac5f8941e993", size = 271860, upload-time = "2025-09-01T22:09:42.413Z" }, ] [[package]] @@ -3400,28 +3400,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.12.11" +version = "0.12.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/55/16ab6a7d88d93001e1ae4c34cbdcfb376652d761799459ff27c1dc20f6fa/ruff-0.12.11.tar.gz", hash = "sha256:c6b09ae8426a65bbee5425b9d0b82796dbb07cb1af045743c79bfb163001165d", size = 5347103, upload-time = "2025-08-28T13:59:08.87Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/f0/e0965dd709b8cabe6356811c0ee8c096806bb57d20b5019eb4e48a117410/ruff-0.12.12.tar.gz", hash = "sha256:b86cd3415dbe31b3b46a71c598f4c4b2f550346d1ccf6326b347cc0c8fd063d6", size = 5359915, upload-time = "2025-09-04T16:50:18.273Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/a2/3b3573e474de39a7a475f3fbaf36a25600bfeb238e1a90392799163b64a0/ruff-0.12.11-py3-none-linux_armv6l.whl", hash = "sha256:93fce71e1cac3a8bf9200e63a38ac5c078f3b6baebffb74ba5274fb2ab276065", size = 11979885, upload-time = "2025-08-28T13:58:26.654Z" }, - { url = "https://files.pythonhosted.org/packages/76/e4/235ad6d1785a2012d3ded2350fd9bc5c5af8c6f56820e696b0118dfe7d24/ruff-0.12.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8e33ac7b28c772440afa80cebb972ffd823621ded90404f29e5ab6d1e2d4b93", size = 12742364, upload-time = "2025-08-28T13:58:30.256Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0d/15b72c5fe6b1e402a543aa9d8960e0a7e19dfb079f5b0b424db48b7febab/ruff-0.12.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d69fb9d4937aa19adb2e9f058bc4fbfe986c2040acb1a4a9747734834eaa0bfd", size = 11920111, upload-time = "2025-08-28T13:58:33.677Z" }, - { url = "https://files.pythonhosted.org/packages/3e/c0/f66339d7893798ad3e17fa5a1e587d6fd9806f7c1c062b63f8b09dda6702/ruff-0.12.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411954eca8464595077a93e580e2918d0a01a19317af0a72132283e28ae21bee", size = 12160060, upload-time = "2025-08-28T13:58:35.74Z" }, - { url = "https://files.pythonhosted.org/packages/03/69/9870368326db26f20c946205fb2d0008988aea552dbaec35fbacbb46efaa/ruff-0.12.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a2c0a2e1a450f387bf2c6237c727dd22191ae8c00e448e0672d624b2bbd7fb0", size = 11799848, upload-time = "2025-08-28T13:58:38.051Z" }, - { url = "https://files.pythonhosted.org/packages/25/8c/dd2c7f990e9b3a8a55eee09d4e675027d31727ce33cdb29eab32d025bdc9/ruff-0.12.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ca4c3a7f937725fd2413c0e884b5248a19369ab9bdd850b5781348ba283f644", size = 13536288, upload-time = "2025-08-28T13:58:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/7a/30/d5496fa09aba59b5e01ea76775a4c8897b13055884f56f1c35a4194c2297/ruff-0.12.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4d1df0098124006f6a66ecf3581a7f7e754c4df7644b2e6704cd7ca80ff95211", size = 14490633, upload-time = "2025-08-28T13:58:42.285Z" }, - { url = "https://files.pythonhosted.org/packages/9b/2f/81f998180ad53445d403c386549d6946d0748e536d58fce5b5e173511183/ruff-0.12.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a8dd5f230efc99a24ace3b77e3555d3fbc0343aeed3fc84c8d89e75ab2ff793", size = 13888430, upload-time = "2025-08-28T13:58:44.641Z" }, - { url = "https://files.pythonhosted.org/packages/87/71/23a0d1d5892a377478c61dbbcffe82a3476b050f38b5162171942a029ef3/ruff-0.12.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc75533039d0ed04cd33fb8ca9ac9620b99672fe7ff1533b6402206901c34ee", size = 12913133, upload-time = "2025-08-28T13:58:47.039Z" }, - { url = "https://files.pythonhosted.org/packages/80/22/3c6cef96627f89b344c933781ed38329bfb87737aa438f15da95907cbfd5/ruff-0.12.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc58f9266d62c6eccc75261a665f26b4ef64840887fc6cbc552ce5b29f96cc8", size = 13169082, upload-time = "2025-08-28T13:58:49.157Z" }, - { url = "https://files.pythonhosted.org/packages/05/b5/68b3ff96160d8b49e8dd10785ff3186be18fd650d356036a3770386e6c7f/ruff-0.12.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a0113bd6eafd545146440225fe60b4e9489f59eb5f5f107acd715ba5f0b3d2f", size = 13139490, upload-time = "2025-08-28T13:58:51.593Z" }, - { url = "https://files.pythonhosted.org/packages/59/b9/050a3278ecd558f74f7ee016fbdf10591d50119df8d5f5da45a22c6afafc/ruff-0.12.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0d737b4059d66295c3ea5720e6efc152623bb83fde5444209b69cd33a53e2000", size = 11958928, upload-time = "2025-08-28T13:58:53.943Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bc/93be37347db854806904a43b0493af8d6873472dfb4b4b8cbb27786eb651/ruff-0.12.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:916fc5defee32dbc1fc1650b576a8fed68f5e8256e2180d4d9855aea43d6aab2", size = 11764513, upload-time = "2025-08-28T13:58:55.976Z" }, - { url = "https://files.pythonhosted.org/packages/7a/a1/1471751e2015a81fd8e166cd311456c11df74c7e8769d4aabfbc7584c7ac/ruff-0.12.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c984f07d7adb42d3ded5be894fb4007f30f82c87559438b4879fe7aa08c62b39", size = 12745154, upload-time = "2025-08-28T13:58:58.16Z" }, - { url = "https://files.pythonhosted.org/packages/68/ab/2542b14890d0f4872dd81b7b2a6aed3ac1786fae1ce9b17e11e6df9e31e3/ruff-0.12.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e07fbb89f2e9249f219d88331c833860489b49cdf4b032b8e4432e9b13e8a4b9", size = 13227653, upload-time = "2025-08-28T13:59:00.276Z" }, - { url = "https://files.pythonhosted.org/packages/22/16/2fbfc61047dbfd009c58a28369a693a1484ad15441723be1cd7fe69bb679/ruff-0.12.11-py3-none-win32.whl", hash = "sha256:c792e8f597c9c756e9bcd4d87cf407a00b60af77078c96f7b6366ea2ce9ba9d3", size = 11944270, upload-time = "2025-08-28T13:59:02.347Z" }, - { url = "https://files.pythonhosted.org/packages/08/a5/34276984705bfe069cd383101c45077ee029c3fe3b28225bf67aa35f0647/ruff-0.12.11-py3-none-win_amd64.whl", hash = "sha256:a3283325960307915b6deb3576b96919ee89432ebd9c48771ca12ee8afe4a0fd", size = 13046600, upload-time = "2025-08-28T13:59:04.751Z" }, - { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290, upload-time = "2025-08-28T13:59:06.933Z" }, + { url = "https://files.pythonhosted.org/packages/09/79/8d3d687224d88367b51c7974cec1040c4b015772bfbeffac95face14c04a/ruff-0.12.12-py3-none-linux_armv6l.whl", hash = "sha256:de1c4b916d98ab289818e55ce481e2cacfaad7710b01d1f990c497edf217dafc", size = 12116602, upload-time = "2025-09-04T16:49:18.892Z" }, + { url = "https://files.pythonhosted.org/packages/c3/c3/6e599657fe192462f94861a09aae935b869aea8a1da07f47d6eae471397c/ruff-0.12.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7acd6045e87fac75a0b0cdedacf9ab3e1ad9d929d149785903cff9bb69ad9727", size = 12868393, upload-time = "2025-09-04T16:49:23.043Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/9e3e40d399abc95336b1843f52fc0daaceb672d0e3c9290a28ff1a96f79d/ruff-0.12.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:abf4073688d7d6da16611f2f126be86523a8ec4343d15d276c614bda8ec44edb", size = 12036967, upload-time = "2025-09-04T16:49:26.04Z" }, + { url = "https://files.pythonhosted.org/packages/e9/03/6816b2ed08836be272e87107d905f0908be5b4a40c14bfc91043e76631b8/ruff-0.12.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:968e77094b1d7a576992ac078557d1439df678a34c6fe02fd979f973af167577", size = 12276038, upload-time = "2025-09-04T16:49:29.056Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d5/707b92a61310edf358a389477eabd8af68f375c0ef858194be97ca5b6069/ruff-0.12.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42a67d16e5b1ffc6d21c5f67851e0e769517fb57a8ebad1d0781b30888aa704e", size = 11901110, upload-time = "2025-09-04T16:49:32.07Z" }, + { url = "https://files.pythonhosted.org/packages/9d/3d/f8b1038f4b9822e26ec3d5b49cf2bc313e3c1564cceb4c1a42820bf74853/ruff-0.12.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b216ec0a0674e4b1214dcc998a5088e54eaf39417327b19ffefba1c4a1e4971e", size = 13668352, upload-time = "2025-09-04T16:49:35.148Z" }, + { url = "https://files.pythonhosted.org/packages/98/0e/91421368ae6c4f3765dd41a150f760c5f725516028a6be30e58255e3c668/ruff-0.12.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:59f909c0fdd8f1dcdbfed0b9569b8bf428cf144bec87d9de298dcd4723f5bee8", size = 14638365, upload-time = "2025-09-04T16:49:38.892Z" }, + { url = "https://files.pythonhosted.org/packages/74/5d/88f3f06a142f58ecc8ecb0c2fe0b82343e2a2b04dcd098809f717cf74b6c/ruff-0.12.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ac93d87047e765336f0c18eacad51dad0c1c33c9df7484c40f98e1d773876f5", size = 14060812, upload-time = "2025-09-04T16:49:42.732Z" }, + { url = "https://files.pythonhosted.org/packages/13/fc/8962e7ddd2e81863d5c92400820f650b86f97ff919c59836fbc4c1a6d84c/ruff-0.12.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01543c137fd3650d322922e8b14cc133b8ea734617c4891c5a9fccf4bfc9aa92", size = 13050208, upload-time = "2025-09-04T16:49:46.434Z" }, + { url = "https://files.pythonhosted.org/packages/53/06/8deb52d48a9a624fd37390555d9589e719eac568c020b27e96eed671f25f/ruff-0.12.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afc2fa864197634e549d87fb1e7b6feb01df0a80fd510d6489e1ce8c0b1cc45", size = 13311444, upload-time = "2025-09-04T16:49:49.931Z" }, + { url = "https://files.pythonhosted.org/packages/2a/81/de5a29af7eb8f341f8140867ffb93f82e4fde7256dadee79016ac87c2716/ruff-0.12.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0c0945246f5ad776cb8925e36af2438e66188d2b57d9cf2eed2c382c58b371e5", size = 13279474, upload-time = "2025-09-04T16:49:53.465Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/d9577fdeaf791737ada1b4f5c6b59c21c3326f3f683229096cccd7674e0c/ruff-0.12.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a0fbafe8c58e37aae28b84a80ba1817f2ea552e9450156018a478bf1fa80f4e4", size = 12070204, upload-time = "2025-09-04T16:49:56.882Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/a910078284b47fad54506dc0af13839c418ff704e341c176f64e1127e461/ruff-0.12.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b9c456fb2fc8e1282affa932c9e40f5ec31ec9cbb66751a316bd131273b57c23", size = 11880347, upload-time = "2025-09-04T16:49:59.729Z" }, + { url = "https://files.pythonhosted.org/packages/df/58/30185fcb0e89f05e7ea82e5817b47798f7fa7179863f9d9ba6fd4fe1b098/ruff-0.12.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f12856123b0ad0147d90b3961f5c90e7427f9acd4b40050705499c98983f489", size = 12891844, upload-time = "2025-09-04T16:50:02.591Z" }, + { url = "https://files.pythonhosted.org/packages/21/9c/28a8dacce4855e6703dcb8cdf6c1705d0b23dd01d60150786cd55aa93b16/ruff-0.12.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:26a1b5a2bf7dd2c47e3b46d077cd9c0fc3b93e6c6cc9ed750bd312ae9dc302ee", size = 13360687, upload-time = "2025-09-04T16:50:05.8Z" }, + { url = "https://files.pythonhosted.org/packages/c8/fa/05b6428a008e60f79546c943e54068316f32ec8ab5c4f73e4563934fbdc7/ruff-0.12.12-py3-none-win32.whl", hash = "sha256:173be2bfc142af07a01e3a759aba6f7791aa47acf3604f610b1c36db888df7b1", size = 12052870, upload-time = "2025-09-04T16:50:09.121Z" }, + { url = "https://files.pythonhosted.org/packages/85/60/d1e335417804df452589271818749d061b22772b87efda88354cf35cdb7a/ruff-0.12.12-py3-none-win_amd64.whl", hash = "sha256:e99620bf01884e5f38611934c09dd194eb665b0109104acae3ba6102b600fd0d", size = 13178016, upload-time = "2025-09-04T16:50:12.559Z" }, + { url = "https://files.pythonhosted.org/packages/28/7e/61c42657f6e4614a4258f1c3b0c5b93adc4d1f8575f5229d1906b483099b/ruff-0.12.12-py3-none-win_arm64.whl", hash = "sha256:2a8199cab4ce4d72d158319b63370abf60991495fb733db96cd923a34c52d093", size = 12256762, upload-time = "2025-09-04T16:50:15.737Z" }, ] [[package]] @@ -3565,27 +3565,27 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.21.4" +version = "0.22.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/2f/402986d0823f8d7ca139d969af2917fefaa9b947d1fb32f6168c509f2492/tokenizers-0.21.4.tar.gz", hash = "sha256:fa23f85fbc9a02ec5c6978da172cdcbac23498c3ca9f3645c5c68740ac007880", size = 351253, upload-time = "2025-07-28T15:48:54.325Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/b4/c1ce3699e81977da2ace8b16d2badfd42b060e7d33d75c4ccdbf9dc920fa/tokenizers-0.22.0.tar.gz", hash = "sha256:2e33b98525be8453f355927f3cab312c36cd3e44f4d7e9e97da2fa94d0a49dcb", size = 362771, upload-time = "2025-08-29T10:25:33.914Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/98/c6/fdb6f72bf6454f52eb4a2510be7fb0f614e541a2554d6210e370d85efff4/tokenizers-0.21.4-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2ccc10a7c3bcefe0f242867dc914fc1226ee44321eb618cfe3019b5df3400133", size = 2863987, upload-time = "2025-07-28T15:48:44.877Z" }, - { url = "https://files.pythonhosted.org/packages/8d/a6/28975479e35ddc751dc1ddc97b9b69bf7fcf074db31548aab37f8116674c/tokenizers-0.21.4-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:5e2f601a8e0cd5be5cc7506b20a79112370b9b3e9cb5f13f68ab11acd6ca7d60", size = 2732457, upload-time = "2025-07-28T15:48:43.265Z" }, - { url = "https://files.pythonhosted.org/packages/aa/8f/24f39d7b5c726b7b0be95dca04f344df278a3fe3a4deb15a975d194cbb32/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b376f5a1aee67b4d29032ee85511bbd1b99007ec735f7f35c8a2eb104eade5", size = 3012624, upload-time = "2025-07-28T13:22:43.895Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/26358925717687a58cb74d7a508de96649544fad5778f0cd9827398dc499/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2107ad649e2cda4488d41dfd031469e9da3fcbfd6183e74e4958fa729ffbf9c6", size = 2939681, upload-time = "2025-07-28T13:22:47.499Z" }, - { url = "https://files.pythonhosted.org/packages/99/6f/cc300fea5db2ab5ddc2c8aea5757a27b89c84469899710c3aeddc1d39801/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c73012da95afafdf235ba80047699df4384fdc481527448a078ffd00e45a7d9", size = 3247445, upload-time = "2025-07-28T15:48:39.711Z" }, - { url = "https://files.pythonhosted.org/packages/be/bf/98cb4b9c3c4afd8be89cfa6423704337dc20b73eb4180397a6e0d456c334/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f23186c40395fc390d27f519679a58023f368a0aad234af145e0f39ad1212732", size = 3428014, upload-time = "2025-07-28T13:22:49.569Z" }, - { url = "https://files.pythonhosted.org/packages/75/c7/96c1cc780e6ca7f01a57c13235dd05b7bc1c0f3588512ebe9d1331b5f5ae/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc88bb34e23a54cc42713d6d98af5f1bf79c07653d24fe984d2d695ba2c922a2", size = 3193197, upload-time = "2025-07-28T13:22:51.471Z" }, - { url = "https://files.pythonhosted.org/packages/f2/90/273b6c7ec78af547694eddeea9e05de771278bd20476525ab930cecaf7d8/tokenizers-0.21.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51b7eabb104f46c1c50b486520555715457ae833d5aee9ff6ae853d1130506ff", size = 3115426, upload-time = "2025-07-28T15:48:41.439Z" }, - { url = "https://files.pythonhosted.org/packages/91/43/c640d5a07e95f1cf9d2c92501f20a25f179ac53a4f71e1489a3dcfcc67ee/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:714b05b2e1af1288bd1bc56ce496c4cebb64a20d158ee802887757791191e6e2", size = 9089127, upload-time = "2025-07-28T15:48:46.472Z" }, - { url = "https://files.pythonhosted.org/packages/44/a1/dd23edd6271d4dca788e5200a807b49ec3e6987815cd9d0a07ad9c96c7c2/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1340ff877ceedfa937544b7d79f5b7becf33a4cfb58f89b3b49927004ef66f78", size = 9055243, upload-time = "2025-07-28T15:48:48.539Z" }, - { url = "https://files.pythonhosted.org/packages/21/2b/b410d6e9021c4b7ddb57248304dc817c4d4970b73b6ee343674914701197/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3c1f4317576e465ac9ef0d165b247825a2a4078bcd01cba6b54b867bdf9fdd8b", size = 9298237, upload-time = "2025-07-28T15:48:50.443Z" }, - { url = "https://files.pythonhosted.org/packages/b7/0a/42348c995c67e2e6e5c89ffb9cfd68507cbaeb84ff39c49ee6e0a6dd0fd2/tokenizers-0.21.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c212aa4e45ec0bb5274b16b6f31dd3f1c41944025c2358faaa5782c754e84c24", size = 9461980, upload-time = "2025-07-28T15:48:52.325Z" }, - { url = "https://files.pythonhosted.org/packages/3d/d3/dacccd834404cd71b5c334882f3ba40331ad2120e69ded32cf5fda9a7436/tokenizers-0.21.4-cp39-abi3-win32.whl", hash = "sha256:6c42a930bc5f4c47f4ea775c91de47d27910881902b0f20e4990ebe045a415d0", size = 2329871, upload-time = "2025-07-28T15:48:56.841Z" }, - { url = "https://files.pythonhosted.org/packages/41/f2/fd673d979185f5dcbac4be7d09461cbb99751554ffb6718d0013af8604cb/tokenizers-0.21.4-cp39-abi3-win_amd64.whl", hash = "sha256:475d807a5c3eb72c59ad9b5fcdb254f6e17f53dfcbb9903233b0dfa9c943b597", size = 2507568, upload-time = "2025-07-28T15:48:55.456Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b1/18c13648edabbe66baa85fe266a478a7931ddc0cd1ba618802eb7b8d9865/tokenizers-0.22.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:eaa9620122a3fb99b943f864af95ed14c8dfc0f47afa3b404ac8c16b3f2bb484", size = 3081954, upload-time = "2025-08-29T10:25:24.993Z" }, + { url = "https://files.pythonhosted.org/packages/c2/02/c3c454b641bd7c4f79e4464accfae9e7dfc913a777d2e561e168ae060362/tokenizers-0.22.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:71784b9ab5bf0ff3075bceeb198149d2c5e068549c0d18fe32d06ba0deb63f79", size = 2945644, upload-time = "2025-08-29T10:25:23.405Z" }, + { url = "https://files.pythonhosted.org/packages/55/02/d10185ba2fd8c2d111e124c9d92de398aee0264b35ce433f79fb8472f5d0/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec5b71f668a8076802b0241a42387d48289f25435b86b769ae1837cad4172a17", size = 3254764, upload-time = "2025-08-29T10:25:12.445Z" }, + { url = "https://files.pythonhosted.org/packages/13/89/17514bd7ef4bf5bfff58e2b131cec0f8d5cea2b1c8ffe1050a2c8de88dbb/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ea8562fa7498850d02a16178105b58803ea825b50dc9094d60549a7ed63654bb", size = 3161654, upload-time = "2025-08-29T10:25:15.493Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d8/bac9f3a7ef6dcceec206e3857c3b61bb16c6b702ed7ae49585f5bd85c0ef/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4136e1558a9ef2e2f1de1555dcd573e1cbc4a320c1a06c4107a3d46dc8ac6e4b", size = 3511484, upload-time = "2025-08-29T10:25:20.477Z" }, + { url = "https://files.pythonhosted.org/packages/aa/27/9c9800eb6763683010a4851db4d1802d8cab9cec114c17056eccb4d4a6e0/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf5954de3962a5fd9781dc12048d24a1a6f1f5df038c6e95db328cd22964206", size = 3712829, upload-time = "2025-08-29T10:25:17.154Z" }, + { url = "https://files.pythonhosted.org/packages/10/e3/b1726dbc1f03f757260fa21752e1921445b5bc350389a8314dd3338836db/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8337ca75d0731fc4860e6204cc24bb36a67d9736142aa06ed320943b50b1e7ed", size = 3408934, upload-time = "2025-08-29T10:25:18.76Z" }, + { url = "https://files.pythonhosted.org/packages/d4/61/aeab3402c26874b74bb67a7f2c4b569dde29b51032c5384db592e7b216f4/tokenizers-0.22.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a89264e26f63c449d8cded9061adea7b5de53ba2346fc7e87311f7e4117c1cc8", size = 3345585, upload-time = "2025-08-29T10:25:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d3/498b4a8a8764cce0900af1add0f176ff24f475d4413d55b760b8cdf00893/tokenizers-0.22.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:790bad50a1b59d4c21592f9c3cf5e5cf9c3c7ce7e1a23a739f13e01fb1be377a", size = 9322986, upload-time = "2025-08-29T10:25:26.607Z" }, + { url = "https://files.pythonhosted.org/packages/a2/62/92378eb1c2c565837ca3cb5f9569860d132ab9d195d7950c1ea2681dffd0/tokenizers-0.22.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:76cf6757c73a10ef10bf06fa937c0ec7393d90432f543f49adc8cab3fb6f26cb", size = 9276630, upload-time = "2025-08-29T10:25:28.349Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f0/342d80457aa1cda7654327460f69db0d69405af1e4c453f4dc6ca7c4a76e/tokenizers-0.22.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:1626cb186e143720c62c6c6b5371e62bbc10af60481388c0da89bc903f37ea0c", size = 9547175, upload-time = "2025-08-29T10:25:29.989Z" }, + { url = "https://files.pythonhosted.org/packages/14/84/8aa9b4adfc4fbd09381e20a5bc6aa27040c9c09caa89988c01544e008d18/tokenizers-0.22.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:da589a61cbfea18ae267723d6b029b84598dc8ca78db9951d8f5beff72d8507c", size = 9692735, upload-time = "2025-08-29T10:25:32.089Z" }, + { url = "https://files.pythonhosted.org/packages/bf/24/83ee2b1dc76bfe05c3142e7d0ccdfe69f0ad2f1ebf6c726cea7f0874c0d0/tokenizers-0.22.0-cp39-abi3-win32.whl", hash = "sha256:dbf9d6851bddae3e046fedfb166f47743c1c7bd11c640f0691dd35ef0bcad3be", size = 2471915, upload-time = "2025-08-29T10:25:36.411Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9b/0e0bf82214ee20231845b127aa4a8015936ad5a46779f30865d10e404167/tokenizers-0.22.0-cp39-abi3-win_amd64.whl", hash = "sha256:c78174859eeaee96021f248a56c801e36bfb6bd5b067f2e95aa82445ca324f00", size = 2680494, upload-time = "2025-08-29T10:25:35.14Z" }, ] [[package]] From 5b0a55ad35dabdd2c465244193e789ea874d51ce Mon Sep 17 00:00:00 2001 From: ccurme Date: Mon, 8 Sep 2025 09:54:20 -0400 Subject: [PATCH 12/30] chore(openai): apply formatting changes to AzureChatOpenAI (#32848) --- .../langchain_openai/chat_models/azure.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/libs/partners/openai/langchain_openai/chat_models/azure.py b/libs/partners/openai/langchain_openai/chat_models/azure.py index ab67b8917d5..c812de60b65 100644 --- a/libs/partners/openai/langchain_openai/chat_models/azure.py +++ b/libs/partners/openai/langchain_openai/chat_models/azure.py @@ -479,10 +479,10 @@ class AzureChatOpenAI(BaseChatOpenAI): Example: ``https://example-resource.azure.openai.com/`` """ deployment_name: Union[str, None] = Field(default=None, alias="azure_deployment") - """A model deployment. - + """A model deployment. + If given sets the base client URL to include ``/deployments/{azure_deployment}`` - + .. note:: This means you won't be able to use non-deployment endpoints. """ @@ -512,27 +512,27 @@ class AzureChatOpenAI(BaseChatOpenAI): """ azure_ad_token_provider: Union[Callable[[], str], None] = None """A function that returns an Azure Active Directory token. - + Will be invoked on every sync request. For async requests, will be invoked if ``azure_ad_async_token_provider`` is not provided. """ azure_ad_async_token_provider: Union[Callable[[], Awaitable[str]], None] = None """A function that returns an Azure Active Directory token. - + Will be invoked on every async request. """ model_version: str = "" """The version of the model (e.g. ``'0125'`` for ``'gpt-3.5-0125'``). - Azure OpenAI doesn't return model version with the response by default so it must + Azure OpenAI doesn't return model version with the response by default so it must be manually specified if you want to use this information downstream, e.g. when calculating costs. - When you specify the version, it will be appended to the model name in the - response. Setting correct version will help you to calculate the cost properly. - Model version is not validated, so make sure you set it correctly to get the + When you specify the version, it will be appended to the model name in the + response. Setting correct version will help you to calculate the cost properly. + Model version is not validated, so make sure you set it correctly to get the correct cost. """ @@ -547,34 +547,34 @@ class AzureChatOpenAI(BaseChatOpenAI): """ model_name: Optional[str] = Field(default=None, alias="model") # type: ignore[assignment] - """Name of the deployed OpenAI model, e.g. ``'gpt-4o'``, ``'gpt-35-turbo'``, etc. - + """Name of the deployed OpenAI model, e.g. ``'gpt-4o'``, ``'gpt-35-turbo'``, etc. + Distinct from the Azure deployment name, which is set by the Azure user. Used for tracing and token counting. - + .. warning:: Does NOT affect completion. """ disabled_params: Optional[dict[str, Any]] = Field(default=None) - """Parameters of the OpenAI client or chat.completions endpoint that should be + """Parameters of the OpenAI client or chat.completions endpoint that should be disabled for the given model. - Should be specified as ``{"param": None | ['val1', 'val2']}`` where the key is the + Should be specified as ``{"param": None | ['val1', 'val2']}`` where the key is the parameter and the value is either None, meaning that parameter should never be used, or it's a list of disabled values for the parameter. For example, older models may not support the ``'parallel_tool_calls'`` parameter at - all, in which case ``disabled_params={"parallel_tool_calls: None}`` can ben passed + all, in which case ``disabled_params={"parallel_tool_calls: None}`` can ben passed in. - + If a parameter is disabled then it will not be used by default in any methods, e.g. - in + in :meth:`~langchain_openai.chat_models.azure.AzureChatOpenAI.with_structured_output`. However this does not prevent a user from directly passed in the parameter during - invocation. - - By default, unless ``model_name="gpt-4o"`` is specified, then + invocation. + + By default, unless ``model_name="gpt-4o"`` is specified, then ``'parallel_tools_calls'`` will be disabled. """ From 6ea06ca9725f8c8034f640206bd58d84982dcc40 Mon Sep 17 00:00:00 2001 From: JunHyungKang <48425469+JunHyungKang@users.noreply.github.com> Date: Mon, 8 Sep 2025 23:08:35 +0900 Subject: [PATCH 13/30] fix(openai): Fix Azure OpenAI Responses API model field issue (#32649) --- .../langchain_openai/chat_models/azure.py | 20 ++++++++++ .../langchain_openai/chat_models/base.py | 2 +- .../chat_models/test_azure_standard.py | 2 - .../unit_tests/chat_models/test_azure.py | 40 +++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/libs/partners/openai/langchain_openai/chat_models/azure.py b/libs/partners/openai/langchain_openai/chat_models/azure.py index c812de60b65..af108e10c97 100644 --- a/libs/partners/openai/langchain_openai/chat_models/azure.py +++ b/libs/partners/openai/langchain_openai/chat_models/azure.py @@ -754,6 +754,26 @@ class AzureChatOpenAI(BaseChatOpenAI): return chat_result + def _get_request_payload( + self, + input_: LanguageModelInput, + *, + stop: Optional[list[str]] = None, + **kwargs: Any, + ) -> dict: + """Get the request payload, using deployment name for Azure Responses API.""" + payload = super()._get_request_payload(input_, stop=stop, **kwargs) + + # For Azure Responses API, use deployment name instead of model name + if ( + self._use_responses_api(payload) + and not payload.get("model") + and self.deployment_name + ): + payload["model"] = self.deployment_name + + return payload + def _stream(self, *args: Any, **kwargs: Any) -> Iterator[ChatGenerationChunk]: """Route to Chat Completions or Responses API.""" if self._use_responses_api({**kwargs, **self.model_kwargs}): diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index 7965e45d922..6f7c386776e 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -3541,7 +3541,7 @@ def _construct_responses_api_payload( payload["reasoning"] = {"effort": payload.pop("reasoning_effort")} # Remove temperature parameter for models that don't support it in responses API - model = payload.get("model", "") + model = payload.get("model") or "" if model.startswith("gpt-5") and "chat" not in model: # gpt-5-chat supports payload.pop("temperature", None) diff --git a/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py b/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py index 278f8dcaaed..96cd02bc6cd 100644 --- a/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py +++ b/libs/partners/openai/tests/integration_tests/chat_models/test_azure_standard.py @@ -21,7 +21,6 @@ class TestAzureOpenAIStandard(ChatModelIntegrationTests): def chat_model_params(self) -> dict: return { "deployment_name": os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"], - "model": "gpt-4o-mini", "openai_api_version": OPENAI_API_VERSION, "azure_endpoint": OPENAI_API_BASE, "stream_usage": True, @@ -49,7 +48,6 @@ class TestAzureOpenAIResponses(ChatModelIntegrationTests): def chat_model_params(self) -> dict: return { "deployment_name": os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"], - "model": "gpt-4o-mini", "openai_api_version": OPENAI_API_VERSION, "azure_endpoint": OPENAI_API_BASE, "use_responses_api": True, diff --git a/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py b/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py index f1d97ab8ebb..1640c120544 100644 --- a/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py +++ b/libs/partners/openai/tests/unit_tests/chat_models/test_azure.py @@ -5,6 +5,7 @@ from unittest import mock import pytest from langchain_core.messages import HumanMessage +from pydantic import SecretStr from typing_extensions import TypedDict from langchain_openai import AzureChatOpenAI @@ -99,3 +100,42 @@ def test_max_completion_tokens_in_payload() -> None: "stream": False, "max_completion_tokens": 300, } + + +def test_responses_api_uses_deployment_name() -> None: + """Test that Azure deployment name is used for Responses API.""" + llm = AzureChatOpenAI( + azure_deployment="your_deployment", + api_version="2025-04-01-preview", + azure_endpoint="your_endpoint", + api_key=SecretStr("your_api_key"), + # Force Responses API usage by including a Responses-only parameter + use_responses_api=True, + output_version="responses/v1", + ) + messages = [HumanMessage("Hello")] + payload = llm._get_request_payload(messages) + + # For Responses API, the model field should be the deployment name + assert payload["model"] == "your_deployment" + assert "input" in payload # Responses API uses 'input' instead of 'messages' + + +def test_chat_completions_api_uses_model_name() -> None: + """Test that regular Chat Completions API still uses model name.""" + llm = AzureChatOpenAI( + azure_deployment="your_deployment", + model="gpt-5", # This is the OpenAI model name + api_version="2025-04-01-preview", + azure_endpoint="your_endpoint", + api_key=SecretStr("your_api_key"), + # No Responses-only parameters, so Chat Completions API will be used + ) + messages = [HumanMessage("Hello")] + payload = llm._get_request_payload(messages) + + # For Chat Completions API, the model field should still be None/model_name + # Azure Chat Completions uses deployment in the URL, not in the model field + assert payload["model"] == "gpt-5" + assert "messages" in payload # Chat Completions API uses 'messages' + assert "input" not in payload From 228fbac3a6bf12340fc2fc8647d12b6890030293 Mon Sep 17 00:00:00 2001 From: Sadiq Khan Date: Mon, 8 Sep 2025 19:42:50 +0530 Subject: [PATCH 14/30] fix(openai): handle `AIMessage`s without `response_id` in `_get_last_messages` (#32824) --- .../langchain_openai/chat_models/base.py | 3 +- .../tests/unit_tests/chat_models/test_base.py | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index 6f7c386776e..38a4568d90e 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -3524,8 +3524,7 @@ def _get_last_messages( response_id = msg.response_metadata.get("id") if response_id: return messages[i + 1 :], response_id - else: - return messages, None + # Continue searching for an AIMessage with a valid response_id return messages, None diff --git a/libs/partners/openai/tests/unit_tests/chat_models/test_base.py b/libs/partners/openai/tests/unit_tests/chat_models/test_base.py index 2c33fe062bf..cf24d857de4 100644 --- a/libs/partners/openai/tests/unit_tests/chat_models/test_base.py +++ b/libs/partners/openai/tests/unit_tests/chat_models/test_base.py @@ -2512,6 +2512,42 @@ def test_get_last_messages() -> None: assert response_id == "resp_123" +def test_get_last_messages_with_mixed_response_metadata() -> None: + """Test that _get_last_messages correctly skips AIMessages without response_id.""" + # Test case where the most recent AIMessage has no response_id, + # but an earlier AIMessage does have one + messages = [ + HumanMessage("Hello"), + AIMessage("Hi there!", response_metadata={"id": "resp_123"}), + HumanMessage("How are you?"), + AIMessage("I'm good"), # No response_metadata + HumanMessage("What's up?"), + ] + last_messages, previous_response_id = _get_last_messages(messages) + # Should return messages after the AIMessage + # with response_id (not the most recent one) + + assert last_messages == [ + HumanMessage("How are you?"), + AIMessage("I'm good"), + HumanMessage("What's up?"), + ] + assert previous_response_id == "resp_123" + + # Test case where no AIMessage has response_id + messages = [ + HumanMessage("Hello"), + AIMessage("Hi there!"), # No response_metadata + HumanMessage("How are you?"), + AIMessage("I'm good"), # No response_metadata + HumanMessage("What's up?"), + ] + last_messages, previous_response_id = _get_last_messages(messages) + # Should return all messages when no AIMessage has response_id + assert last_messages == messages + assert previous_response_id is None + + def test_get_request_payload_use_previous_response_id() -> None: # Default - don't use previous_response ID llm = ChatOpenAI( From d8d93882f9f8023fc4426e4749e4d2531169bd83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:14:09 -0400 Subject: [PATCH 15/30] chore(infra): bump `actions/checkout` from 4 to 5 (#32584) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
Release notes

Sourced from actions/checkout's releases.

v5.0.0

What's Changed

⚠️ Minimum Compatible Runner Version

v2.327.1
Release Notes

Make sure your runner is updated to this version or newer to use this release.

Full Changelog: https://github.com/actions/checkout/compare/v4...v5.0.0

v4.3.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4...v4.3.0

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

... (truncated)

Changelog

Sourced from actions/checkout's changelog.

Changelog

V5.0.0

V4.3.0

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/_compile_integration_test.yml | 2 +- .github/workflows/_integration_test.yml | 2 +- .github/workflows/_lint.yml | 2 +- .github/workflows/_release.yml | 12 ++++++------ .github/workflows/_test.yml | 2 +- .github/workflows/_test_doc_imports.yml | 2 +- .github/workflows/_test_pydantic.yml | 2 +- .github/workflows/_test_release.yml | 4 ++-- .github/workflows/api_doc_build.yml | 4 ++-- .github/workflows/check-broken-links.yml | 2 +- .github/workflows/check_core_versions.yml | 2 +- .github/workflows/check_diffs.yml | 4 ++-- .github/workflows/check_new_docs.yml | 2 +- .github/workflows/codspeed.yml | 2 +- .github/workflows/people.yml | 2 +- .github/workflows/run_notebooks.yml | 2 +- .github/workflows/scheduled_test.yml | 6 +++--- 17 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/_compile_integration_test.yml b/.github/workflows/_compile_integration_test.yml index 566a7ea000b..334da4d141f 100644 --- a/.github/workflows/_compile_integration_test.yml +++ b/.github/workflows/_compile_integration_test.yml @@ -27,7 +27,7 @@ jobs: timeout-minutes: 20 name: 'Python ${{ inputs.python-version }}' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ inputs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_integration_test.yml b/.github/workflows/_integration_test.yml index a1f7f988fa0..c5b2362a6ae 100644 --- a/.github/workflows/_integration_test.yml +++ b/.github/workflows/_integration_test.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest name: 'Python ${{ inputs.python-version }}' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ inputs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_lint.yml b/.github/workflows/_lint.yml index de83f80188b..dba94f9f44c 100644 --- a/.github/workflows/_lint.yml +++ b/.github/workflows/_lint.yml @@ -33,7 +33,7 @@ jobs: timeout-minutes: 20 steps: - name: '📋 Checkout Code' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ inputs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index 3679d207d57..e077e7b0e40 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -43,7 +43,7 @@ jobs: version: ${{ steps.check-version.outputs.version }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python + uv uses: "./.github/actions/uv_setup" @@ -92,7 +92,7 @@ jobs: outputs: release-body: ${{ steps.generate-release-body.outputs.release-body }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: repository: langchain-ai/langchain path: langchain @@ -199,7 +199,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # We explicitly *don't* set up caching here. This ensures our tests are # maximally sensitive to catching breakage. @@ -362,7 +362,7 @@ jobs: AZURE_OPENAI_LLM_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_LLM_DEPLOYMENT_NAME }} AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # We implement this conditional as Github Actions does not have good support # for conditionally needing steps. https://github.com/actions/runner/issues/491 @@ -440,7 +440,7 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python + uv uses: "./.github/actions/uv_setup" @@ -479,7 +479,7 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python + uv uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml index 2b26e6cfa51..dc48456b3ca 100644 --- a/.github/workflows/_test.yml +++ b/.github/workflows/_test.yml @@ -32,7 +32,7 @@ jobs: name: 'Python ${{ inputs.python-version }}' steps: - name: '📋 Checkout Code' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ inputs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_test_doc_imports.yml b/.github/workflows/_test_doc_imports.yml index ebc95c77a76..5207a9ca227 100644 --- a/.github/workflows/_test_doc_imports.yml +++ b/.github/workflows/_test_doc_imports.yml @@ -21,7 +21,7 @@ jobs: name: '🔍 Check Doc Imports (Python ${{ inputs.python-version }})' steps: - name: '📋 Checkout Code' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ inputs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_test_pydantic.yml b/.github/workflows/_test_pydantic.yml index 2e2b7cfe841..3a5f8d03ed7 100644 --- a/.github/workflows/_test_pydantic.yml +++ b/.github/workflows/_test_pydantic.yml @@ -34,7 +34,7 @@ jobs: name: 'Pydantic ~=${{ inputs.pydantic-version }}' steps: - name: '📋 Checkout Code' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ inputs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/_test_release.yml b/.github/workflows/_test_release.yml index 95ca2aaad8b..3c80c0e9c31 100644 --- a/.github/workflows/_test_release.yml +++ b/.github/workflows/_test_release.yml @@ -27,7 +27,7 @@ jobs: version: ${{ steps.check-version.outputs.version }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '🐍 Set up Python + UV' uses: "./.github/actions/uv_setup" @@ -83,7 +83,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/download-artifact@v5 with: diff --git a/.github/workflows/api_doc_build.yml b/.github/workflows/api_doc_build.yml index e3eab91c962..3cd664a4beb 100644 --- a/.github/workflows/api_doc_build.yml +++ b/.github/workflows/api_doc_build.yml @@ -17,10 +17,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: path: langchain - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: repository: langchain-ai/langchain-api-docs-html path: langchain-api-docs-html diff --git a/.github/workflows/check-broken-links.yml b/.github/workflows/check-broken-links.yml index 22a3a22d618..6c949b5bbf8 100644 --- a/.github/workflows/check-broken-links.yml +++ b/.github/workflows/check-broken-links.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'langchain-ai' || github.event_name != 'schedule' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '🟢 Setup Node.js 18.x' uses: actions/setup-node@v4 with: diff --git a/.github/workflows/check_core_versions.yml b/.github/workflows/check_core_versions.yml index 477a4259b3a..7905bf06ce3 100644 --- a/.github/workflows/check_core_versions.yml +++ b/.github/workflows/check_core_versions.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '✅ Verify pyproject.toml & version.py Match' run: | diff --git a/.github/workflows/check_diffs.yml b/.github/workflows/check_diffs.yml index 0c81880442d..ced20078937 100644 --- a/.github/workflows/check_diffs.yml +++ b/.github/workflows/check_diffs.yml @@ -33,7 +33,7 @@ jobs: if: ${{ !contains(github.event.pull_request.labels.*.name, 'ci-ignore') }} steps: - name: '📋 Checkout Code' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: '🐍 Setup Python 3.11' uses: actions/setup-python@v5 with: @@ -138,7 +138,7 @@ jobs: run: working-directory: ${{ matrix.job-configs.working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '🐍 Set up Python ${{ matrix.job-configs.python-version }} + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/check_new_docs.yml b/.github/workflows/check_new_docs.yml index eab0156d1e8..1df3ac9f504 100644 --- a/.github/workflows/check_new_docs.yml +++ b/.github/workflows/check_new_docs.yml @@ -22,7 +22,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-python@v5 with: python-version: '3.10' diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 6d6025082df..089f019074d 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -36,7 +36,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # We have to use 3.12 as 3.13 is not yet supported - name: '📦 Install UV Package Manager' diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml index d47b4e73529..3347d61ff5e 100644 --- a/.github/workflows/people.yml +++ b/.github/workflows/people.yml @@ -19,7 +19,7 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # Ref: https://github.com/actions/runner/issues/2033 - name: '🔧 Fix Git Safe Directory in Container' run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig diff --git a/.github/workflows/run_notebooks.yml b/.github/workflows/run_notebooks.yml index 8f5c194762a..e6d5def0c2c 100644 --- a/.github/workflows/run_notebooks.yml +++ b/.github/workflows/run_notebooks.yml @@ -26,7 +26,7 @@ jobs: if: github.repository == 'langchain-ai/langchain' || github.event_name != 'schedule' name: '📑 Test Documentation Notebooks' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: '🐍 Set up Python + UV' uses: "./.github/actions/uv_setup" diff --git a/.github/workflows/scheduled_test.yml b/.github/workflows/scheduled_test.yml index 62ed8699ddd..3501ba66523 100644 --- a/.github/workflows/scheduled_test.yml +++ b/.github/workflows/scheduled_test.yml @@ -68,14 +68,14 @@ jobs: working-directory: ${{ fromJSON(needs.compute-matrix.outputs.matrix).working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: path: langchain - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: repository: langchain-ai/langchain-google path: langchain-google - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: repository: langchain-ai/langchain-aws path: langchain-aws From f8bcc98362883b2147037eeb1d695190aa7e1515 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:16:19 -0400 Subject: [PATCH 16/30] chore(infra): bump `amannn/action-semantic-pull-request` from 5 to 6 (#32585) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 5 to 6.
Release notes

Sourced from amannn/action-semantic-pull-request's releases.

v6.0.0

6.0.0 (2025-08-13)

⚠ BREAKING CHANGES

  • Upgrade action to use Node.js 24 and ESM (#287)

Features

  • Upgrade action to use Node.js 24 and ESM (#287) (bc0c9a7)

v5.5.3

5.5.3 (2024-06-28)

Bug Fixes

v5.5.2

5.5.2 (2024-04-24)

Bug Fixes

v5.5.1

5.5.1 (2024-04-24)

Bug Fixes

v5.5.0

5.5.0 (2024-04-23)

Features

v5.4.0

5.4.0 (2023-11-03)

... (truncated)

Changelog

Sourced from amannn/action-semantic-pull-request's changelog.

5.3.0 (2023-09-25)

Features

5.2.0 (2023-03-16)

Features

5.1.0 (2023-02-10)

Features

  • Add regex support to scope and disallowScopes configuration (#226) (403a6f8)

5.0.2 (2022-10-17)

Bug Fixes

  • Upgrade @actions/core to avoid deprecation warnings (#208) (91f4126)

5.0.1 (2022-10-14)

Bug Fixes

  • Upgrade GitHub Action to use Node v16 (#207) (6282ee3)

5.0.0 (2022-10-11)

⚠ BREAKING CHANGES

  • Enum options need to be newline delimited (to allow whitespace within them) (#205)

Features

  • Enum options need to be newline delimited (to allow whitespace within them) (#205) (c906fe1)

4.6.0 (2022-09-26)

Features

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=amannn/action-semantic-pull-request&package-manager=github_actions&previous-version=5&new-version=6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pr_lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_lint.yml b/.github/workflows/pr_lint.yml index 33b98b09194..8c4bf36d2c1 100644 --- a/.github/workflows/pr_lint.yml +++ b/.github/workflows/pr_lint.yml @@ -62,7 +62,7 @@ jobs: runs-on: ubuntu-latest steps: - name: '✅ Validate Conventional Commits Format' - uses: amannn/action-semantic-pull-request@v5 + uses: amannn/action-semantic-pull-request@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 9368ce6b07a1415f1e27be3321096b45059a47ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:16:59 -0400 Subject: [PATCH 17/30] chore(infra): bump `google-github-actions/auth` from 2 to 3 (#32777) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2 to 3.
Release notes

Sourced from google-github-actions/auth's releases.

v3.0.0

What's Changed

Full Changelog: https://github.com/google-github-actions/auth/compare/v2...v3.0.0

v2.1.13

What's Changed

Full Changelog: https://github.com/google-github-actions/auth/compare/v2.1.12...v2.1.13

v2.1.12

What's Changed

Full Changelog: https://github.com/google-github-actions/auth/compare/v2.1.11...v2.1.12

v2.1.11

What's Changed

Full Changelog: https://github.com/google-github-actions/auth/compare/v2.1.10...v2.1.11

v2.1.10

What's Changed

Full Changelog: https://github.com/google-github-actions/auth/compare/v2.1.9...v2.1.10

v2.1.9

What's Changed

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google-github-actions/auth&package-manager=github_actions&previous-version=2&new-version=3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/run_notebooks.yml | 2 +- .github/workflows/scheduled_test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_notebooks.yml b/.github/workflows/run_notebooks.yml index e6d5def0c2c..df9b645cd01 100644 --- a/.github/workflows/run_notebooks.yml +++ b/.github/workflows/run_notebooks.yml @@ -35,7 +35,7 @@ jobs: - name: '🔐 Authenticate to Google Cloud' id: 'auth' - uses: google-github-actions/auth@v2 + uses: google-github-actions/auth@v3 with: credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' diff --git a/.github/workflows/scheduled_test.yml b/.github/workflows/scheduled_test.yml index 3501ba66523..d297c099381 100644 --- a/.github/workflows/scheduled_test.yml +++ b/.github/workflows/scheduled_test.yml @@ -106,7 +106,7 @@ jobs: - name: '🔐 Authenticate to Google Cloud' id: 'auth' - uses: google-github-actions/auth@v2 + uses: google-github-actions/auth@v3 with: credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' From e0aaaccb616f02a6022feb1a9c4bc50fd27a9d9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:18:01 -0400 Subject: [PATCH 18/30] chore(infra): bump `aws-actions/configure-aws-credentials` from 4 to 5 (#32841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 4 to 5.
Release notes

Sourced from aws-actions/configure-aws-credentials's releases.

v5.0.0

5.0.0 (2025-09-03)

⚠ BREAKING CHANGES

  • Cleanup input handling. Changes invalid boolean input behavior (see #1445)

Features

v4.3.1

4.3.1 (2025-08-04)

Bug Fixes

v4.3.0

4.3.0 (2025-08-04)

NOTE: This release tag originally pointed to 59b441846ad109fa4a1549b73ef4e149c4bfb53b, but a critical bug was discovered shortly after publishing. We updated this tag to d0834ad3a60a024346910e522a81b0002bd37fea to prevent anyone using the 4.3.0 tag from encountering the bug, and we published 4.3.1 to allow workflows to auto update correctly.

Features

Bug Fixes

  • docs: readme samples versioning (5b3c895)
  • the wrong example region for China partition in README (37fe9a7)
  • properly set proxy environment variable (cbea708)

Miscellaneous Chores

v4.2.1

4.2.1 (2025-05-14)

Bug Fixes

... (truncated)

Changelog

Sourced from aws-actions/configure-aws-credentials's changelog.

4.3.1 (2025-08-04)

Bug Fixes

4.3.0 (2025-08-04)

Features

Bug Fixes

  • docs: readme samples versioning (5b3c895)
  • the wrong example region for China partition in README (37fe9a7)
  • properly set proxy environment variable (cbea708)

Miscellaneous Chores

4.2.1 (2025-05-14)

Bug Fixes

  • ensure explicit inputs take precedence over environment variables (e56e6c4)
  • prioritize explicit inputs over environment variables (df9c8fe)

4.2.0 (2025-05-06)

Features

  • add Expiration field to Outputs (a4f3267)
  • Document role-duration-seconds range (5a0cf01)
  • support action inputs as environment variables (#1338) (2c168ad)

Bug Fixes

  • make sure action builds, also fix dependabot autoapprove (c401b8a)
  • role chaning on mulitple runs (#1340) (9e38641)

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aws-actions/configure-aws-credentials&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/run_notebooks.yml | 2 +- .github/workflows/scheduled_test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_notebooks.yml b/.github/workflows/run_notebooks.yml index df9b645cd01..ba7278cd042 100644 --- a/.github/workflows/run_notebooks.yml +++ b/.github/workflows/run_notebooks.yml @@ -40,7 +40,7 @@ jobs: credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' - name: '🔐 Configure AWS Credentials' - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@v5 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/scheduled_test.yml b/.github/workflows/scheduled_test.yml index d297c099381..0ac9e328233 100644 --- a/.github/workflows/scheduled_test.yml +++ b/.github/workflows/scheduled_test.yml @@ -111,7 +111,7 @@ jobs: credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' - name: '🔐 Configure AWS Credentials' - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@v5 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} From 20401df25dd9f47770050cf348d310a3ab42c0af Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 16:36:22 +0200 Subject: [PATCH 19/30] chore(cli): fix some DOC rules (preview) (#32839) Co-authored-by: Mason Daugherty --- libs/cli/langchain_cli/dev_scripts.py | 26 +++++++- .../namespaces/migrate/generate/generic.py | 30 ++++++++- .../namespaces/migrate/generate/grit.py | 19 +++++- .../namespaces/migrate/generate/utils.py | 63 +++++++++++++++++-- libs/cli/langchain_cli/utils/events.py | 9 ++- libs/cli/langchain_cli/utils/find_replace.py | 10 ++- libs/cli/langchain_cli/utils/git.py | 45 ++++++++++++- libs/cli/langchain_cli/utils/github.py | 9 ++- libs/cli/langchain_cli/utils/packages.py | 26 +++++++- libs/cli/pyproject.toml | 3 +- 10 files changed, 218 insertions(+), 22 deletions(-) diff --git a/libs/cli/langchain_cli/dev_scripts.py b/libs/cli/langchain_cli/dev_scripts.py index 00048d8afe3..98ae985f051 100644 --- a/libs/cli/langchain_cli/dev_scripts.py +++ b/libs/cli/langchain_cli/dev_scripts.py @@ -14,7 +14,19 @@ def create_demo_server( config_keys: Sequence[str] = (), playground_type: Literal["default", "chat"] = "default", ) -> FastAPI: - """Create a demo server for the current template.""" + """Create a demo server for the current template. + + Args: + config_keys: Optional sequence of config keys to expose in the playground. + playground_type: The type of playground to use. Can be `'default'` or `'chat'`. + + Returns: + The demo server. + + Raises: + KeyError: If the `pyproject.toml` file is missing required fields. + ImportError: If the module defined in `pyproject.toml` cannot be imported. + """ app = FastAPI() package_root = get_package_root() pyproject = package_root / "pyproject.toml" @@ -41,10 +53,18 @@ def create_demo_server( def create_demo_server_configurable() -> FastAPI: - """Create a configurable demo server.""" + """Create a configurable demo server. + + Returns: + The configurable demo server. + """ return create_demo_server(config_keys=["configurable"]) def create_demo_server_chat() -> FastAPI: - """Create a chat demo server.""" + """Create a chat demo server. + + Returns: + The chat demo server. + """ return create_demo_server(playground_type="chat") diff --git a/libs/cli/langchain_cli/namespaces/migrate/generate/generic.py b/libs/cli/langchain_cli/namespaces/migrate/generate/generic.py index 98167d8c231..ac8c059e465 100644 --- a/libs/cli/langchain_cli/namespaces/migrate/generate/generic.py +++ b/libs/cli/langchain_cli/namespaces/migrate/generate/generic.py @@ -11,7 +11,16 @@ def generate_raw_migrations( to_package: str, filter_by_all: bool = False, # noqa: FBT001, FBT002 ) -> list[tuple[str, str]]: - """Scan the `langchain` package and generate migrations for all modules.""" + """Scan the `langchain` package and generate migrations for all modules. + + Args: + from_package: The package to migrate from. + to_package: The package to migrate to. + filter_by_all: Whether to only consider items in `__all__`. + + Returns: + A list of tuples containing the original import path and the new import path. + """ package = importlib.import_module(from_package) items = [] @@ -84,6 +93,13 @@ def generate_top_level_imports(pkg: str) -> list[tuple[str, str]]: and the second tuple will contain the path to importing it from the top level namespaces (e.g., ``langchain_community.chat_models.XYZ``) + + Args: + pkg: The package to scan. + + Returns: + A list of tuples containing the fully qualified path and the top-level + import path. """ package = importlib.import_module(pkg) @@ -130,7 +146,17 @@ def generate_simplified_migrations( to_package: str, filter_by_all: bool = True, # noqa: FBT001, FBT002 ) -> list[tuple[str, str]]: - """Get all the raw migrations, then simplify them if possible.""" + """Get all the raw migrations, then simplify them if possible. + + Args: + from_package: The package to migrate from. + to_package: The package to migrate to. + filter_by_all: Whether to only consider items in `__all__`. + + Returns: + A list of tuples containing the original import path and the simplified + import path. + """ raw_migrations = generate_raw_migrations( from_package, to_package, diff --git a/libs/cli/langchain_cli/namespaces/migrate/generate/grit.py b/libs/cli/langchain_cli/namespaces/migrate/generate/grit.py index 14944ec459d..86f55f95021 100644 --- a/libs/cli/langchain_cli/namespaces/migrate/generate/grit.py +++ b/libs/cli/langchain_cli/namespaces/migrate/generate/grit.py @@ -2,13 +2,28 @@ def split_package(package: str) -> tuple[str, str]: - """Split a package name into the containing package and the final name.""" + """Split a package name into the containing package and the final name. + + Args: + package: The full package name. + + Returns: + A tuple of `(containing_package, final_name)`. + """ parts = package.split(".") return ".".join(parts[:-1]), parts[-1] def dump_migrations_as_grit(name: str, migration_pairs: list[tuple[str, str]]) -> str: - """Dump the migration pairs as a Grit file.""" + """Dump the migration pairs as a Grit file. + + Args: + name: The name of the migration. + migration_pairs: A list of tuples `(from_module, to_module)`. + + Returns: + The Grit file as a string. + """ remapped = ",\n".join( [ f""" diff --git a/libs/cli/langchain_cli/namespaces/migrate/generate/utils.py b/libs/cli/langchain_cli/namespaces/migrate/generate/utils.py index 8794637cd65..8c7a01f3b17 100644 --- a/libs/cli/langchain_cli/namespaces/migrate/generate/utils.py +++ b/libs/cli/langchain_cli/namespaces/migrate/generate/utils.py @@ -59,7 +59,15 @@ def _get_class_names(code: str) -> list[str]: def is_subclass(class_obj: type, classes_: list[type]) -> bool: - """Check if the given class object is a subclass of any class in list classes.""" + """Check if the given class object is a subclass of any class in list classes. + + Args: + class_obj: The class to check. + classes_: A list of classes to check against. + + Returns: + True if `class_obj` is a subclass of any class in `classes_`, False otherwise. + """ return any( issubclass(class_obj, kls) for kls in classes_ @@ -68,7 +76,15 @@ def is_subclass(class_obj: type, classes_: list[type]) -> bool: def find_subclasses_in_module(module: ModuleType, classes_: list[type]) -> list[str]: - """Find all classes in the module that inherit from one of the classes.""" + """Find all classes in the module that inherit from one of the classes. + + Args: + module: The module to inspect. + classes_: A list of classes to check against. + + Returns: + A list of class names that are subclasses of any class in `classes_`. + """ subclasses = [] # Iterate over all attributes of the module that are classes for _name, obj in inspect.getmembers(module, inspect.isclass): @@ -91,7 +107,15 @@ def identify_all_imports_in_file( *, from_package: Optional[str] = None, ) -> list[tuple[str, str]]: - """Let's also identify all the imports in the given file.""" + """Identify all the imports in the given file. + + Args: + file: The file to analyze. + from_package: If provided, only return imports from this package. + + Returns: + A list of tuples `(module, name)` representing the imports found in the file. + """ code = Path(file).read_text(encoding="utf-8") return find_imports_from_package(code, from_package=from_package) @@ -106,6 +130,9 @@ def identify_pkg_source(pkg_root: str) -> pathlib.Path: Returns: Returns the path to the source code for the package. + Raises: + ValueError: If there is not exactly one directory starting with `'langchain_'` + in the package root. """ dirs = [d for d in Path(pkg_root).iterdir() if d.is_dir()] matching_dirs = [d for d in dirs if d.name.startswith("langchain_")] @@ -116,7 +143,15 @@ def identify_pkg_source(pkg_root: str) -> pathlib.Path: def list_classes_by_package(pkg_root: str) -> list[tuple[str, str]]: - """List all classes in a package.""" + """List all classes in a package. + + Args: + pkg_root: the root of the package. + + Returns: + A list of tuples `(module, class_name)` representing all classes found in the + package, excluding test files. + """ module_classes = [] pkg_source = identify_pkg_source(pkg_root) files = list(pkg_source.rglob("*.py")) @@ -130,7 +165,15 @@ def list_classes_by_package(pkg_root: str) -> list[tuple[str, str]]: def list_init_imports_by_package(pkg_root: str) -> list[tuple[str, str]]: - """List all the things that are being imported in a package by module.""" + """List all the things that are being imported in a package by module. + + Args: + pkg_root: the root of the package. + + Returns: + A list of tuples `(module, name)` representing the imports found in + `__init__.py` files. + """ imports = [] pkg_source = identify_pkg_source(pkg_root) # Scan all the files in the package @@ -150,7 +193,15 @@ def find_imports_from_package( *, from_package: Optional[str] = None, ) -> list[tuple[str, str]]: - """Find imports in code.""" + """Find imports in code. + + Args: + code: The code to analyze. + from_package: If provided, only return imports from this package. + + Returns: + A list of tuples `(module, name)` representing the imports found. + """ # Parse the code into an AST tree = ast.parse(code) # Create an instance of the visitor diff --git a/libs/cli/langchain_cli/utils/events.py b/libs/cli/langchain_cli/utils/events.py index b947156e224..4b8e628efce 100644 --- a/libs/cli/langchain_cli/utils/events.py +++ b/libs/cli/langchain_cli/utils/events.py @@ -22,7 +22,14 @@ class EventDict(TypedDict): def create_events(events: list[EventDict]) -> Optional[dict[str, Any]]: - """Create events.""" + """Create events. + + Args: + events: A list of event dictionaries. + + Returns: + The response from the event tracking service, or None if there was an error. + """ try: data = { "events": [ diff --git a/libs/cli/langchain_cli/utils/find_replace.py b/libs/cli/langchain_cli/utils/find_replace.py index 2cfacf70b37..b53aa42a08d 100644 --- a/libs/cli/langchain_cli/utils/find_replace.py +++ b/libs/cli/langchain_cli/utils/find_replace.py @@ -4,7 +4,15 @@ from pathlib import Path def find_and_replace(source: str, replacements: dict[str, str]) -> str: - """Find and replace text in a string.""" + """Find and replace text in a string. + + Args: + source: The source string. + replacements: A dictionary of `{find: replace}` pairs. + + Returns: + The modified string. + """ rtn = source # replace keys in deterministic alphabetical order diff --git a/libs/cli/langchain_cli/utils/git.py b/libs/cli/langchain_cli/utils/git.py index 0ca83eb6a4c..4eb52435dfa 100644 --- a/libs/cli/langchain_cli/utils/git.py +++ b/libs/cli/langchain_cli/utils/git.py @@ -36,7 +36,20 @@ def parse_dependency_string( branch: Optional[str], api_path: Optional[str], ) -> DependencySource: - """Parse a dependency string into a DependencySource.""" + """Parse a dependency string into a DependencySource. + + Args: + dep: the dependency string. + repo: optional repository. + branch: optional branch. + api_path: optional API path. + + Returns: + The parsed dependency source information. + + Raises: + ValueError: if the dependency string is invalid. + """ if dep is not None and dep.startswith("git+"): if repo is not None or branch is not None: msg = ( @@ -129,7 +142,22 @@ def parse_dependencies( branch: list[str], api_path: list[str], ) -> list[DependencySource]: - """Parse dependencies.""" + """Parse dependencies. + + Args: + dependencies: the dependencies to parse + repo: the repositories to use + branch: the branches to use + api_path: the api paths to use + + Returns: + A list of DependencySource objects. + + Raises: + ValueError: if the number of `dependencies`, `repos`, `branches`, or `api_paths` + do not match. + + """ num_deps = max( len(dependencies) if dependencies is not None else 0, len(repo), @@ -177,7 +205,18 @@ def _get_repo_path(gitstring: str, ref: Optional[str], repo_dir: Path) -> Path: def update_repo(gitstring: str, ref: Optional[str], repo_dir: Path) -> Path: - """Update a git repository to the specified ref.""" + """Update a git repository to the specified ref. + + Tries to pull if the repo already exists, otherwise clones it. + + Args: + gitstring: The git repository URL. + ref: The git reference. + repo_dir: The directory to clone the repository into. + + Returns: + The path to the cloned repository. + """ # see if path already saved repo_path = _get_repo_path(gitstring, ref, repo_dir) if repo_path.exists(): diff --git a/libs/cli/langchain_cli/utils/github.py b/libs/cli/langchain_cli/utils/github.py index 2feabea7ef9..b1cd6e01461 100644 --- a/libs/cli/langchain_cli/utils/github.py +++ b/libs/cli/langchain_cli/utils/github.py @@ -6,7 +6,14 @@ from typing import Optional def list_packages(*, contains: Optional[str] = None) -> list[str]: - """List all packages in the langchain repository templates directory.""" + """List all packages in the langchain repository templates directory. + + Args: + contains: Optional substring that the package name must contain. + + Returns: + A list of package names. + """ conn = http.client.HTTPSConnection("api.github.com") try: headers = { diff --git a/libs/cli/langchain_cli/utils/packages.py b/libs/cli/langchain_cli/utils/packages.py index 0d3610c3887..a1c96c5ccc7 100644 --- a/libs/cli/langchain_cli/utils/packages.py +++ b/libs/cli/langchain_cli/utils/packages.py @@ -7,7 +7,19 @@ from tomlkit import load def get_package_root(cwd: Optional[Path] = None) -> Path: - """Get package root directory.""" + """Get package root directory. + + Args: + cwd: The current working directory to start the search from. + If None, uses the current working directory of the process. + + Returns: + The path to the package root directory. + + Raises: + FileNotFoundError: If no `pyproject.toml` file is found in the directory + hierarchy. + """ # traverse path for routes to host (any directory holding a pyproject.toml file) package_root = Path.cwd() if cwd is None else cwd visited: set[Path] = set() @@ -38,7 +50,17 @@ class LangServeExport(TypedDict): def get_langserve_export(filepath: Path) -> LangServeExport: - """Get LangServe export information from a pyproject.toml file.""" + """Get LangServe export information from a `pyproject.toml` file. + + Args: + filepath: Path to the `pyproject.toml` file. + + Returns: + The LangServeExport information. + + Raises: + KeyError: If the `pyproject.toml` file is missing required fields. + """ with filepath.open() as f: data: dict[str, Any] = load(f) try: diff --git a/libs/cli/pyproject.toml b/libs/cli/pyproject.toml index e5cbdd50463..cf333f246e3 100644 --- a/libs/cli/pyproject.toml +++ b/libs/cli/pyproject.toml @@ -52,6 +52,7 @@ select = [ "ALL",] ignore = [ "C90", # McCabe complexity "COM812", # Messes with the formatter + "CPY", # No copyright "FIX002", # Line contains TODO "PERF203", # Rarely useful "PLR09", # Too many something (arg, statements, etc) @@ -78,7 +79,7 @@ pydocstyle.convention = "google" pyupgrade.keep-runtime-typing = true [tool.ruff.lint.per-file-ignores] -"tests/**" = [ "D1", "S", "SLF",] +"tests/**" = [ "D1", "DOC", "S", "SLF",] "scripts/**" = [ "INP", "S",] [tool.mypy] From 0c3e8ccd0ebad79c51bb4e8ff8d821f03bf59572 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 16:46:09 +0200 Subject: [PATCH 20/30] chore(text-splitters): select ALL rules with exclusions (#32325) Co-authored-by: Mason Daugherty --- .../langchain_text_splitters/base.py | 82 ++++---- .../langchain_text_splitters/character.py | 46 +++-- .../langchain_text_splitters/html.py | 188 ++++++++++-------- .../langchain_text_splitters/json.py | 16 +- .../langchain_text_splitters/jsx.py | 2 + .../langchain_text_splitters/konlpy.py | 15 +- .../langchain_text_splitters/latex.py | 2 + .../langchain_text_splitters/markdown.py | 3 +- .../langchain_text_splitters/nltk.py | 26 ++- .../langchain_text_splitters/python.py | 2 + .../sentence_transformers.py | 17 +- .../langchain_text_splitters/spacy.py | 23 ++- libs/text-splitters/pyproject.toml | 96 +++------ libs/text-splitters/scripts/check_imports.py | 2 +- .../test_nlp_text_splitters.py | 38 ++-- .../integration_tests/test_text_splitter.py | 30 ++- .../tests/unit_tests/conftest.py | 9 +- .../tests/unit_tests/test_text_splitters.py | 139 +++++++------ libs/text-splitters/uv.lock | 74 +++---- 19 files changed, 444 insertions(+), 366 deletions(-) diff --git a/libs/text-splitters/langchain_text_splitters/base.py b/libs/text-splitters/langchain_text_splitters/base.py index 0ab553cefe4..bce83f14fa0 100644 --- a/libs/text-splitters/langchain_text_splitters/base.py +++ b/libs/text-splitters/langchain_text_splitters/base.py @@ -1,3 +1,5 @@ +"""Text splitter base interface.""" + from __future__ import annotations import copy @@ -16,12 +18,27 @@ from typing import ( ) from langchain_core.documents import BaseDocumentTransformer, Document -from typing_extensions import Self +from typing_extensions import Self, override if TYPE_CHECKING: from collections.abc import Collection, Iterable, Sequence from collections.abc import Set as AbstractSet + +try: + import tiktoken + + _HAS_TIKTOKEN = True +except ImportError: + _HAS_TIKTOKEN = False + +try: + from transformers.tokenization_utils_base import PreTrainedTokenizerBase + + _HAS_TRANSFORMERS = True +except ImportError: + _HAS_TRANSFORMERS = False + logger = logging.getLogger(__name__) TS = TypeVar("TS", bound="TextSplitter") @@ -78,13 +95,13 @@ class TextSplitter(BaseDocumentTransformer, ABC): self, texts: list[str], metadatas: Optional[list[dict[Any, Any]]] = None ) -> list[Document]: """Create documents from a list of texts.""" - _metadatas = metadatas or [{}] * len(texts) + metadatas_ = metadatas or [{}] * len(texts) documents = [] for i, text in enumerate(texts): index = 0 previous_chunk_len = 0 for chunk in self.split_text(text): - metadata = copy.deepcopy(_metadatas[i]) + metadata = copy.deepcopy(metadatas_[i]) if self._add_start_index: offset = index + previous_chunk_len - self._chunk_overlap index = text.find(chunk, max(0, offset)) @@ -106,9 +123,7 @@ class TextSplitter(BaseDocumentTransformer, ABC): text = separator.join(docs) if self._strip_whitespace: text = text.strip() - if text == "": - return None - return text + return text or None def _merge_splits(self, splits: Iterable[str], separator: str) -> list[str]: # We now want to combine these smaller pieces into medium size @@ -119,15 +134,17 @@ class TextSplitter(BaseDocumentTransformer, ABC): current_doc: list[str] = [] total = 0 for d in splits: - _len = self._length_function(d) + len_ = self._length_function(d) if ( - total + _len + (separator_len if len(current_doc) > 0 else 0) + total + len_ + (separator_len if len(current_doc) > 0 else 0) > self._chunk_size ): if total > self._chunk_size: logger.warning( - f"Created a chunk of size {total}, " - f"which is longer than the specified {self._chunk_size}" + "Created a chunk of size %s, " + "which is longer than the specified %s", + total, + self._chunk_size, ) if len(current_doc) > 0: doc = self._join_docs(current_doc, separator) @@ -137,7 +154,7 @@ class TextSplitter(BaseDocumentTransformer, ABC): # - we have a larger chunk than in the chunk overlap # - or if we still have any chunks and the length is long while total > self._chunk_overlap or ( - total + _len + (separator_len if len(current_doc) > 0 else 0) + total + len_ + (separator_len if len(current_doc) > 0 else 0) > self._chunk_size and total > 0 ): @@ -146,33 +163,31 @@ class TextSplitter(BaseDocumentTransformer, ABC): ) current_doc = current_doc[1:] current_doc.append(d) - total += _len + (separator_len if len(current_doc) > 1 else 0) + total += len_ + (separator_len if len(current_doc) > 1 else 0) doc = self._join_docs(current_doc, separator) if doc is not None: docs.append(doc) return docs @classmethod - def from_huggingface_tokenizer(cls, tokenizer: Any, **kwargs: Any) -> TextSplitter: + def from_huggingface_tokenizer( + cls, tokenizer: PreTrainedTokenizerBase, **kwargs: Any + ) -> TextSplitter: """Text splitter that uses HuggingFace tokenizer to count length.""" - try: - from transformers.tokenization_utils_base import PreTrainedTokenizerBase - - if not isinstance(tokenizer, PreTrainedTokenizerBase): - msg = ( - "Tokenizer received was not an instance of PreTrainedTokenizerBase" - ) - raise ValueError(msg) - - def _huggingface_tokenizer_length(text: str) -> int: - return len(tokenizer.tokenize(text)) - - except ImportError as err: + if not _HAS_TRANSFORMERS: msg = ( "Could not import transformers python package. " "Please install it with `pip install transformers`." ) - raise ValueError(msg) from err + raise ValueError(msg) + + if not isinstance(tokenizer, PreTrainedTokenizerBase): + msg = "Tokenizer received was not an instance of PreTrainedTokenizerBase" # type: ignore[unreachable] + raise ValueError(msg) # noqa: TRY004 + + def _huggingface_tokenizer_length(text: str) -> int: + return len(tokenizer.tokenize(text)) + return cls(length_function=_huggingface_tokenizer_length, **kwargs) @classmethod @@ -185,15 +200,13 @@ class TextSplitter(BaseDocumentTransformer, ABC): **kwargs: Any, ) -> Self: """Text splitter that uses tiktoken encoder to count length.""" - try: - import tiktoken - except ImportError as err: + if not _HAS_TIKTOKEN: msg = ( "Could not import tiktoken python package. " "This is needed in order to calculate max_tokens_for_prompt. " "Please install it with `pip install tiktoken`." ) - raise ImportError(msg) from err + raise ImportError(msg) if model_name is not None: enc = tiktoken.encoding_for_model(model_name) @@ -220,6 +233,7 @@ class TextSplitter(BaseDocumentTransformer, ABC): return cls(length_function=_tiktoken_encoder, **kwargs) + @override def transform_documents( self, documents: Sequence[Document], **kwargs: Any ) -> Sequence[Document]: @@ -240,15 +254,13 @@ class TokenTextSplitter(TextSplitter): ) -> None: """Create a new TextSplitter.""" super().__init__(**kwargs) - try: - import tiktoken - except ImportError as err: + if not _HAS_TIKTOKEN: msg = ( "Could not import tiktoken python package. " "This is needed in order to for TokenTextSplitter. " "Please install it with `pip install tiktoken`." ) - raise ImportError(msg) from err + raise ImportError(msg) if model_name is not None: enc = tiktoken.encoding_for_model(model_name) diff --git a/libs/text-splitters/langchain_text_splitters/character.py b/libs/text-splitters/langchain_text_splitters/character.py index 90366c5b51d..3a6d77d42d0 100644 --- a/libs/text-splitters/langchain_text_splitters/character.py +++ b/libs/text-splitters/langchain_text_splitters/character.py @@ -1,3 +1,5 @@ +"""Character text splitters.""" + from __future__ import annotations import re @@ -56,24 +58,24 @@ def _split_text_with_regex( if separator: if keep_separator: # The parentheses in the pattern keep the delimiters in the result. - _splits = re.split(f"({separator})", text) + splits_ = re.split(f"({separator})", text) splits = ( - ([_splits[i] + _splits[i + 1] for i in range(0, len(_splits) - 1, 2)]) + ([splits_[i] + splits_[i + 1] for i in range(0, len(splits_) - 1, 2)]) if keep_separator == "end" - else ([_splits[i] + _splits[i + 1] for i in range(1, len(_splits), 2)]) + else ([splits_[i] + splits_[i + 1] for i in range(1, len(splits_), 2)]) ) - if len(_splits) % 2 == 0: - splits += _splits[-1:] + if len(splits_) % 2 == 0: + splits += splits_[-1:] splits = ( - ([*splits, _splits[-1]]) + ([*splits, splits_[-1]]) if keep_separator == "end" - else ([_splits[0], *splits]) + else ([splits_[0], *splits]) ) else: splits = re.split(separator, text) else: splits = list(text) - return [s for s in splits if s != ""] + return [s for s in splits if s] class RecursiveCharacterTextSplitter(TextSplitter): @@ -102,38 +104,38 @@ class RecursiveCharacterTextSplitter(TextSplitter): separator = separators[-1] new_separators = [] for i, _s in enumerate(separators): - _separator = _s if self._is_separator_regex else re.escape(_s) - if _s == "": + separator_ = _s if self._is_separator_regex else re.escape(_s) + if not _s: separator = _s break - if re.search(_separator, text): + if re.search(separator_, text): separator = _s new_separators = separators[i + 1 :] break - _separator = separator if self._is_separator_regex else re.escape(separator) + separator_ = separator if self._is_separator_regex else re.escape(separator) splits = _split_text_with_regex( - text, _separator, keep_separator=self._keep_separator + text, separator_, keep_separator=self._keep_separator ) # Now go merging things, recursively splitting longer texts. - _good_splits = [] - _separator = "" if self._keep_separator else separator + good_splits = [] + separator_ = "" if self._keep_separator else separator for s in splits: if self._length_function(s) < self._chunk_size: - _good_splits.append(s) + good_splits.append(s) else: - if _good_splits: - merged_text = self._merge_splits(_good_splits, _separator) + if good_splits: + merged_text = self._merge_splits(good_splits, separator_) final_chunks.extend(merged_text) - _good_splits = [] + good_splits = [] if not new_separators: final_chunks.append(s) else: other_info = self._split_text(s, new_separators) final_chunks.extend(other_info) - if _good_splits: - merged_text = self._merge_splits(_good_splits, _separator) + if good_splits: + merged_text = self._merge_splits(good_splits, separator_) final_chunks.extend(merged_text) return final_chunks @@ -177,7 +179,7 @@ class RecursiveCharacterTextSplitter(TextSplitter): Returns: List[str]: A list of separators appropriate for the specified language. """ - if language in (Language.C, Language.CPP): + if language in {Language.C, Language.CPP}: return [ # Split along class definitions "\nclass ", diff --git a/libs/text-splitters/langchain_text_splitters/html.py b/libs/text-splitters/langchain_text_splitters/html.py index 4d78fbcc35a..35471fb2ff8 100644 --- a/libs/text-splitters/langchain_text_splitters/html.py +++ b/libs/text-splitters/langchain_text_splitters/html.py @@ -1,3 +1,5 @@ +"""HTML text splitters.""" + from __future__ import annotations import copy @@ -5,6 +7,7 @@ import pathlib import re from io import StringIO from typing import ( + IO, TYPE_CHECKING, Any, Callable, @@ -18,13 +21,36 @@ from typing import ( import requests from langchain_core._api import beta from langchain_core.documents import BaseDocumentTransformer, Document +from typing_extensions import override from langchain_text_splitters.character import RecursiveCharacterTextSplitter if TYPE_CHECKING: - from collections.abc import Iterable, Sequence + from collections.abc import Iterable, Iterator, Sequence - from bs4.element import PageElement + from bs4.element import ResultSet + +try: + import nltk + + _HAS_NLTK = True +except ImportError: + _HAS_NLTK = False + +try: + from bs4 import BeautifulSoup, Tag + from bs4.element import NavigableString, PageElement + + _HAS_BS4 = True +except ImportError: + _HAS_BS4 = False + +try: + from lxml import etree + + _HAS_LXML = True +except ImportError: + _HAS_LXML = False class ElementType(TypedDict): @@ -36,6 +62,29 @@ class ElementType(TypedDict): metadata: dict[str, str] +# Unfortunately, BeautifulSoup doesn't define overloads for Tag.find_all. +# So doing the type resolution ourselves. + + +def _find_all_strings( + tag: Tag, + *, + recursive: bool = True, +) -> ResultSet[NavigableString]: + return cast( + "ResultSet[NavigableString]", tag.find_all(string=True, recursive=recursive) + ) + + +def _find_all_tags( + tag: Tag, + *, + name: Union[bool, str, list[str], None] = None, + recursive: bool = True, +) -> ResultSet[Tag]: + return cast("ResultSet[Tag]", tag.find_all(name, recursive=recursive)) + + class HTMLHeaderTextSplitter: """Split HTML content into structured Documents based on specified headers. @@ -157,16 +206,11 @@ class HTMLHeaderTextSplitter: Raises: requests.RequestException: If the HTTP request fails. """ - kwargs.setdefault("timeout", timeout) - response = requests.get( - url, - timeout=kwargs.get("timeout", timeout), - **{k: v for k, v in kwargs.items() if k != "timeout"}, - ) + response = requests.get(url, timeout=timeout, **kwargs) response.raise_for_status() return self.split_text(response.text) - def split_text_from_file(self, file: Any) -> list[Document]: + def split_text_from_file(self, file: Union[str, IO[str]]) -> list[Document]: """Split HTML content from a file into a list of Document objects. Args: @@ -178,13 +222,12 @@ class HTMLHeaderTextSplitter: the header hierarchy to their corresponding titles. """ if isinstance(file, str): - with open(file, encoding="utf-8") as f: - html_content = f.read() + html_content = pathlib.Path(file).read_text(encoding="utf-8") else: html_content = file.read() return list(self._generate_documents(html_content)) - def _generate_documents(self, html_content: str) -> Any: + def _generate_documents(self, html_content: str) -> Iterator[Document]: """Private method that performs a DFS traversal over the DOM and yields. Document objects on-the-fly. This approach maintains the same splitting @@ -197,20 +240,18 @@ class HTMLHeaderTextSplitter: Yields: Document objects as they are created. """ - try: - from bs4 import BeautifulSoup - except ImportError as e: + if not _HAS_BS4: msg = ( "Unable to import BeautifulSoup. Please install via `pip install bs4`." ) - raise ImportError(msg) from e + raise ImportError(msg) soup = BeautifulSoup(html_content, "html.parser") - body = soup.body if soup.body else soup + body = soup.body or soup # Dictionary of active headers: # key = user-defined header name (e.g. "Header 1") - # value = (header_text, level, dom_depth) + # value = tuple of header_text, level, dom_depth active_headers: dict[str, tuple[str, int, int]] = {} current_chunk: list[str] = [] @@ -232,7 +273,6 @@ class HTMLHeaderTextSplitter: while stack: node = stack.pop() children = list(node.children) - from bs4.element import Tag stack.extend( child for child in reversed(children) if isinstance(child, Tag) @@ -243,8 +283,7 @@ class HTMLHeaderTextSplitter: continue text_elements = [ - str(child).strip() - for child in node.find_all(string=True, recursive=False) + str(child).strip() for child in _find_all_strings(node, recursive=False) ] node_text = " ".join(elem for elem in text_elements if elem) if not node_text: @@ -353,11 +392,11 @@ class HTMLSectionSplitter: self, texts: list[str], metadatas: Optional[list[dict[Any, Any]]] = None ) -> list[Document]: """Create documents from a list of texts.""" - _metadatas = metadatas or [{}] * len(texts) + metadatas_ = metadatas or [{}] * len(texts) documents = [] for i, text in enumerate(texts): for chunk in self.split_text(text): - metadata = copy.deepcopy(_metadatas[i]) + metadata = copy.deepcopy(metadatas_[i]) for key in chunk.metadata: if chunk.metadata[key] == "#TITLE#": @@ -386,38 +425,35 @@ class HTMLSectionSplitter: * 'content': The content under the header. * 'tag_name': The name of the header tag (e.g., "h1", "h2"). """ - try: - from bs4 import BeautifulSoup - except ImportError as e: + if not _HAS_BS4: msg = "Unable to import BeautifulSoup/PageElement, \ please install with `pip install \ bs4`." - raise ImportError(msg) from e + raise ImportError(msg) soup = BeautifulSoup(html_doc, "html.parser") - headers = list(self.headers_to_split_on.keys()) + header_names = list(self.headers_to_split_on.keys()) sections: list[dict[str, str | None]] = [] - headers = soup.find_all(["body", *headers]) # type: ignore[assignment] + headers = _find_all_tags(soup, name=["body", *header_names]) for i, header in enumerate(headers): - header_element = cast("PageElement", header) if i == 0: current_header = "#TITLE#" current_header_tag = "h1" section_content: list[str] = [] else: - current_header = header_element.text.strip() - current_header_tag = header_element.name # type: ignore[attr-defined] + current_header = header.text.strip() + current_header_tag = header.name section_content = [] - for element in header_element.next_elements: - if i + 1 < len(headers) and element == headers[i + 1]: # type: ignore[comparison-overlap] + for element in header.next_elements: + if i + 1 < len(headers) and element == headers[i + 1]: break if isinstance(element, str): section_content.append(element) content = " ".join(section_content).strip() - if content != "": + if content: sections.append( { "header": current_header, @@ -441,11 +477,9 @@ class HTMLSectionSplitter: Returns: str: The transformed HTML content as a string. """ - try: - from lxml import etree - except ImportError as e: + if not _HAS_LXML: msg = "Unable to import lxml, please install with `pip install lxml`." - raise ImportError(msg) from e + raise ImportError(msg) # use lxml library to parse html document and return xml ElementTree # Create secure parsers to prevent XXE attacks html_parser = etree.HTMLParser(no_network=True) @@ -464,7 +498,7 @@ class HTMLSectionSplitter: result = transform(tree) return str(result) - def split_text_from_file(self, file: Any) -> list[Document]: + def split_text_from_file(self, file: StringIO) -> list[Document]: """Split HTML content from a file into a list of Document objects. Args: @@ -546,7 +580,7 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): preserve_images: bool = False, preserve_videos: bool = False, preserve_audio: bool = False, - custom_handlers: Optional[dict[str, Callable[[Any], str]]] = None, + custom_handlers: Optional[dict[str, Callable[[Tag], str]]] = None, stopword_removal: bool = False, stopword_lang: str = "english", normalize_text: bool = False, @@ -592,17 +626,12 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): keep_separator: Whether separators should be at the beginning of a chunk, at the end, or not at all. """ - try: - from bs4 import BeautifulSoup, Tag - - self._BeautifulSoup = BeautifulSoup - self._Tag = Tag - except ImportError as err: + if not _HAS_BS4: msg = ( "Could not import BeautifulSoup. " "Please install it with 'pip install bs4'." ) - raise ImportError(msg) from err + raise ImportError(msg) self._headers_to_split_on = sorted(headers_to_split_on) self._max_chunk_size = max_chunk_size @@ -645,16 +674,13 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): ) if self._stopword_removal: - try: - import nltk - - nltk.download("stopwords") - self._stopwords = set(nltk.corpus.stopwords.words(self._stopword_lang)) - except ImportError as err: + if not _HAS_NLTK: msg = ( "Could not import nltk. Please install it with 'pip install nltk'." ) - raise ImportError(msg) from err + raise ImportError(msg) + nltk.download("stopwords") + self._stopwords = set(nltk.corpus.stopwords.words(self._stopword_lang)) def split_text(self, text: str) -> list[Document]: """Splits the provided HTML text into smaller chunks based on the configuration. @@ -665,7 +691,7 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): Returns: List[Document]: A list of Document objects containing the split content. """ - soup = self._BeautifulSoup(text, "html.parser") + soup = BeautifulSoup(text, "html.parser") self._process_media(soup) @@ -677,6 +703,7 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): return self._process_html(soup) + @override def transform_documents( self, documents: Sequence[Document], **kwargs: Any ) -> list[Document]: @@ -695,17 +722,17 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): transformed.extend(splits) return transformed - def _process_media(self, soup: Any) -> None: + def _process_media(self, soup: BeautifulSoup) -> None: """Processes the media elements. Process elements in the HTML content by wrapping them in a tag and converting them to Markdown format. Args: - soup (Any): Parsed HTML content using BeautifulSoup. + soup: Parsed HTML content using BeautifulSoup. """ if self._preserve_images: - for img_tag in soup.find_all("img"): + for img_tag in _find_all_tags(soup, name="img"): img_src = img_tag.get("src", "") markdown_img = f"![image:{img_src}]({img_src})" wrapper = soup.new_tag("media-wrapper") @@ -713,7 +740,7 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): img_tag.replace_with(wrapper) if self._preserve_videos: - for video_tag in soup.find_all("video"): + for video_tag in _find_all_tags(soup, name="video"): video_src = video_tag.get("src", "") markdown_video = f"![video:{video_src}]({video_src})" wrapper = soup.new_tag("media-wrapper") @@ -721,40 +748,40 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): video_tag.replace_with(wrapper) if self._preserve_audio: - for audio_tag in soup.find_all("audio"): + for audio_tag in _find_all_tags(soup, name="audio"): audio_src = audio_tag.get("src", "") markdown_audio = f"![audio:{audio_src}]({audio_src})" wrapper = soup.new_tag("media-wrapper") wrapper.string = markdown_audio audio_tag.replace_with(wrapper) - def _process_links(self, soup: Any) -> None: + def _process_links(self, soup: BeautifulSoup) -> None: """Processes the links in the HTML content. Args: - soup (Any): Parsed HTML content using BeautifulSoup. + soup: Parsed HTML content using BeautifulSoup. """ - for a_tag in soup.find_all("a"): + for a_tag in _find_all_tags(soup, name="a"): a_href = a_tag.get("href", "") a_text = a_tag.get_text(strip=True) markdown_link = f"[{a_text}]({a_href})" wrapper = soup.new_tag("link-wrapper") wrapper.string = markdown_link - a_tag.replace_with(markdown_link) + a_tag.replace_with(NavigableString(markdown_link)) - def _filter_tags(self, soup: Any) -> None: + def _filter_tags(self, soup: BeautifulSoup) -> None: """Filters the HTML content based on the allowlist and denylist tags. Args: - soup (Any): Parsed HTML content using BeautifulSoup. + soup: Parsed HTML content using BeautifulSoup. """ if self._allowlist_tags: - for tag in soup.find_all(name=True): + for tag in _find_all_tags(soup, name=True): if tag.name not in self._allowlist_tags: tag.decompose() if self._denylist_tags: - for tag in soup.find_all(self._denylist_tags): + for tag in _find_all_tags(soup, name=self._denylist_tags): tag.decompose() def _normalize_and_clean_text(self, text: str) -> str: @@ -778,14 +805,14 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): return text - def _process_html(self, soup: Any) -> list[Document]: + def _process_html(self, soup: BeautifulSoup) -> list[Document]: """Processes the HTML content using BeautifulSoup and splits it using headers. Args: - soup (Any): Parsed HTML content using BeautifulSoup. + soup: Parsed HTML content using BeautifulSoup. Returns: - List[Document]: A list of Document objects containing the split content. + A list of Document objects containing the split content. """ documents: list[Document] = [] current_headers: dict[str, str] = {} @@ -793,17 +820,18 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): preserved_elements: dict[str, str] = {} placeholder_count: int = 0 - def _get_element_text(element: Any) -> str: + def _get_element_text(element: PageElement) -> str: """Recursively extracts and processes the text of an element. Applies custom handlers where applicable, and ensures correct spacing. Args: - element (Any): The HTML element to process. + element: The HTML element to process. Returns: - str: The processed text of the element. + The processed text of the element. """ + element = cast("Union[Tag, NavigableString]", element) if element.name in self._custom_handlers: return self._custom_handlers[element.name](element) @@ -820,10 +848,10 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): return self._normalize_and_clean_text(text) - elements = soup.find_all(recursive=False) + elements = _find_all_tags(soup, recursive=False) def _process_element( - element: list[Any], + element: ResultSet[Tag], documents: list[Document], current_headers: dict[str, str], current_content: list[str], @@ -831,8 +859,8 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): placeholder_count: int, ) -> tuple[list[Document], dict[str, str], list[str], dict[str, str], int]: for elem in element: - if elem.name.lower() in ["html", "body", "div", "main"]: - children = elem.find_all(recursive=False) + if elem.name.lower() in {"html", "body", "div", "main"}: + children = _find_all_tags(elem, recursive=False) ( documents, current_headers, @@ -847,7 +875,7 @@ class HTMLSemanticPreservingSplitter(BaseDocumentTransformer): preserved_elements, placeholder_count, ) - content = " ".join(elem.find_all(string=True, recursive=False)) + content = " ".join(_find_all_strings(elem, recursive=False)) if content: content = self._normalize_and_clean_text(content) current_content.append(content) diff --git a/libs/text-splitters/langchain_text_splitters/json.py b/libs/text-splitters/langchain_text_splitters/json.py index c2fa8936d2d..6e61bc33f96 100644 --- a/libs/text-splitters/langchain_text_splitters/json.py +++ b/libs/text-splitters/langchain_text_splitters/json.py @@ -1,3 +1,5 @@ +"""JSON text splitter.""" + from __future__ import annotations import copy @@ -50,13 +52,17 @@ class RecursiveJsonSplitter: return len(json.dumps(data)) @staticmethod - def _set_nested_dict(d: dict[str, Any], path: list[str], value: Any) -> None: + def _set_nested_dict( + d: dict[str, Any], + path: list[str], + value: Any, # noqa: ANN401 + ) -> None: """Set a value in a nested dictionary based on the given path.""" for key in path[:-1]: d = d.setdefault(key, {}) d[path[-1]] = value - def _list_to_dict_preprocessing(self, data: Any) -> Any: + def _list_to_dict_preprocessing(self, data: Any) -> Any: # noqa: ANN401 if isinstance(data, dict): # Process each key-value pair in the dictionary return {k: self._list_to_dict_preprocessing(v) for k, v in data.items()} @@ -71,7 +77,7 @@ class RecursiveJsonSplitter: def _json_split( self, - data: Any, + data: Any, # noqa: ANN401 current_path: Optional[list[str]] = None, chunks: Optional[list[dict[str, Any]]] = None, ) -> list[dict[str, Any]]: @@ -136,13 +142,13 @@ class RecursiveJsonSplitter: metadatas: Optional[list[dict[Any, Any]]] = None, ) -> list[Document]: """Create documents from a list of json objects (Dict).""" - _metadatas = metadatas or [{}] * len(texts) + metadatas_ = metadatas or [{}] * len(texts) documents = [] for i, text in enumerate(texts): for chunk in self.split_text( json_data=text, convert_lists=convert_lists, ensure_ascii=ensure_ascii ): - metadata = copy.deepcopy(_metadatas[i]) + metadata = copy.deepcopy(metadatas_[i]) new_doc = Document(page_content=chunk, metadata=metadata) documents.append(new_doc) return documents diff --git a/libs/text-splitters/langchain_text_splitters/jsx.py b/libs/text-splitters/langchain_text_splitters/jsx.py index 46216701125..1333065a760 100644 --- a/libs/text-splitters/langchain_text_splitters/jsx.py +++ b/libs/text-splitters/langchain_text_splitters/jsx.py @@ -1,3 +1,5 @@ +"""JavaScript framework text splitter.""" + import re from typing import Any, Optional diff --git a/libs/text-splitters/langchain_text_splitters/konlpy.py b/libs/text-splitters/langchain_text_splitters/konlpy.py index fc1763790f9..863447e883c 100644 --- a/libs/text-splitters/langchain_text_splitters/konlpy.py +++ b/libs/text-splitters/langchain_text_splitters/konlpy.py @@ -1,9 +1,18 @@ +"""Konlpy text splitter.""" + from __future__ import annotations from typing import Any from langchain_text_splitters.base import TextSplitter +try: + import konlpy + + _HAS_KONLPY = True +except ImportError: + _HAS_KONLPY = False + class KonlpyTextSplitter(TextSplitter): """Splitting text using Konlpy package. @@ -19,14 +28,12 @@ class KonlpyTextSplitter(TextSplitter): """Initialize the Konlpy text splitter.""" super().__init__(**kwargs) self._separator = separator - try: - import konlpy - except ImportError as err: + if not _HAS_KONLPY: msg = """ Konlpy is not installed, please install it with `pip install konlpy` """ - raise ImportError(msg) from err + raise ImportError(msg) self.kkma = konlpy.tag.Kkma() def split_text(self, text: str) -> list[str]: diff --git a/libs/text-splitters/langchain_text_splitters/latex.py b/libs/text-splitters/langchain_text_splitters/latex.py index 55d47f7851e..fc9c2ff498f 100644 --- a/libs/text-splitters/langchain_text_splitters/latex.py +++ b/libs/text-splitters/langchain_text_splitters/latex.py @@ -1,3 +1,5 @@ +"""Latex text splitter.""" + from __future__ import annotations from typing import Any diff --git a/libs/text-splitters/langchain_text_splitters/markdown.py b/libs/text-splitters/langchain_text_splitters/markdown.py index b5fb63c5d77..a1d40a43228 100644 --- a/libs/text-splitters/langchain_text_splitters/markdown.py +++ b/libs/text-splitters/langchain_text_splitters/markdown.py @@ -1,3 +1,5 @@ +"""Markdown text splitters.""" + from __future__ import annotations import re @@ -138,7 +140,6 @@ class MarkdownHeaderTextSplitter: current_content: list[str] = [] current_metadata: dict[str, str] = {} # Keep track of the nested header structure - # header_stack: List[Dict[str, Union[int, str]]] = [] header_stack: list[HeaderType] = [] initial_metadata: dict[str, str] = {} diff --git a/libs/text-splitters/langchain_text_splitters/nltk.py b/libs/text-splitters/langchain_text_splitters/nltk.py index 4ac7b0dbf02..8041d47d493 100644 --- a/libs/text-splitters/langchain_text_splitters/nltk.py +++ b/libs/text-splitters/langchain_text_splitters/nltk.py @@ -1,9 +1,18 @@ +"""NLTK text splitter.""" + from __future__ import annotations from typing import Any from langchain_text_splitters.base import TextSplitter +try: + import nltk + + _HAS_NLTK = True +except ImportError: + _HAS_NLTK = False + class NLTKTextSplitter(TextSplitter): """Splitting text using NLTK package.""" @@ -21,19 +30,16 @@ class NLTKTextSplitter(TextSplitter): self._separator = separator self._language = language self._use_span_tokenize = use_span_tokenize - if self._use_span_tokenize and self._separator != "": + if self._use_span_tokenize and self._separator: msg = "When use_span_tokenize is True, separator should be ''" raise ValueError(msg) - try: - import nltk - - if self._use_span_tokenize: - self._tokenizer = nltk.tokenize._get_punkt_tokenizer(self._language) - else: - self._tokenizer = nltk.tokenize.sent_tokenize - except ImportError as err: + if not _HAS_NLTK: msg = "NLTK is not installed, please install it with `pip install nltk`." - raise ImportError(msg) from err + raise ImportError(msg) + if self._use_span_tokenize: + self._tokenizer = nltk.tokenize._get_punkt_tokenizer(self._language) # noqa: SLF001 + else: + self._tokenizer = nltk.tokenize.sent_tokenize def split_text(self, text: str) -> list[str]: """Split incoming text and return chunks.""" diff --git a/libs/text-splitters/langchain_text_splitters/python.py b/libs/text-splitters/langchain_text_splitters/python.py index ffd4a10f62e..ccab44bcf65 100644 --- a/libs/text-splitters/langchain_text_splitters/python.py +++ b/libs/text-splitters/langchain_text_splitters/python.py @@ -1,3 +1,5 @@ +"""Python code text splitter.""" + from __future__ import annotations from typing import Any diff --git a/libs/text-splitters/langchain_text_splitters/sentence_transformers.py b/libs/text-splitters/langchain_text_splitters/sentence_transformers.py index 8cbe227495b..de3cd279705 100644 --- a/libs/text-splitters/langchain_text_splitters/sentence_transformers.py +++ b/libs/text-splitters/langchain_text_splitters/sentence_transformers.py @@ -1,9 +1,18 @@ +"""Sentence transformers text splitter.""" + from __future__ import annotations from typing import Any, Optional, cast from langchain_text_splitters.base import TextSplitter, Tokenizer, split_text_on_tokens +try: + from sentence_transformers import SentenceTransformer + + _HAS_SENTENCE_TRANSFORMERS = True +except ImportError: + _HAS_SENTENCE_TRANSFORMERS = False + class SentenceTransformersTokenTextSplitter(TextSplitter): """Splitting text to tokens using sentence model tokenizer.""" @@ -18,15 +27,13 @@ class SentenceTransformersTokenTextSplitter(TextSplitter): """Create a new TextSplitter.""" super().__init__(**kwargs, chunk_overlap=chunk_overlap) - try: - from sentence_transformers import SentenceTransformer - except ImportError as err: + if not _HAS_SENTENCE_TRANSFORMERS: msg = ( "Could not import sentence_transformers python package. " - "This is needed in order to for SentenceTransformersTokenTextSplitter. " + "This is needed in order to use SentenceTransformersTokenTextSplitter. " "Please install it with `pip install sentence-transformers`." ) - raise ImportError(msg) from err + raise ImportError(msg) self.model_name = model_name self._model = SentenceTransformer(self.model_name) diff --git a/libs/text-splitters/langchain_text_splitters/spacy.py b/libs/text-splitters/langchain_text_splitters/spacy.py index af7c8e3e25b..cfc6fa6eec3 100644 --- a/libs/text-splitters/langchain_text_splitters/spacy.py +++ b/libs/text-splitters/langchain_text_splitters/spacy.py @@ -1,9 +1,20 @@ +"""Spacy text splitter.""" + from __future__ import annotations from typing import Any from langchain_text_splitters.base import TextSplitter +try: + import spacy + from spacy.lang.en import English + from spacy.language import Language + + _HAS_SPACY = True +except ImportError: + _HAS_SPACY = False + class SpacyTextSplitter(TextSplitter): """Splitting text using Spacy package. @@ -42,16 +53,12 @@ class SpacyTextSplitter(TextSplitter): def _make_spacy_pipeline_for_splitting( pipeline: str, *, max_length: int = 1_000_000 -) -> Any: # avoid importing spacy - try: - import spacy - except ImportError as err: +) -> Language: + if not _HAS_SPACY: msg = "Spacy is not installed, please install it with `pip install spacy`." - raise ImportError(msg) from err + raise ImportError(msg) if pipeline == "sentencizer": - from spacy.lang.en import English - - sentencizer: Any = English() + sentencizer: Language = English() sentencizer.add_pipe("sentencizer") else: sentencizer = spacy.load(pipeline, exclude=["ner", "tagger"]) diff --git a/libs/text-splitters/pyproject.toml b/libs/text-splitters/pyproject.toml index 9d4dd95f39b..35ced364e4d 100644 --- a/libs/text-splitters/pyproject.toml +++ b/libs/text-splitters/pyproject.toml @@ -25,7 +25,8 @@ typing = [ "mypy<1.18,>=1.17.1", "lxml-stubs<1.0.0,>=0.5.1", "types-requests<3.0.0.0,>=2.31.0.20240218", - "tiktoken<1.0.0,>=0.8.0", + "tiktoken<1.0.0,>=0.11.0", + "beautifulsoup4<5.0.0,>=4.13.5", ] dev = ["jupyter<2.0.0,>=1.0.0", "langchain-core"] test = [ @@ -66,71 +67,46 @@ ignore_missing_imports = true target-version = "py39" [tool.ruff.lint] -select = [ - "A", # flake8-builtins - "B", # flake8-bugbear - "ASYNC", # flake8-async - "C4", # flake8-comprehensions - "COM", # flake8-commas - "D", # pydocstyle - "E", # pycodestyle error - "EM", # flake8-errmsg - "F", # pyflakes - "FA", # flake8-future-annotations - "FBT", # flake8-boolean-trap - "FLY", # flake8-flynt - "I", # isort - "ICN", # flake8-import-conventions - "INT", # flake8-gettext - "ISC", # isort-comprehensions - "PGH", # pygrep-hooks - "PIE", # flake8-pie - "PERF", # flake8-perf - "PYI", # flake8-pyi - "Q", # flake8-quotes - "RET", # flake8-return - "RSE", # flake8-rst-docstrings - "RUF", # ruff - "S", # flake8-bandit - "SLF", # flake8-self - "SLOT", # flake8-slots - "SIM", # flake8-simplify - "T10", # flake8-debugger - "T20", # flake8-print - "TID", # flake8-tidy-imports - "UP", # pyupgrade - "W", # pycodestyle warning - "YTT", # flake8-2020 -] +select = [ "ALL",] ignore = [ - "D100", # pydocstyle: Missing docstring in public module - "D101", # pydocstyle: Missing docstring in public class - "D102", # pydocstyle: Missing docstring in public method - "D103", # pydocstyle: Missing docstring in public function - "D104", # pydocstyle: Missing docstring in public package - "D105", # pydocstyle: Missing docstring in magic method - "D107", # pydocstyle: Missing docstring in __init__ - "D203", # Messes with the formatter - "D213", # pydocstyle: Multi-line docstring summary should start at the second line (incompatible with D212) - "D407", # pydocstyle: Missing-dashed-underline-after-section + "C90", # McCabe complexity "COM812", # Messes with the formatter + "FIX002", # Line contains TODO "ISC001", # Messes with the formatter "PERF203", # Rarely useful - "S112", # Rarely useful + "PLR09", # Too many something (arg, statements, etc) "RUF012", # Doesn't play well with Pydantic - "SLF001", # Private member access - "UP007", # pyupgrade: non-pep604-annotation-union - "UP045", # pyupgrade: non-pep604-annotation-optional + "TC001", # Doesn't play well with Pydantic + "TC002", # Doesn't play well with Pydantic + "TC003", # Doesn't play well with Pydantic + "TD002", # Missing author in TODO + "TD003", # Missing issue link in TODO ] -unfixable = ["B028"] # People should intentionally tune the stacklevel +unfixable = [ + "B028", # People should intentionally tune the stacklevel + "PLW1510", # People should intentionally set the check argument +] + +flake8-annotations.allow-star-arg-any = true +flake8-annotations.mypy-init-return = true +flake8-type-checking.runtime-evaluated-base-classes = ["pydantic.BaseModel","langchain_core.load.serializable.Serializable","langchain_core.runnables.base.RunnableSerializable"] +pep8-naming.classmethod-decorators = [ "classmethod", "langchain_core.utils.pydantic.pre_init", "pydantic.field_validator", "pydantic.v1.root_validator",] +pydocstyle.convention = "google" pyupgrade.keep-runtime-typing = true -[tool.ruff.lint.extend-per-file-ignores] -"tests/**/*.py" = [ - "S101", # Tests need assertions - "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes +[tool.ruff.lint.per-file-ignores] +"scripts/**" = [ + "D1", # Docstrings not mandatory in scripts + "INP001", # Not a package + "S311" # Standard pseudo-random generators are not suitable for cryptographic purposes +] +"tests/**" = [ + "D1", # Docstrings not mandatory in tests + "PLR2004", # Magic value comparisons + "S101", # Tests need assertions + "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes + "SLF001" # Private member access in tests ] - [tool.coverage.run] omit = ["tests/*"] @@ -142,9 +118,3 @@ markers = [ "compile: mark placeholder test used to compile integration tests without running them", ] asyncio_mode = "auto" - -[tool.ruff.lint.pydocstyle] -convention = "google" - -[tool.ruff.lint.per-file-ignores] -"tests/**" = ["D"] diff --git a/libs/text-splitters/scripts/check_imports.py b/libs/text-splitters/scripts/check_imports.py index 00069f9f95a..6242951b623 100644 --- a/libs/text-splitters/scripts/check_imports.py +++ b/libs/text-splitters/scripts/check_imports.py @@ -10,7 +10,7 @@ if __name__ == "__main__": try: module_name = f"test_module_{uuid.uuid4().hex[:20]}" SourceFileLoader(module_name, file).load_module() - except Exception: + except Exception: # noqa: BLE001 has_failure = True print(file) # noqa: T201 traceback.print_exc() diff --git a/libs/text-splitters/tests/integration_tests/test_nlp_text_splitters.py b/libs/text-splitters/tests/integration_tests/test_nlp_text_splitters.py index b4d6499f98b..82e55b0d9d4 100644 --- a/libs/text-splitters/tests/integration_tests/test_nlp_text_splitters.py +++ b/libs/text-splitters/tests/integration_tests/test_nlp_text_splitters.py @@ -1,6 +1,6 @@ """Test text splitting functionality using NLTK and Spacy based sentence splitters.""" -from typing import Any +import re import nltk import pytest @@ -15,11 +15,8 @@ def setup_module() -> None: @pytest.fixture -def spacy() -> Any: - try: - import spacy - except ImportError: - pytest.skip("Spacy not installed.") +def spacy() -> None: + spacy = pytest.importorskip("spacy") # Check if en_core_web_sm model is available try: @@ -32,18 +29,27 @@ def spacy() -> Any: "en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl" ) - return spacy - def test_nltk_text_splitting_args() -> None: """Test invalid arguments.""" - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match=re.escape( + "Got a larger chunk overlap (4) than chunk size (2), should be smaller." + ), + ): NLTKTextSplitter(chunk_size=2, chunk_overlap=4) -def test_spacy_text_splitting_args(spacy: Any) -> None: +@pytest.mark.usefixtures("spacy") +def test_spacy_text_splitting_args() -> None: """Test invalid arguments.""" - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match=re.escape( + "Got a larger chunk overlap (4) than chunk size (2), should be smaller." + ), + ): SpacyTextSplitter(chunk_size=2, chunk_overlap=4) @@ -57,8 +63,9 @@ def test_nltk_text_splitter() -> None: assert output == expected_output +@pytest.mark.usefixtures("spacy") @pytest.mark.parametrize("pipeline", ["sentencizer", "en_core_web_sm"]) -def test_spacy_text_splitter(pipeline: str, spacy: Any) -> None: +def test_spacy_text_splitter(pipeline: str) -> None: """Test splitting by sentence using Spacy.""" text = "This is sentence one. And this is sentence two." separator = "|||" @@ -68,8 +75,9 @@ def test_spacy_text_splitter(pipeline: str, spacy: Any) -> None: assert output == expected_output +@pytest.mark.usefixtures("spacy") @pytest.mark.parametrize("pipeline", ["sentencizer", "en_core_web_sm"]) -def test_spacy_text_splitter_strip_whitespace(pipeline: str, spacy: Any) -> None: +def test_spacy_text_splitter_strip_whitespace(pipeline: str) -> None: """Test splitting by sentence using Spacy.""" text = "This is sentence one. And this is sentence two." separator = "|||" @@ -83,7 +91,9 @@ def test_spacy_text_splitter_strip_whitespace(pipeline: str, spacy: Any) -> None def test_nltk_text_splitter_args() -> None: """Test invalid arguments for NLTKTextSplitter.""" - with pytest.raises(ValueError): + with pytest.raises( + ValueError, match="When use_span_tokenize is True, separator should be ''" + ): NLTKTextSplitter( chunk_size=80, chunk_overlap=0, diff --git a/libs/text-splitters/tests/integration_tests/test_text_splitter.py b/libs/text-splitters/tests/integration_tests/test_text_splitter.py index ad0549e2424..9ee11220113 100644 --- a/libs/text-splitters/tests/integration_tests/test_text_splitter.py +++ b/libs/text-splitters/tests/integration_tests/test_text_splitter.py @@ -1,8 +1,7 @@ """Test text splitters that require an integration.""" -from typing import Any - import pytest +from transformers import GPT2TokenizerFast from langchain_text_splitters import ( TokenTextSplitter, @@ -13,25 +12,17 @@ from langchain_text_splitters.sentence_transformers import ( ) -@pytest.fixture -def sentence_transformers() -> Any: - try: - import sentence_transformers - except ImportError: - pytest.skip("SentenceTransformers not installed.") - return sentence_transformers - - def test_huggingface_type_check() -> None: """Test that type checks are done properly on input.""" - with pytest.raises(ValueError): - CharacterTextSplitter.from_huggingface_tokenizer("foo") + with pytest.raises( + ValueError, + match="Tokenizer received was not an instance of PreTrainedTokenizerBase", + ): + CharacterTextSplitter.from_huggingface_tokenizer("foo") # type: ignore[arg-type] def test_huggingface_tokenizer() -> None: """Test text splitter that uses a HuggingFace tokenizer.""" - from transformers import GPT2TokenizerFast - tokenizer = GPT2TokenizerFast.from_pretrained("gpt2") text_splitter = CharacterTextSplitter.from_huggingface_tokenizer( tokenizer, separator=" ", chunk_size=1, chunk_overlap=0 @@ -63,7 +54,8 @@ def test_token_text_splitter_from_tiktoken() -> None: assert expected_tokenizer == actual_tokenizer -def test_sentence_transformers_count_tokens(sentence_transformers: Any) -> None: +@pytest.mark.requires("sentence_transformers") +def test_sentence_transformers_count_tokens() -> None: splitter = SentenceTransformersTokenTextSplitter( model_name="sentence-transformers/paraphrase-albert-small-v2" ) @@ -78,7 +70,8 @@ def test_sentence_transformers_count_tokens(sentence_transformers: Any) -> None: assert expected_token_count == token_count -def test_sentence_transformers_split_text(sentence_transformers: Any) -> None: +@pytest.mark.requires("sentence_transformers") +def test_sentence_transformers_split_text() -> None: splitter = SentenceTransformersTokenTextSplitter( model_name="sentence-transformers/paraphrase-albert-small-v2" ) @@ -88,7 +81,8 @@ def test_sentence_transformers_split_text(sentence_transformers: Any) -> None: assert expected_text_chunks == text_chunks -def test_sentence_transformers_multiple_tokens(sentence_transformers: Any) -> None: +@pytest.mark.requires("sentence_transformers") +def test_sentence_transformers_multiple_tokens() -> None: splitter = SentenceTransformersTokenTextSplitter(chunk_overlap=0) text = "Lorem " diff --git a/libs/text-splitters/tests/unit_tests/conftest.py b/libs/text-splitters/tests/unit_tests/conftest.py index ad5ea6273cb..d56ef0cedf7 100644 --- a/libs/text-splitters/tests/unit_tests/conftest.py +++ b/libs/text-splitters/tests/unit_tests/conftest.py @@ -4,10 +4,9 @@ from collections.abc import Sequence from importlib import util import pytest -from pytest import Config, Function, Parser -def pytest_addoption(parser: Parser) -> None: +def pytest_addoption(parser: pytest.Parser) -> None: """Add custom command line options to pytest.""" parser.addoption( "--only-extended", @@ -21,7 +20,9 @@ def pytest_addoption(parser: Parser) -> None: ) -def pytest_collection_modifyitems(config: Config, items: Sequence[Function]) -> None: +def pytest_collection_modifyitems( + config: pytest.Config, items: Sequence[pytest.Function] +) -> None: """Add implementations for handling custom markers. At the moment, this adds support for a custom `requires` marker. @@ -64,7 +65,7 @@ def pytest_collection_modifyitems(config: Config, items: Sequence[Function]) -> if pkg not in required_pkgs_info: try: installed = util.find_spec(pkg) is not None - except Exception: + except (ImportError, ValueError): installed = False required_pkgs_info[pkg] = installed diff --git a/libs/text-splitters/tests/unit_tests/test_text_splitters.py b/libs/text-splitters/tests/unit_tests/test_text_splitters.py index 5ecca3bdf71..c366af91709 100644 --- a/libs/text-splitters/tests/unit_tests/test_text_splitters.py +++ b/libs/text-splitters/tests/unit_tests/test_text_splitters.py @@ -1,11 +1,14 @@ """Test text splitting functionality.""" +from __future__ import annotations + import random import re import string from typing import Any, Callable import pytest +from bs4 import Tag from langchain_core.documents import Document from langchain_text_splitters import ( @@ -103,7 +106,9 @@ def test_character_text_splitter_longer_words() -> None: def test_character_text_splitter_keep_separator_regex( *, separator: str, is_separator_regex: bool ) -> None: - """Test splitting by characters while keeping the separator + """Test CharacterTextSplitter keep separator regex. + + Test splitting by characters while keeping the separator that is a regex special character. """ text = "foo.bar.baz.123" @@ -125,7 +130,9 @@ def test_character_text_splitter_keep_separator_regex( def test_character_text_splitter_keep_separator_regex_start( *, separator: str, is_separator_regex: bool ) -> None: - """Test splitting by characters while keeping the separator + """Test CharacterTextSplitter keep separator regex and put at start. + + Test splitting by characters while keeping the separator that is a regex special character and placing it at the start of each chunk. """ text = "foo.bar.baz.123" @@ -147,7 +154,9 @@ def test_character_text_splitter_keep_separator_regex_start( def test_character_text_splitter_keep_separator_regex_end( *, separator: str, is_separator_regex: bool ) -> None: - """Test splitting by characters while keeping the separator + """Test CharacterTextSplitter keep separator regex and put at end. + + Test splitting by characters while keeping the separator that is a regex special character and placing it at the end of each chunk. """ text = "foo.bar.baz.123" @@ -169,8 +178,11 @@ def test_character_text_splitter_keep_separator_regex_end( def test_character_text_splitter_discard_separator_regex( *, separator: str, is_separator_regex: bool ) -> None: - """Test splitting by characters discarding the separator - that is a regex special character.""" + """Test CharacterTextSplitter discard separator regex. + + Test splitting by characters discarding the separator + that is a regex special character. + """ text = "foo.bar.baz.123" splitter = CharacterTextSplitter( separator=separator, @@ -210,12 +222,17 @@ def test_recursive_character_text_splitter_keep_separators() -> None: def test_character_text_splitting_args() -> None: """Test invalid arguments.""" - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match=re.escape( + "Got a larger chunk overlap (4) than chunk size (2), should be smaller." + ), + ): CharacterTextSplitter(chunk_size=2, chunk_overlap=4) for invalid_size in (0, -1): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="chunk_size must be > 0, got"): CharacterTextSplitter(chunk_size=invalid_size) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="chunk_overlap must be >= 0, got -1"): CharacterTextSplitter(chunk_size=2, chunk_overlap=-1) @@ -1164,7 +1181,6 @@ def test_html_code_splitter() -> None: def test_md_header_text_splitter_1() -> None: """Test markdown splitter by header: Case 1.""" - markdown_document = ( "# Foo\n\n" " ## Bar\n\n" @@ -1235,7 +1251,6 @@ def test_md_header_text_splitter_2() -> None: def test_md_header_text_splitter_3() -> None: """Test markdown splitter by header: Case 3.""" - markdown_document = ( "# Foo\n\n" " ## Bar\n\n" @@ -1290,7 +1305,6 @@ def test_md_header_text_splitter_3() -> None: def test_md_header_text_splitter_preserve_headers_1() -> None: """Test markdown splitter by header: Preserve Headers.""" - markdown_document = ( "# Foo\n\n" " ## Bat\n\n" @@ -1324,7 +1338,6 @@ def test_md_header_text_splitter_preserve_headers_1() -> None: def test_md_header_text_splitter_preserve_headers_2() -> None: """Test markdown splitter by header: Preserve Headers.""" - markdown_document = ( "# Foo\n\n" " ## Bar\n\n" @@ -1372,7 +1385,6 @@ def test_md_header_text_splitter_preserve_headers_2() -> None: @pytest.mark.parametrize("fence", [("```"), ("~~~")]) def test_md_header_text_splitter_fenced_code_block(fence: str) -> None: """Test markdown splitter by header: Fenced code block.""" - markdown_document = ( f"# This is a Header\n\n{fence}\nfoo()\n# Not a header\nbar()\n{fence}" ) @@ -1402,7 +1414,6 @@ def test_md_header_text_splitter_fenced_code_block_interleaved( fence: str, other_fence: str ) -> None: """Test markdown splitter by header: Interleaved fenced code block.""" - markdown_document = ( "# This is a Header\n\n" f"{fence}\n" @@ -1438,7 +1449,6 @@ def test_md_header_text_splitter_fenced_code_block_interleaved( @pytest.mark.parametrize("characters", ["\ufeff"]) def test_md_header_text_splitter_with_invisible_characters(characters: str) -> None: """Test markdown splitter by header: Fenced code block.""" - markdown_document = f"{characters}# Foo\n\nfoo()\n{characters}## Bar\n\nbar()" headers_to_split_on = [ @@ -1609,7 +1619,6 @@ EXPERIMENTAL_MARKDOWN_DOCUMENT = ( def test_experimental_markdown_syntax_text_splitter() -> None: """Test experimental markdown syntax splitter.""" - markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter() output = markdown_splitter.split_text(EXPERIMENTAL_MARKDOWN_DOCUMENT) @@ -1663,7 +1672,6 @@ def test_experimental_markdown_syntax_text_splitter() -> None: def test_experimental_markdown_syntax_text_splitter_header_configuration() -> None: """Test experimental markdown syntax splitter.""" - headers_to_split_on = [("#", "Encabezamiento 1")] markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter( @@ -1709,7 +1717,6 @@ def test_experimental_markdown_syntax_text_splitter_header_configuration() -> No def test_experimental_markdown_syntax_text_splitter_with_headers() -> None: """Test experimental markdown syntax splitter.""" - markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter(strip_headers=False) output = markdown_splitter.split_text(EXPERIMENTAL_MARKDOWN_DOCUMENT) @@ -1768,7 +1775,6 @@ def test_experimental_markdown_syntax_text_splitter_with_headers() -> None: def test_experimental_markdown_syntax_text_splitter_split_lines() -> None: """Test experimental markdown syntax splitter.""" - markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter(return_each_line=True) output = markdown_splitter.split_text(EXPERIMENTAL_MARKDOWN_DOCUMENT) @@ -1876,8 +1882,11 @@ EXPERIMENTAL_MARKDOWN_DOCUMENTS = [ def test_experimental_markdown_syntax_text_splitter_on_multi_files() -> None: - """Test experimental markdown syntax splitter split - on default called consecutively on two files.""" + """Test ExperimentalMarkdownSyntaxTextSplitter on multiple files. + + Test experimental markdown syntax splitter split on default called consecutively + on two files. + """ markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter() output = [] for experimental_markdown_document in EXPERIMENTAL_MARKDOWN_DOCUMENTS: @@ -1958,8 +1967,11 @@ def test_experimental_markdown_syntax_text_splitter_on_multi_files() -> None: def test_experimental_markdown_syntax_text_splitter_split_lines_on_multi_files() -> ( None ): - """Test experimental markdown syntax splitter split - on each line called consecutively on two files.""" + """Test ExperimentalMarkdownSyntaxTextSplitter split lines on multiple files. + + Test experimental markdown syntax splitter split on each line called consecutively + on two files. + """ markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter(return_each_line=True) output = [] for experimental_markdown_document in EXPERIMENTAL_MARKDOWN_DOCUMENTS: @@ -2083,9 +2095,10 @@ def test_experimental_markdown_syntax_text_splitter_split_lines_on_multi_files() def test_experimental_markdown_syntax_text_splitter_with_header_on_multi_files() -> ( None ): - """Test experimental markdown splitter - by header called consecutively on two files""" + """Test ExperimentalMarkdownSyntaxTextSplitter with header on multiple files. + Test experimental markdown splitter by header called consecutively on two files. + """ markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter(strip_headers=False) output = [] for experimental_markdown_document in EXPERIMENTAL_MARKDOWN_DOCUMENTS: @@ -2171,9 +2184,11 @@ def test_experimental_markdown_syntax_text_splitter_with_header_on_multi_files() def test_experimental_markdown_syntax_text_splitter_header_config_on_multi_files() -> ( None ): - """Test experimental markdown splitter - by header configuration called consecutively on two files""" + """Test ExperimentalMarkdownSyntaxTextSplitter header config on multiple files. + Test experimental markdown splitter by header configuration called consecutively + on two files. + """ headers_to_split_on = [("#", "Encabezamiento 1")] markdown_splitter = ExperimentalMarkdownSyntaxTextSplitter( headers_to_split_on=headers_to_split_on @@ -2354,8 +2369,8 @@ def test_haskell_code_splitter() -> None: def html_header_splitter_splitter_factory() -> Callable[ [list[tuple[str, str]]], HTMLHeaderTextSplitter ]: - """ - Fixture to create an HTMLHeaderTextSplitter instance with given headers. + """Fixture to create an HTMLHeaderTextSplitter instance with given headers. + This factory allows dynamic creation of splitters with different headers. """ @@ -2553,14 +2568,15 @@ def html_header_splitter_splitter_factory() -> Callable[ ) @pytest.mark.requires("bs4") def test_html_header_text_splitter( - html_header_splitter_splitter_factory: Any, + html_header_splitter_splitter_factory: Callable[ + [list[tuple[str, str]]], HTMLHeaderTextSplitter + ], headers_to_split_on: list[tuple[str, str]], html_input: str, expected_documents: list[Document], test_case: str, ) -> None: - """ - Test the HTML header text splitter. + """Test the HTML header text splitter. Args: html_header_splitter_splitter_factory (Any): Factory function to create @@ -2574,10 +2590,7 @@ def test_html_header_text_splitter( AssertionError: If the number of documents or their content/metadata does not match the expected values. """ - - splitter = html_header_splitter_splitter_factory( - headers_to_split_on=headers_to_split_on - ) + splitter = html_header_splitter_splitter_factory(headers_to_split_on) docs = splitter.split_text(html_input) assert len(docs) == len(expected_documents), ( @@ -2709,14 +2722,15 @@ def test_html_header_text_splitter( ) @pytest.mark.requires("bs4") def test_additional_html_header_text_splitter( - html_header_splitter_splitter_factory: Any, + html_header_splitter_splitter_factory: Callable[ + [list[tuple[str, str]]], HTMLHeaderTextSplitter + ], headers_to_split_on: list[tuple[str, str]], html_content: str, expected_output: list[Document], test_case: str, ) -> None: - """ - Test the HTML header text splitter. + """Test the HTML header text splitter. Args: html_header_splitter_splitter_factory (Any): Factory function to create @@ -2730,9 +2744,7 @@ def test_additional_html_header_text_splitter( AssertionError: If the number of documents or their content/metadata does not match the expected output. """ - splitter = html_header_splitter_splitter_factory( - headers_to_split_on=headers_to_split_on - ) + splitter = html_header_splitter_splitter_factory(headers_to_split_on) docs = splitter.split_text(html_content) assert len(docs) == len(expected_output), ( @@ -2780,14 +2792,16 @@ def test_additional_html_header_text_splitter( ) @pytest.mark.requires("bs4") def test_html_no_headers_with_multiple_splitters( - html_header_splitter_splitter_factory: Any, + html_header_splitter_splitter_factory: Callable[ + [list[tuple[str, str]]], HTMLHeaderTextSplitter + ], headers_to_split_on: list[tuple[str, str]], html_content: str, expected_output: list[Document], test_case: str, ) -> None: - """ - Test HTML content splitting without headers using multiple splitters. + """Test HTML content splitting without headers using multiple splitters. + Args: html_header_splitter_splitter_factory (Any): Factory to create the HTML header splitter. @@ -2796,13 +2810,12 @@ def test_html_no_headers_with_multiple_splitters( expected_output (List[Document]): Expected list of Document objects after splitting. test_case (str): Description of the test case. + Raises: AssertionError: If the number of documents or their content/metadata does not match the expected output. """ - splitter = html_header_splitter_splitter_factory( - headers_to_split_on=headers_to_split_on - ) + splitter = html_header_splitter_splitter_factory(headers_to_split_on) docs = splitter.split_text(html_content) assert len(docs) == len(expected_output), ( @@ -3046,7 +3059,7 @@ def test_happy_path_splitting_with_duplicate_header_tag() -> None: def test_split_json() -> None: - """Test json text splitter""" + """Test json text splitter.""" max_chunk = 800 splitter = RecursiveJsonSplitter(max_chunk_size=max_chunk) @@ -3068,7 +3081,7 @@ def test_split_json() -> None: def test_split_json_with_lists() -> None: - """Test json text splitter with list conversion""" + """Test json text splitter with list conversion.""" max_chunk = 800 splitter = RecursiveJsonSplitter(max_chunk_size=max_chunk) @@ -3240,7 +3253,7 @@ def test_visualbasic6_code_splitter() -> None: ] -def custom_iframe_extractor(iframe_tag: Any) -> str: +def custom_iframe_extractor(iframe_tag: Tag) -> str: iframe_src = iframe_tag.get("src", "") return f"[iframe:{iframe_src}]({iframe_src})" @@ -3324,8 +3337,11 @@ def test_html_splitter_with_nested_elements() -> None: @pytest.mark.requires("bs4") def test_html_splitter_with_preserved_elements() -> None: - """Test HTML splitting with preserved elements like ,
    with low chunk - size.""" + """Test HTML splitter with preserved elements. + + Test HTML splitting with preserved elements like
,
    with low chunk + size. + """ html_content = """

    Section 1

@@ -3563,8 +3579,11 @@ def test_html_splitter_with_no_headers() -> None: @pytest.mark.requires("bs4") def test_html_splitter_with_media_preservation() -> None: - """Test HTML splitting with media elements preserved and converted to Markdown-like - links.""" + """Test HTML splitter with media preservation. + + Test HTML splitting with media elements preserved and converted to Markdown-like + links. + """ html_content = """

Section 1

This is an image:

@@ -3600,7 +3619,7 @@ def test_html_splitter_with_media_preservation() -> None: @pytest.mark.requires("bs4") def test_html_splitter_keep_separator_true() -> None: - """Test HTML splitting with keep_separator=True""" + """Test HTML splitting with keep_separator=True.""" html_content = """

Section 1

This is some text. This is some other text.

@@ -3629,7 +3648,7 @@ def test_html_splitter_keep_separator_true() -> None: @pytest.mark.requires("bs4") def test_html_splitter_keep_separator_false() -> None: - """Test HTML splitting with keep_separator=False""" + """Test HTML splitting with keep_separator=False.""" html_content = """

Section 1

This is some text. This is some other text.

@@ -3658,7 +3677,7 @@ def test_html_splitter_keep_separator_false() -> None: @pytest.mark.requires("bs4") def test_html_splitter_keep_separator_start() -> None: - """Test HTML splitting with keep_separator="start" """ + """Test HTML splitting with keep_separator="start".""" html_content = """

Section 1

This is some text. This is some other text.

@@ -3687,7 +3706,7 @@ def test_html_splitter_keep_separator_start() -> None: @pytest.mark.requires("bs4") def test_html_splitter_keep_separator_end() -> None: - """Test HTML splitting with keep_separator="end" """ + """Test HTML splitting with keep_separator="end".""" html_content = """

Section 1

This is some text. This is some other text.

@@ -3716,7 +3735,7 @@ def test_html_splitter_keep_separator_end() -> None: @pytest.mark.requires("bs4") def test_html_splitter_keep_separator_default() -> None: - """Test HTML splitting with keep_separator not set""" + """Test HTML splitting with keep_separator not set.""" html_content = """

Section 1

This is some text. This is some other text.

diff --git a/libs/text-splitters/uv.lock b/libs/text-splitters/uv.lock index b5f8882b310..bf549a5ad20 100644 --- a/libs/text-splitters/uv.lock +++ b/libs/text-splitters/uv.lock @@ -129,15 +129,15 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.13.1" +version = "4.13.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/f3/d90227cc52f7b8fcd0f2af804f56e55edf8dd07036b681a2809e3245318b/beautifulsoup4-4.13.1.tar.gz", hash = "sha256:741c8b6903a1e4ae8ba32b9c9ae7510dab7a197fdbadcf9fcdeb0891ef5ec66a", size = 618295, upload-time = "2025-02-03T12:15:13.622Z" } +sdist = { url = "https://files.pythonhosted.org/packages/85/2e/3e5079847e653b1f6dc647aa24549d68c6addb4c595cc0d902d1b19308ad/beautifulsoup4-4.13.5.tar.gz", hash = "sha256:5e70131382930e7c3de33450a2f54a63d5e4b19386eab43a5b34d594268f3695", size = 622954, upload-time = "2025-08-24T14:06:13.168Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/75/899bf9b6270b2ce5e8f01b8da121b29e4b88256feb2cf6c6418d4cc42130/beautifulsoup4-4.13.1-py3-none-any.whl", hash = "sha256:72465267014897bb10ca749bb632bde6c2d20f3254afd5458544bd74e6c2e6d8", size = 185056, upload-time = "2025-02-03T12:15:12.076Z" }, + { url = "https://files.pythonhosted.org/packages/04/eb/f4151e0c7377a6e08a38108609ba5cede57986802757848688aeedd1b9e8/beautifulsoup4-4.13.5-py3-none-any.whl", hash = "sha256:642085eaa22233aceadff9c69651bc51e8bf3f874fb6d7104ece2beb24b47c4a", size = 105113, upload-time = "2025-08-24T14:06:14.884Z" }, ] [[package]] @@ -1191,6 +1191,7 @@ test-integration = [ { name = "transformers" }, ] typing = [ + { name = "beautifulsoup4" }, { name = "lxml-stubs" }, { name = "mypy" }, { name = "tiktoken" }, @@ -1229,9 +1230,10 @@ test-integration = [ { name = "transformers", specifier = ">=4.51.3,<5.0.0" }, ] typing = [ + { name = "beautifulsoup4", specifier = ">=4.13.5,<5.0.0" }, { name = "lxml-stubs", specifier = ">=0.5.1,<1.0.0" }, { name = "mypy", specifier = ">=1.17.1,<1.18" }, - { name = "tiktoken", specifier = ">=0.8.0,<1.0.0" }, + { name = "tiktoken", specifier = ">=0.11.0,<1.0.0" }, { name = "types-requests", specifier = ">=2.31.0.20240218,<3.0.0.0" }, ] @@ -3464,44 +3466,44 @@ wheels = [ [[package]] name = "tiktoken" -version = "0.8.0" +version = "0.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "regex" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/37/02/576ff3a6639e755c4f70997b2d315f56d6d71e0d046f4fb64cb81a3fb099/tiktoken-0.8.0.tar.gz", hash = "sha256:9ccbb2740f24542534369c5635cfd9b2b3c2490754a78ac8831d99f89f94eeb2", size = 35107, upload-time = "2024-10-03T22:44:04.196Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/86/ad0155a37c4f310935d5ac0b1ccf9bdb635dcb906e0a9a26b616dd55825a/tiktoken-0.11.0.tar.gz", hash = "sha256:3c518641aee1c52247c2b97e74d8d07d780092af79d5911a6ab5e79359d9b06a", size = 37648, upload-time = "2025-08-08T23:58:08.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/ba/a35fad753bbca8ba0cc1b0f3402a70256a110ced7ac332cf84ba89fc87ab/tiktoken-0.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b07e33283463089c81ef1467180e3e00ab00d46c2c4bbcef0acab5f771d6695e", size = 1039905, upload-time = "2024-10-03T22:43:17.292Z" }, - { url = "https://files.pythonhosted.org/packages/91/05/13dab8fd7460391c387b3e69e14bf1e51ff71fe0a202cd2933cc3ea93fb6/tiktoken-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9269348cb650726f44dd3bbb3f9110ac19a8dcc8f54949ad3ef652ca22a38e21", size = 982417, upload-time = "2024-10-03T22:43:19.437Z" }, - { url = "https://files.pythonhosted.org/packages/e9/98/18ec4a8351a6cf4537e40cd6e19a422c10cce1ef00a2fcb716e0a96af58b/tiktoken-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e13f37bc4ef2d012731e93e0fef21dc3b7aea5bb9009618de9a4026844e560", size = 1144915, upload-time = "2024-10-03T22:43:21.385Z" }, - { url = "https://files.pythonhosted.org/packages/2e/28/cf3633018cbcc6deb7805b700ccd6085c9a5a7f72b38974ee0bffd56d311/tiktoken-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f13d13c981511331eac0d01a59b5df7c0d4060a8be1e378672822213da51e0a2", size = 1177221, upload-time = "2024-10-03T22:43:23.325Z" }, - { url = "https://files.pythonhosted.org/packages/57/81/8a5be305cbd39d4e83a794f9e80c7f2c84b524587b7feb27c797b2046d51/tiktoken-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6b2ddbc79a22621ce8b1166afa9f9a888a664a579350dc7c09346a3b5de837d9", size = 1237398, upload-time = "2024-10-03T22:43:24.71Z" }, - { url = "https://files.pythonhosted.org/packages/dc/da/8d1cc3089a83f5cf11c2e489332752981435280285231924557350523a59/tiktoken-0.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d8c2d0e5ba6453a290b86cd65fc51fedf247e1ba170191715b049dac1f628005", size = 884215, upload-time = "2024-10-03T22:43:26.793Z" }, - { url = "https://files.pythonhosted.org/packages/f6/1e/ca48e7bfeeccaf76f3a501bd84db1fa28b3c22c9d1a1f41af9fb7579c5f6/tiktoken-0.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d622d8011e6d6f239297efa42a2657043aaed06c4f68833550cac9e9bc723ef1", size = 1039700, upload-time = "2024-10-03T22:43:28.315Z" }, - { url = "https://files.pythonhosted.org/packages/8c/f8/f0101d98d661b34534769c3818f5af631e59c36ac6d07268fbfc89e539ce/tiktoken-0.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2efaf6199717b4485031b4d6edb94075e4d79177a172f38dd934d911b588d54a", size = 982413, upload-time = "2024-10-03T22:43:29.807Z" }, - { url = "https://files.pythonhosted.org/packages/ac/3c/2b95391d9bd520a73830469f80a96e3790e6c0a5ac2444f80f20b4b31051/tiktoken-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5637e425ce1fc49cf716d88df3092048359a4b3bbb7da762840426e937ada06d", size = 1144242, upload-time = "2024-10-04T04:42:53.66Z" }, - { url = "https://files.pythonhosted.org/packages/01/c4/c4a4360de845217b6aa9709c15773484b50479f36bb50419c443204e5de9/tiktoken-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fb0e352d1dbe15aba082883058b3cce9e48d33101bdaac1eccf66424feb5b47", size = 1176588, upload-time = "2024-10-03T22:43:31.136Z" }, - { url = "https://files.pythonhosted.org/packages/f8/a3/ef984e976822cd6c2227c854f74d2e60cf4cd6fbfca46251199914746f78/tiktoken-0.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:56edfefe896c8f10aba372ab5706b9e3558e78db39dd497c940b47bf228bc419", size = 1237261, upload-time = "2024-10-03T22:43:32.75Z" }, - { url = "https://files.pythonhosted.org/packages/1e/86/eea2309dc258fb86c7d9b10db536434fc16420feaa3b6113df18b23db7c2/tiktoken-0.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:326624128590def898775b722ccc327e90b073714227175ea8febbc920ac0a99", size = 884537, upload-time = "2024-10-03T22:43:34.592Z" }, - { url = "https://files.pythonhosted.org/packages/c1/22/34b2e136a6f4af186b6640cbfd6f93400783c9ef6cd550d9eab80628d9de/tiktoken-0.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:881839cfeae051b3628d9823b2e56b5cc93a9e2efb435f4cf15f17dc45f21586", size = 1039357, upload-time = "2024-10-03T22:43:36.362Z" }, - { url = "https://files.pythonhosted.org/packages/04/d2/c793cf49c20f5855fd6ce05d080c0537d7418f22c58e71f392d5e8c8dbf7/tiktoken-0.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fe9399bdc3f29d428f16a2f86c3c8ec20be3eac5f53693ce4980371c3245729b", size = 982616, upload-time = "2024-10-03T22:43:37.658Z" }, - { url = "https://files.pythonhosted.org/packages/b3/a1/79846e5ef911cd5d75c844de3fa496a10c91b4b5f550aad695c5df153d72/tiktoken-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a58deb7075d5b69237a3ff4bb51a726670419db6ea62bdcd8bd80c78497d7ab", size = 1144011, upload-time = "2024-10-03T22:43:39.092Z" }, - { url = "https://files.pythonhosted.org/packages/26/32/e0e3a859136e95c85a572e4806dc58bf1ddf651108ae8b97d5f3ebe1a244/tiktoken-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2908c0d043a7d03ebd80347266b0e58440bdef5564f84f4d29fb235b5df3b04", size = 1175432, upload-time = "2024-10-03T22:43:40.323Z" }, - { url = "https://files.pythonhosted.org/packages/c7/89/926b66e9025b97e9fbabeaa59048a736fe3c3e4530a204109571104f921c/tiktoken-0.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:294440d21a2a51e12d4238e68a5972095534fe9878be57d905c476017bff99fc", size = 1236576, upload-time = "2024-10-03T22:43:41.516Z" }, - { url = "https://files.pythonhosted.org/packages/45/e2/39d4aa02a52bba73b2cd21ba4533c84425ff8786cc63c511d68c8897376e/tiktoken-0.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:d8f3192733ac4d77977432947d563d7e1b310b96497acd3c196c9bddb36ed9db", size = 883824, upload-time = "2024-10-03T22:43:43.33Z" }, - { url = "https://files.pythonhosted.org/packages/e3/38/802e79ba0ee5fcbf240cd624143f57744e5d411d2e9d9ad2db70d8395986/tiktoken-0.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:02be1666096aff7da6cbd7cdaa8e7917bfed3467cd64b38b1f112e96d3b06a24", size = 1039648, upload-time = "2024-10-03T22:43:45.22Z" }, - { url = "https://files.pythonhosted.org/packages/b1/da/24cdbfc302c98663fbea66f5866f7fa1048405c7564ab88483aea97c3b1a/tiktoken-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94ff53c5c74b535b2cbf431d907fc13c678bbd009ee633a2aca269a04389f9a", size = 982763, upload-time = "2024-10-03T22:43:46.571Z" }, - { url = "https://files.pythonhosted.org/packages/e4/f0/0ecf79a279dfa41fc97d00adccf976ecc2556d3c08ef3e25e45eb31f665b/tiktoken-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b231f5e8982c245ee3065cd84a4712d64692348bc609d84467c57b4b72dcbc5", size = 1144417, upload-time = "2024-10-03T22:43:48.633Z" }, - { url = "https://files.pythonhosted.org/packages/ab/d3/155d2d4514f3471a25dc1d6d20549ef254e2aa9bb5b1060809b1d3b03d3a/tiktoken-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4177faa809bd55f699e88c96d9bb4635d22e3f59d635ba6fd9ffedf7150b9953", size = 1175108, upload-time = "2024-10-03T22:43:50.568Z" }, - { url = "https://files.pythonhosted.org/packages/19/eb/5989e16821ee8300ef8ee13c16effc20dfc26c777d05fbb6825e3c037b81/tiktoken-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5376b6f8dc4753cd81ead935c5f518fa0fbe7e133d9e25f648d8c4dabdd4bad7", size = 1236520, upload-time = "2024-10-03T22:43:51.759Z" }, - { url = "https://files.pythonhosted.org/packages/40/59/14b20465f1d1cb89cfbc96ec27e5617b2d41c79da12b5e04e96d689be2a7/tiktoken-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:18228d624807d66c87acd8f25fc135665617cab220671eb65b50f5d70fa51f69", size = 883849, upload-time = "2024-10-03T22:43:53.999Z" }, - { url = "https://files.pythonhosted.org/packages/08/f3/8a8ba9329e6b426d822c974d58fc6477f3f7b3b8deef651813d275cbe75f/tiktoken-0.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17807445f0cf1f25771c9d86496bd8b5c376f7419912519699f3cc4dc5c12e", size = 1040915, upload-time = "2024-10-03T22:43:55.177Z" }, - { url = "https://files.pythonhosted.org/packages/42/7a/914bd98100449422778f9222d00b3a4ee654211c40784e57541fa46311ab/tiktoken-0.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:886f80bd339578bbdba6ed6d0567a0d5c6cfe198d9e587ba6c447654c65b8edc", size = 983753, upload-time = "2024-10-03T22:43:56.303Z" }, - { url = "https://files.pythonhosted.org/packages/f7/01/1483856d84827c5fe541cb160f07914c6b063b8d961146e9c3557c4730c0/tiktoken-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6adc8323016d7758d6de7313527f755b0fc6c72985b7d9291be5d96d73ecd1e1", size = 1145913, upload-time = "2024-10-03T22:43:58.682Z" }, - { url = "https://files.pythonhosted.org/packages/c2/e1/6c7a772e0200131e960e3381f1d7b26406bc5612c70677989c1498af2a60/tiktoken-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b591fb2b30d6a72121a80be24ec7a0e9eb51c5500ddc7e4c2496516dd5e3816b", size = 1178505, upload-time = "2024-10-03T22:43:59.86Z" }, - { url = "https://files.pythonhosted.org/packages/3e/6b/3ae00f0bff5d0b6925bf6370cf0ff606f56daed76210c2b0a156017b78dc/tiktoken-0.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:845287b9798e476b4d762c3ebda5102be87ca26e5d2c9854002825d60cdb815d", size = 1239111, upload-time = "2024-10-03T22:44:01.094Z" }, - { url = "https://files.pythonhosted.org/packages/d5/3b/7c8812952ca55e1bab08afc1dda3c5991804c71b550b9402e82a082ab795/tiktoken-0.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:1473cfe584252dc3fa62adceb5b1c763c1874e04511b197da4e6de51d6ce5a02", size = 884803, upload-time = "2024-10-03T22:44:03.079Z" }, + { url = "https://files.pythonhosted.org/packages/8b/4d/c6a2e7dca2b4f2e9e0bfd62b3fe4f114322e2c028cfba905a72bc76ce479/tiktoken-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:8a9b517d6331d7103f8bef29ef93b3cca95fa766e293147fe7bacddf310d5917", size = 1059937, upload-time = "2025-08-08T23:57:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/41/54/3739d35b9f94cb8dc7b0db2edca7192d5571606aa2369a664fa27e811804/tiktoken-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b4ddb1849e6bf0afa6cc1c5d809fb980ca240a5fffe585a04e119519758788c0", size = 999230, upload-time = "2025-08-08T23:57:30.241Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f4/ec8d43338d28d53513004ebf4cd83732a135d11011433c58bf045890cc10/tiktoken-0.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10331d08b5ecf7a780b4fe4d0281328b23ab22cdb4ff65e68d56caeda9940ecc", size = 1130076, upload-time = "2025-08-08T23:57:31.706Z" }, + { url = "https://files.pythonhosted.org/packages/94/80/fb0ada0a882cb453caf519a4bf0d117c2a3ee2e852c88775abff5413c176/tiktoken-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b062c82300341dc87e0258c69f79bed725f87e753c21887aea90d272816be882", size = 1183942, upload-time = "2025-08-08T23:57:33.142Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e9/6c104355b463601719582823f3ea658bc3aa7c73d1b3b7553ebdc48468ce/tiktoken-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:195d84bec46169af3b1349a1495c151d37a0ff4cba73fd08282736be7f92cc6c", size = 1244705, upload-time = "2025-08-08T23:57:34.594Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/eaa6068f47e8b3f0aab9e05177cce2cf5aa2cc0ca93981792e620d4d4117/tiktoken-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe91581b0ecdd8783ce8cb6e3178f2260a3912e8724d2f2d49552b98714641a1", size = 884152, upload-time = "2025-08-08T23:57:36.18Z" }, + { url = "https://files.pythonhosted.org/packages/8a/91/912b459799a025d2842566fe1e902f7f50d54a1ce8a0f236ab36b5bd5846/tiktoken-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ae374c46afadad0f501046db3da1b36cd4dfbfa52af23c998773682446097cf", size = 1059743, upload-time = "2025-08-08T23:57:37.516Z" }, + { url = "https://files.pythonhosted.org/packages/8c/e9/6faa6870489ce64f5f75dcf91512bf35af5864583aee8fcb0dcb593121f5/tiktoken-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25a512ff25dc6c85b58f5dd4f3d8c674dc05f96b02d66cdacf628d26a4e4866b", size = 999334, upload-time = "2025-08-08T23:57:38.595Z" }, + { url = "https://files.pythonhosted.org/packages/a1/3e/a05d1547cf7db9dc75d1461cfa7b556a3b48e0516ec29dfc81d984a145f6/tiktoken-0.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2130127471e293d385179c1f3f9cd445070c0772be73cdafb7cec9a3684c0458", size = 1129402, upload-time = "2025-08-08T23:57:39.627Z" }, + { url = "https://files.pythonhosted.org/packages/34/9a/db7a86b829e05a01fd4daa492086f708e0a8b53952e1dbc9d380d2b03677/tiktoken-0.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e43022bf2c33f733ea9b54f6a3f6b4354b909f5a73388fb1b9347ca54a069c", size = 1184046, upload-time = "2025-08-08T23:57:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/9d/bb/52edc8e078cf062ed749248f1454e9e5cfd09979baadb830b3940e522015/tiktoken-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:adb4e308eb64380dc70fa30493e21c93475eaa11669dea313b6bbf8210bfd013", size = 1244691, upload-time = "2025-08-08T23:57:42.251Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/884b6cd7ae2570ecdcaffa02b528522b18fef1cbbfdbcaa73799807d0d3b/tiktoken-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ece6b76bfeeb61a125c44bbefdfccc279b5288e6007fbedc0d32bfec602df2f2", size = 884392, upload-time = "2025-08-08T23:57:43.628Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9e/eceddeffc169fc75fe0fd4f38471309f11cb1906f9b8aa39be4f5817df65/tiktoken-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fd9e6b23e860973cf9526544e220b223c60badf5b62e80a33509d6d40e6c8f5d", size = 1055199, upload-time = "2025-08-08T23:57:45.076Z" }, + { url = "https://files.pythonhosted.org/packages/4f/cf/5f02bfefffdc6b54e5094d2897bc80efd43050e5b09b576fd85936ee54bf/tiktoken-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a76d53cee2da71ee2731c9caa747398762bda19d7f92665e882fef229cb0b5b", size = 996655, upload-time = "2025-08-08T23:57:46.304Z" }, + { url = "https://files.pythonhosted.org/packages/65/8e/c769b45ef379bc360c9978c4f6914c79fd432400a6733a8afc7ed7b0726a/tiktoken-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ef72aab3ea240646e642413cb363b73869fed4e604dcfd69eec63dc54d603e8", size = 1128867, upload-time = "2025-08-08T23:57:47.438Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2d/4d77f6feb9292bfdd23d5813e442b3bba883f42d0ac78ef5fdc56873f756/tiktoken-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f929255c705efec7a28bf515e29dc74220b2f07544a8c81b8d69e8efc4578bd", size = 1183308, upload-time = "2025-08-08T23:57:48.566Z" }, + { url = "https://files.pythonhosted.org/packages/7a/65/7ff0a65d3bb0fc5a1fb6cc71b03e0f6e71a68c5eea230d1ff1ba3fd6df49/tiktoken-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61f1d15822e4404953d499fd1dcc62817a12ae9fb1e4898033ec8fe3915fdf8e", size = 1244301, upload-time = "2025-08-08T23:57:49.642Z" }, + { url = "https://files.pythonhosted.org/packages/f5/6e/5b71578799b72e5bdcef206a214c3ce860d999d579a3b56e74a6c8989ee2/tiktoken-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:45927a71ab6643dfd3ef57d515a5db3d199137adf551f66453be098502838b0f", size = 884282, upload-time = "2025-08-08T23:57:50.759Z" }, + { url = "https://files.pythonhosted.org/packages/cc/cd/a9034bcee638716d9310443818d73c6387a6a96db93cbcb0819b77f5b206/tiktoken-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a5f3f25ffb152ee7fec78e90a5e5ea5b03b4ea240beed03305615847f7a6ace2", size = 1055339, upload-time = "2025-08-08T23:57:51.802Z" }, + { url = "https://files.pythonhosted.org/packages/f1/91/9922b345f611b4e92581f234e64e9661e1c524875c8eadd513c4b2088472/tiktoken-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dc6e9ad16a2a75b4c4be7208055a1f707c9510541d94d9cc31f7fbdc8db41d8", size = 997080, upload-time = "2025-08-08T23:57:53.442Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9d/49cd047c71336bc4b4af460ac213ec1c457da67712bde59b892e84f1859f/tiktoken-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a0517634d67a8a48fd4a4ad73930c3022629a85a217d256a6e9b8b47439d1e4", size = 1128501, upload-time = "2025-08-08T23:57:54.808Z" }, + { url = "https://files.pythonhosted.org/packages/52/d5/a0dcdb40dd2ea357e83cb36258967f0ae96f5dd40c722d6e382ceee6bba9/tiktoken-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fb4effe60574675118b73c6fbfd3b5868e5d7a1f570d6cc0d18724b09ecf318", size = 1182743, upload-time = "2025-08-08T23:57:56.307Z" }, + { url = "https://files.pythonhosted.org/packages/3b/17/a0fc51aefb66b7b5261ca1314afa83df0106b033f783f9a7bcbe8e741494/tiktoken-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94f984c9831fd32688aef4348803b0905d4ae9c432303087bae370dc1381a2b8", size = 1244057, upload-time = "2025-08-08T23:57:57.628Z" }, + { url = "https://files.pythonhosted.org/packages/50/79/bcf350609f3a10f09fe4fc207f132085e497fdd3612f3925ab24d86a0ca0/tiktoken-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2177ffda31dec4023356a441793fed82f7af5291120751dee4d696414f54db0c", size = 883901, upload-time = "2025-08-08T23:57:59.359Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b6/81c5799ab77a9580c6d840cf77d4717e929193a42190fd623a080c647aa6/tiktoken-0.11.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:13220f12c9e82e399377e768640ddfe28bea962739cc3a869cad98f42c419a89", size = 1061648, upload-time = "2025-08-08T23:58:00.753Z" }, + { url = "https://files.pythonhosted.org/packages/50/89/faa668066b2a4640534ef5797c09ecd0a48b43367502129b217339dfaa97/tiktoken-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f2db627f5c74477c0404b4089fd8a28ae22fa982a6f7d9c7d4c305c375218f3", size = 1000950, upload-time = "2025-08-08T23:58:01.855Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/5f950528b54cb3025af4bc3522c23dbfb691afe8ffb292aa1e8dc2e6bddf/tiktoken-0.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2302772f035dceb2bcf8e55a735e4604a0b51a6dd50f38218ff664d46ec43807", size = 1130777, upload-time = "2025-08-08T23:58:03.256Z" }, + { url = "https://files.pythonhosted.org/packages/27/a4/e82ddf0773835ba24536ac8c0dce561e697698ec020a93212a1e041d39b4/tiktoken-0.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b977989afe44c94bcc50db1f76971bb26dca44218bd203ba95925ef56f8e7a", size = 1185692, upload-time = "2025-08-08T23:58:04.476Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c2/06361e41d176e62797ae65fa678111cdd30553321cf4d83e7b84107ea95f/tiktoken-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:669a1aa1ad6ebf1b3c26b45deb346f345da7680f845b5ea700bba45c20dea24c", size = 1246518, upload-time = "2025-08-08T23:58:06.126Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ad/ca37e15c46741ebb3904d562d03194e845539a08f7751a6df0f391757312/tiktoken-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:e363f33c720a055586f730c00e330df4c7ea0024bf1c83a8a9a9dbc054c4f304", size = 884702, upload-time = "2025-08-08T23:58:07.534Z" }, ] [[package]] From 323729915abb4b95eda953b08612769566b30acf Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 16:50:38 +0200 Subject: [PATCH 21/30] chore(standard-tests): add mypy strict checking (#32384) Co-authored-by: Mason Daugherty --- .../langchain_tests/conftest.py | 4 +- .../integration_tests/chat_models.py | 26 +- .../integration_tests/vectorstores.py | 2 +- .../langchain_tests/unit_tests/chat_models.py | 4 +- libs/standard-tests/pyproject.toml | 22 +- libs/standard-tests/uv.lock | 2141 +++++++++-------- 6 files changed, 1107 insertions(+), 1092 deletions(-) diff --git a/libs/standard-tests/langchain_tests/conftest.py b/libs/standard-tests/langchain_tests/conftest.py index b1674bc963d..fb441f65f36 100644 --- a/libs/standard-tests/langchain_tests/conftest.py +++ b/libs/standard-tests/langchain_tests/conftest.py @@ -3,7 +3,7 @@ import gzip from os import PathLike from pathlib import Path -from typing import Union +from typing import Any, Union import pytest import yaml @@ -36,7 +36,7 @@ class CustomSerializer: def deserialize(data: bytes) -> dict: """Decompress data and convert it from YAML.""" text = gzip.decompress(data).decode("utf-8") - cassette = yaml.safe_load(text) + cassette: dict[str, Any] = yaml.safe_load(text) cassette["requests"] = [ Request._from_dict(request) for request in cassette["requests"] ] diff --git a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py index ee7f9ed94bb..dce989b3a6a 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py +++ b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py @@ -15,7 +15,6 @@ from langchain_core.messages import ( AIMessage, AIMessageChunk, BaseMessage, - BaseMessageChunk, HumanMessage, SystemMessage, ToolMessage, @@ -67,8 +66,6 @@ def _get_joke_class( if schema_type == "json_schema": return Joke.model_json_schema(), validate_joke_dict - msg = "Invalid schema type" - raise ValueError(msg) class _TestCallbackHandler(BaseCallbackHandler): @@ -1381,7 +1378,7 @@ class ChatModelIntegrationTests(ChatModelTests): _validate_tool_call_message(result) # Test stream - full: Optional[BaseMessageChunk] = None + full: Optional[BaseMessage] = None for chunk in model_with_tools.stream(query): full = chunk if full is None else full + chunk # type: ignore[assignment] assert isinstance(full, AIMessage) @@ -1443,7 +1440,7 @@ class ChatModelIntegrationTests(ChatModelTests): _validate_tool_call_message(result) # Test astream - full: Optional[BaseMessageChunk] = None + full: Optional[BaseMessage] = None async for chunk in model_with_tools.astream(query): full = chunk if full is None else full + chunk # type: ignore[assignment] assert isinstance(full, AIMessage) @@ -1791,7 +1788,7 @@ class ChatModelIntegrationTests(ChatModelTests): result = model_with_tools.invoke(query) _validate_tool_call_message_no_args(result) - full: Optional[BaseMessageChunk] = None + full: Optional[BaseMessage] = None for chunk in model_with_tools.stream(query): full = chunk if full is None else full + chunk # type: ignore[assignment] assert isinstance(full, AIMessage) @@ -1932,7 +1929,11 @@ class ChatModelIntegrationTests(ChatModelTests): assert isinstance(result, AIMessage) @pytest.mark.parametrize("schema_type", ["pydantic", "typeddict", "json_schema"]) - def test_structured_output(self, model: BaseChatModel, schema_type: str) -> None: + def test_structured_output( + self, + model: BaseChatModel, + schema_type: Literal["pydantic", "typeddict", "json_schema"], + ) -> None: """Test to verify structured output is generated both on invoke and stream. This test is optional and should be skipped if the model does not support @@ -1968,7 +1969,7 @@ class ChatModelIntegrationTests(ChatModelTests): if not self.has_structured_output: pytest.skip("Test requires structured output.") - schema, validation_function = _get_joke_class(schema_type) # type: ignore[arg-type] + schema, validation_function = _get_joke_class(schema_type) chat = model.with_structured_output(schema, **self.structured_output_kwargs) mock_callback = MagicMock() mock_callback.on_chat_model_start = MagicMock() @@ -2012,7 +2013,9 @@ class ChatModelIntegrationTests(ChatModelTests): @pytest.mark.parametrize("schema_type", ["pydantic", "typeddict", "json_schema"]) async def test_structured_output_async( - self, model: BaseChatModel, schema_type: str + self, + model: BaseChatModel, + schema_type: Literal["pydantic", "typeddict", "json_schema"], ) -> None: """Test to verify structured output is generated both on invoke and stream. @@ -2049,7 +2052,7 @@ class ChatModelIntegrationTests(ChatModelTests): if not self.has_structured_output: pytest.skip("Test requires structured output.") - schema, validation_function = _get_joke_class(schema_type) # type: ignore[arg-type] + schema, validation_function = _get_joke_class(schema_type) chat = model.with_structured_output(schema, **self.structured_output_kwargs) ainvoke_callback = _TestCallbackHandler() @@ -2269,9 +2272,6 @@ class ChatModelIntegrationTests(ChatModelTests): punchline: str = FieldProper(description="answer to resolve the joke") # Pydantic class - # Type ignoring since the interface only officially supports pydantic 1 - # or pydantic.v1.BaseModel but not pydantic.BaseModel from pydantic 2. - # We'll need to do a pass updating the type signatures. chat = model.with_structured_output(Joke, method="json_mode") msg = ( "Tell me a joke about cats. Return the result as a JSON with 'setup' and " diff --git a/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py b/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py index 96088a552cb..ef25d1e3758 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py +++ b/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py @@ -4,7 +4,7 @@ from abc import abstractmethod import pytest from langchain_core.documents import Document -from langchain_core.embeddings.fake import DeterministicFakeEmbedding, Embeddings +from langchain_core.embeddings import DeterministicFakeEmbedding, Embeddings from langchain_core.vectorstores import VectorStore from langchain_tests.base import BaseStandardTests diff --git a/libs/standard-tests/langchain_tests/unit_tests/chat_models.py b/libs/standard-tests/langchain_tests/unit_tests/chat_models.py index 0c3b038df8d..177e85f2957 100644 --- a/libs/standard-tests/langchain_tests/unit_tests/chat_models.py +++ b/libs/standard-tests/langchain_tests/unit_tests/chat_models.py @@ -1022,8 +1022,8 @@ class ChatModelUnitTests(ChatModelTests): # Test optional params model = self.chat_model_class( - max_tokens=10, # type: ignore[call-arg] - stop=["test"], # type: ignore[call-arg] + max_tokens=10, + stop=["test"], **self.chat_model_params, ) ls_params = model._get_ls_params() diff --git a/libs/standard-tests/pyproject.toml b/libs/standard-tests/pyproject.toml index 7d80d80ba70..613ab8c315f 100644 --- a/libs/standard-tests/pyproject.toml +++ b/libs/standard-tests/pyproject.toml @@ -32,25 +32,29 @@ repository = "https://github.com/langchain-ai/langchain" [dependency-groups] test = ["langchain-core"] test_integration = [] - lint = ["ruff<0.13,>=0.12.10"] -typing = ["mypy<2,>=1.17.1", "langchain-core"] +typing = [ + "mypy<1.18,>=1.17.1", + "types-pyyaml<7.0.0.0,>=6.0.12.2", + "langchain-core", +] [tool.uv.sources] langchain-core = { path = "../core", editable = true } [tool.mypy] -disallow_untyped_defs = "True" +plugins = ["pydantic.mypy"] +strict = true +enable_error_code = "deprecated" +warn_unreachable = true + +# TODO: activate for 'strict' checking +disallow_any_generics = false [[tool.mypy.overrides]] -module = "yaml" +module = ["vcr.*",] ignore_missing_imports = true -[[tool.mypy.overrides]] -module = "vcr.*" -ignore_missing_imports = true - - [tool.ruff] target-version = "py39" diff --git a/libs/standard-tests/uv.lock b/libs/standard-tests/uv.lock index 85115c0d15e..10668d37c96 100644 --- a/libs/standard-tests/uv.lock +++ b/libs/standard-tests/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 1 requires-python = ">=3.9" resolution-markers = [ "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", @@ -16,9 +16,9 @@ resolution-markers = [ name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, ] [[package]] @@ -31,27 +31,27 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126, upload-time = "2025-01-05T13:13:11.095Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041, upload-time = "2025-01-05T13:13:07.985Z" }, + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, ] [[package]] name = "backports-asyncio-runner" version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, + { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313 }, ] [[package]] name = "certifi" version = "2025.1.31" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload-time = "2025-01-31T02:16:47.166Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload-time = "2025-01-31T02:16:45.015Z" }, + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, ] [[package]] @@ -61,167 +61,167 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191, upload-time = "2024-09-04T20:43:30.027Z" }, - { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592, upload-time = "2024-09-04T20:43:32.108Z" }, - { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload-time = "2024-09-04T20:43:34.186Z" }, - { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload-time = "2024-09-04T20:43:36.286Z" }, - { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload-time = "2024-09-04T20:43:38.586Z" }, - { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload-time = "2024-09-04T20:43:40.084Z" }, - { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload-time = "2024-09-04T20:43:41.526Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload-time = "2024-09-04T20:43:43.117Z" }, - { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload-time = "2024-09-04T20:43:45.256Z" }, - { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload-time = "2024-09-04T20:43:46.779Z" }, - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload-time = "2024-09-04T20:43:48.186Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload-time = "2024-09-04T20:43:49.812Z" }, - { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, - { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, - { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, - { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, - { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, - { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/ea/8bb50596b8ffbc49ddd7a1ad305035daa770202a6b782fc164647c2673ad/cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", size = 182220, upload-time = "2024-09-04T20:45:01.577Z" }, - { url = "https://files.pythonhosted.org/packages/ae/11/e77c8cd24f58285a82c23af484cf5b124a376b32644e445960d1a4654c3a/cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", size = 178605, upload-time = "2024-09-04T20:45:03.837Z" }, - { url = "https://files.pythonhosted.org/packages/ed/65/25a8dc32c53bf5b7b6c2686b42ae2ad58743f7ff644844af7cdb29b49361/cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", size = 424910, upload-time = "2024-09-04T20:45:05.315Z" }, - { url = "https://files.pythonhosted.org/packages/42/7a/9d086fab7c66bd7c4d0f27c57a1b6b068ced810afc498cc8c49e0088661c/cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", size = 447200, upload-time = "2024-09-04T20:45:06.903Z" }, - { url = "https://files.pythonhosted.org/packages/da/63/1785ced118ce92a993b0ec9e0d0ac8dc3e5dbfbcaa81135be56c69cabbb6/cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", size = 454565, upload-time = "2024-09-04T20:45:08.975Z" }, - { url = "https://files.pythonhosted.org/packages/74/06/90b8a44abf3556599cdec107f7290277ae8901a58f75e6fe8f970cd72418/cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", size = 435635, upload-time = "2024-09-04T20:45:10.64Z" }, - { url = "https://files.pythonhosted.org/packages/bd/62/a1f468e5708a70b1d86ead5bab5520861d9c7eacce4a885ded9faa7729c3/cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", size = 445218, upload-time = "2024-09-04T20:45:12.366Z" }, - { url = "https://files.pythonhosted.org/packages/5b/95/b34462f3ccb09c2594aa782d90a90b045de4ff1f70148ee79c69d37a0a5a/cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", size = 460486, upload-time = "2024-09-04T20:45:13.935Z" }, - { url = "https://files.pythonhosted.org/packages/fc/fc/a1e4bebd8d680febd29cf6c8a40067182b64f00c7d105f8f26b5bc54317b/cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", size = 437911, upload-time = "2024-09-04T20:45:15.696Z" }, - { url = "https://files.pythonhosted.org/packages/e6/c3/21cab7a6154b6a5ea330ae80de386e7665254835b9e98ecc1340b3a7de9a/cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", size = 460632, upload-time = "2024-09-04T20:45:17.284Z" }, - { url = "https://files.pythonhosted.org/packages/cb/b5/fd9f8b5a84010ca169ee49f4e4ad6f8c05f4e3545b72ee041dbbcb159882/cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", size = 171820, upload-time = "2024-09-04T20:45:18.762Z" }, - { url = "https://files.pythonhosted.org/packages/8c/52/b08750ce0bce45c143e1b5d7357ee8c55341b52bdef4b0f081af1eb248c2/cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", size = 181290, upload-time = "2024-09-04T20:45:20.226Z" }, + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, + { url = "https://files.pythonhosted.org/packages/b9/ea/8bb50596b8ffbc49ddd7a1ad305035daa770202a6b782fc164647c2673ad/cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", size = 182220 }, + { url = "https://files.pythonhosted.org/packages/ae/11/e77c8cd24f58285a82c23af484cf5b124a376b32644e445960d1a4654c3a/cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", size = 178605 }, + { url = "https://files.pythonhosted.org/packages/ed/65/25a8dc32c53bf5b7b6c2686b42ae2ad58743f7ff644844af7cdb29b49361/cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", size = 424910 }, + { url = "https://files.pythonhosted.org/packages/42/7a/9d086fab7c66bd7c4d0f27c57a1b6b068ced810afc498cc8c49e0088661c/cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", size = 447200 }, + { url = "https://files.pythonhosted.org/packages/da/63/1785ced118ce92a993b0ec9e0d0ac8dc3e5dbfbcaa81135be56c69cabbb6/cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", size = 454565 }, + { url = "https://files.pythonhosted.org/packages/74/06/90b8a44abf3556599cdec107f7290277ae8901a58f75e6fe8f970cd72418/cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", size = 435635 }, + { url = "https://files.pythonhosted.org/packages/bd/62/a1f468e5708a70b1d86ead5bab5520861d9c7eacce4a885ded9faa7729c3/cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", size = 445218 }, + { url = "https://files.pythonhosted.org/packages/5b/95/b34462f3ccb09c2594aa782d90a90b045de4ff1f70148ee79c69d37a0a5a/cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", size = 460486 }, + { url = "https://files.pythonhosted.org/packages/fc/fc/a1e4bebd8d680febd29cf6c8a40067182b64f00c7d105f8f26b5bc54317b/cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", size = 437911 }, + { url = "https://files.pythonhosted.org/packages/e6/c3/21cab7a6154b6a5ea330ae80de386e7665254835b9e98ecc1340b3a7de9a/cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", size = 460632 }, + { url = "https://files.pythonhosted.org/packages/cb/b5/fd9f8b5a84010ca169ee49f4e4ad6f8c05f4e3545b72ee041dbbcb159882/cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", size = 171820 }, + { url = "https://files.pythonhosted.org/packages/8c/52/b08750ce0bce45c143e1b5d7357ee8c55341b52bdef4b0f081af1eb248c2/cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", size = 181290 }, ] [[package]] name = "charset-normalizer" version = "3.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013, upload-time = "2024-12-24T18:09:43.671Z" }, - { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285, upload-time = "2024-12-24T18:09:48.113Z" }, - { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449, upload-time = "2024-12-24T18:09:50.845Z" }, - { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892, upload-time = "2024-12-24T18:09:52.078Z" }, - { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123, upload-time = "2024-12-24T18:09:54.575Z" }, - { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943, upload-time = "2024-12-24T18:09:57.324Z" }, - { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063, upload-time = "2024-12-24T18:09:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578, upload-time = "2024-12-24T18:10:02.357Z" }, - { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629, upload-time = "2024-12-24T18:10:03.678Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778, upload-time = "2024-12-24T18:10:06.197Z" }, - { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453, upload-time = "2024-12-24T18:10:08.848Z" }, - { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479, upload-time = "2024-12-24T18:10:10.044Z" }, - { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790, upload-time = "2024-12-24T18:10:11.323Z" }, - { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995, upload-time = "2024-12-24T18:10:12.838Z" }, - { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471, upload-time = "2024-12-24T18:10:14.101Z" }, - { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831, upload-time = "2024-12-24T18:10:15.512Z" }, - { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335, upload-time = "2024-12-24T18:10:18.369Z" }, - { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862, upload-time = "2024-12-24T18:10:19.743Z" }, - { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673, upload-time = "2024-12-24T18:10:21.139Z" }, - { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211, upload-time = "2024-12-24T18:10:22.382Z" }, - { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039, upload-time = "2024-12-24T18:10:24.802Z" }, - { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939, upload-time = "2024-12-24T18:10:26.124Z" }, - { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075, upload-time = "2024-12-24T18:10:30.027Z" }, - { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340, upload-time = "2024-12-24T18:10:32.679Z" }, - { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205, upload-time = "2024-12-24T18:10:34.724Z" }, - { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441, upload-time = "2024-12-24T18:10:37.574Z" }, - { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105, upload-time = "2024-12-24T18:10:38.83Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404, upload-time = "2024-12-24T18:10:44.272Z" }, - { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423, upload-time = "2024-12-24T18:10:45.492Z" }, - { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184, upload-time = "2024-12-24T18:10:47.898Z" }, - { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268, upload-time = "2024-12-24T18:10:50.589Z" }, - { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601, upload-time = "2024-12-24T18:10:52.541Z" }, - { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098, upload-time = "2024-12-24T18:10:53.789Z" }, - { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520, upload-time = "2024-12-24T18:10:55.048Z" }, - { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852, upload-time = "2024-12-24T18:10:57.647Z" }, - { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488, upload-time = "2024-12-24T18:10:59.43Z" }, - { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192, upload-time = "2024-12-24T18:11:00.676Z" }, - { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550, upload-time = "2024-12-24T18:11:01.952Z" }, - { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785, upload-time = "2024-12-24T18:11:03.142Z" }, - { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" }, - { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" }, - { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" }, - { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" }, - { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" }, - { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" }, - { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" }, - { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" }, - { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" }, - { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" }, - { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" }, - { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" }, - { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" }, - { url = "https://files.pythonhosted.org/packages/7f/c0/b913f8f02836ed9ab32ea643c6fe4d3325c3d8627cf6e78098671cafff86/charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", size = 197867, upload-time = "2024-12-24T18:12:10.438Z" }, - { url = "https://files.pythonhosted.org/packages/0f/6c/2bee440303d705b6fb1e2ec789543edec83d32d258299b16eed28aad48e0/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", size = 141385, upload-time = "2024-12-24T18:12:11.847Z" }, - { url = "https://files.pythonhosted.org/packages/3d/04/cb42585f07f6f9fd3219ffb6f37d5a39b4fd2db2355b23683060029c35f7/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", size = 151367, upload-time = "2024-12-24T18:12:13.177Z" }, - { url = "https://files.pythonhosted.org/packages/54/54/2412a5b093acb17f0222de007cc129ec0e0df198b5ad2ce5699355269dfe/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", size = 143928, upload-time = "2024-12-24T18:12:14.497Z" }, - { url = "https://files.pythonhosted.org/packages/5a/6d/e2773862b043dcf8a221342954f375392bb2ce6487bcd9f2c1b34e1d6781/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", size = 146203, upload-time = "2024-12-24T18:12:15.731Z" }, - { url = "https://files.pythonhosted.org/packages/b9/f8/ca440ef60d8f8916022859885f231abb07ada3c347c03d63f283bec32ef5/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", size = 148082, upload-time = "2024-12-24T18:12:18.641Z" }, - { url = "https://files.pythonhosted.org/packages/04/d2/42fd330901aaa4b805a1097856c2edf5095e260a597f65def493f4b8c833/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", size = 142053, upload-time = "2024-12-24T18:12:20.036Z" }, - { url = "https://files.pythonhosted.org/packages/9e/af/3a97a4fa3c53586f1910dadfc916e9c4f35eeada36de4108f5096cb7215f/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", size = 150625, upload-time = "2024-12-24T18:12:22.804Z" }, - { url = "https://files.pythonhosted.org/packages/26/ae/23d6041322a3556e4da139663d02fb1b3c59a23ab2e2b56432bd2ad63ded/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", size = 153549, upload-time = "2024-12-24T18:12:24.163Z" }, - { url = "https://files.pythonhosted.org/packages/94/22/b8f2081c6a77cb20d97e57e0b385b481887aa08019d2459dc2858ed64871/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", size = 150945, upload-time = "2024-12-24T18:12:25.415Z" }, - { url = "https://files.pythonhosted.org/packages/c7/0b/c5ec5092747f801b8b093cdf5610e732b809d6cb11f4c51e35fc28d1d389/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", size = 146595, upload-time = "2024-12-24T18:12:28.03Z" }, - { url = "https://files.pythonhosted.org/packages/0c/5a/0b59704c38470df6768aa154cc87b1ac7c9bb687990a1559dc8765e8627e/charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", size = 95453, upload-time = "2024-12-24T18:12:29.569Z" }, - { url = "https://files.pythonhosted.org/packages/85/2d/a9790237cb4d01a6d57afadc8573c8b73c609ade20b80f4cda30802009ee/charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", size = 102811, upload-time = "2024-12-24T18:12:30.83Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" }, + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/7f/c0/b913f8f02836ed9ab32ea643c6fe4d3325c3d8627cf6e78098671cafff86/charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", size = 197867 }, + { url = "https://files.pythonhosted.org/packages/0f/6c/2bee440303d705b6fb1e2ec789543edec83d32d258299b16eed28aad48e0/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", size = 141385 }, + { url = "https://files.pythonhosted.org/packages/3d/04/cb42585f07f6f9fd3219ffb6f37d5a39b4fd2db2355b23683060029c35f7/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", size = 151367 }, + { url = "https://files.pythonhosted.org/packages/54/54/2412a5b093acb17f0222de007cc129ec0e0df198b5ad2ce5699355269dfe/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", size = 143928 }, + { url = "https://files.pythonhosted.org/packages/5a/6d/e2773862b043dcf8a221342954f375392bb2ce6487bcd9f2c1b34e1d6781/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", size = 146203 }, + { url = "https://files.pythonhosted.org/packages/b9/f8/ca440ef60d8f8916022859885f231abb07ada3c347c03d63f283bec32ef5/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", size = 148082 }, + { url = "https://files.pythonhosted.org/packages/04/d2/42fd330901aaa4b805a1097856c2edf5095e260a597f65def493f4b8c833/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", size = 142053 }, + { url = "https://files.pythonhosted.org/packages/9e/af/3a97a4fa3c53586f1910dadfc916e9c4f35eeada36de4108f5096cb7215f/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", size = 150625 }, + { url = "https://files.pythonhosted.org/packages/26/ae/23d6041322a3556e4da139663d02fb1b3c59a23ab2e2b56432bd2ad63ded/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", size = 153549 }, + { url = "https://files.pythonhosted.org/packages/94/22/b8f2081c6a77cb20d97e57e0b385b481887aa08019d2459dc2858ed64871/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", size = 150945 }, + { url = "https://files.pythonhosted.org/packages/c7/0b/c5ec5092747f801b8b093cdf5610e732b809d6cb11f4c51e35fc28d1d389/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", size = 146595 }, + { url = "https://files.pythonhosted.org/packages/0c/5a/0b59704c38470df6768aa154cc87b1ac7c9bb687990a1559dc8765e8627e/charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", size = 95453 }, + { url = "https://files.pythonhosted.org/packages/85/2d/a9790237cb4d01a6d57afadc8573c8b73c609ade20b80f4cda30802009ee/charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", size = 102811 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, ] [[package]] name = "exceptiongroup" version = "1.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload-time = "2024-07-12T22:26:00.161Z" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload-time = "2024-07-12T22:25:58.476Z" }, + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, ] [[package]] name = "h11" version = "0.14.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, ] [[package]] @@ -232,9 +232,9 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196, upload-time = "2024-11-15T12:30:47.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551, upload-time = "2024-11-15T12:30:45.782Z" }, + { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, ] [[package]] @@ -247,18 +247,18 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, ] [[package]] @@ -268,18 +268,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641 } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656 }, ] [[package]] name = "iniconfig" version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, ] [[package]] @@ -289,18 +289,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpointer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699, upload-time = "2023-06-26T12:07:29.144Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699 } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898, upload-time = "2023-06-16T21:01:28.466Z" }, + { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898 }, ] [[package]] name = "jsonpointer" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, ] [[package]] @@ -390,6 +390,7 @@ test = [ typing = [ { name = "langchain-core" }, { name = "mypy" }, + { name = "types-pyyaml" }, ] [package.metadata] @@ -414,7 +415,8 @@ test = [{ name = "langchain-core", editable = "../core" }] test-integration = [] typing = [ { name = "langchain-core", editable = "../core" }, - { name = "mypy", specifier = ">=1.17.1,<2" }, + { name = "mypy", specifier = ">=1.17.1,<1.18" }, + { name = "types-pyyaml", specifier = ">=6.0.12.2,<7.0.0.0" }, ] [[package]] @@ -430,9 +432,9 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105, upload-time = "2025-06-27T19:20:36.207Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687, upload-time = "2025-06-27T19:20:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687 }, ] [[package]] @@ -442,18 +444,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, ] [[package]] @@ -463,111 +465,111 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183, upload-time = "2025-05-19T14:16:37.381Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/92/0926a5baafa164b5d0ade3cd7932be39310375d7e25c9d7ceca05cb26a45/multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff", size = 66052, upload-time = "2025-05-19T14:13:49.944Z" }, - { url = "https://files.pythonhosted.org/packages/b2/54/8a857ae4f8f643ec444d91f419fdd49cc7a90a2ca0e42d86482b604b63bd/multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028", size = 38867, upload-time = "2025-05-19T14:13:51.92Z" }, - { url = "https://files.pythonhosted.org/packages/9e/5f/63add9069f945c19bc8b217ea6b0f8a1ad9382eab374bb44fae4354b3baf/multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0", size = 38138, upload-time = "2025-05-19T14:13:53.778Z" }, - { url = "https://files.pythonhosted.org/packages/97/8b/fbd9c0fc13966efdb4a47f5bcffff67a4f2a3189fbeead5766eaa4250b20/multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772", size = 220433, upload-time = "2025-05-19T14:13:55.346Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c4/5132b2d75b3ea2daedb14d10f91028f09f74f5b4d373b242c1b8eec47571/multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7", size = 218059, upload-time = "2025-05-19T14:13:56.993Z" }, - { url = "https://files.pythonhosted.org/packages/1a/70/f1e818c7a29b908e2d7b4fafb1d7939a41c64868e79de2982eea0a13193f/multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299", size = 231120, upload-time = "2025-05-19T14:13:58.333Z" }, - { url = "https://files.pythonhosted.org/packages/b4/7e/95a194d85f27d5ef9cbe48dff9ded722fc6d12fedf641ec6e1e680890be7/multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc", size = 227457, upload-time = "2025-05-19T14:13:59.663Z" }, - { url = "https://files.pythonhosted.org/packages/25/2b/590ad220968d1babb42f265debe7be5c5c616df6c5688c995a06d8a9b025/multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad", size = 219111, upload-time = "2025-05-19T14:14:01.019Z" }, - { url = "https://files.pythonhosted.org/packages/e0/f0/b07682b995d3fb5313f339b59d7de02db19ba0c02d1f77c27bdf8212d17c/multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915", size = 213012, upload-time = "2025-05-19T14:14:02.396Z" }, - { url = "https://files.pythonhosted.org/packages/24/56/c77b5f36feef2ec92f1119756e468ac9c3eebc35aa8a4c9e51df664cbbc9/multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01", size = 225408, upload-time = "2025-05-19T14:14:04.826Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b3/e8189b82af9b198b47bc637766208fc917189eea91d674bad417e657bbdf/multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598", size = 214396, upload-time = "2025-05-19T14:14:06.187Z" }, - { url = "https://files.pythonhosted.org/packages/20/e0/200d14c84e35ae13ee99fd65dc106e1a1acb87a301f15e906fc7d5b30c17/multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f", size = 222237, upload-time = "2025-05-19T14:14:07.778Z" }, - { url = "https://files.pythonhosted.org/packages/13/f3/bb3df40045ca8262694a3245298732ff431dc781414a89a6a364ebac6840/multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145", size = 231425, upload-time = "2025-05-19T14:14:09.516Z" }, - { url = "https://files.pythonhosted.org/packages/85/3b/538563dc18514384dac169bcba938753ad9ab4d4c8d49b55d6ae49fb2579/multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c", size = 226251, upload-time = "2025-05-19T14:14:10.82Z" }, - { url = "https://files.pythonhosted.org/packages/56/79/77e1a65513f09142358f1beb1d4cbc06898590b34a7de2e47023e3c5a3a2/multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683", size = 220363, upload-time = "2025-05-19T14:14:12.638Z" }, - { url = "https://files.pythonhosted.org/packages/16/57/67b0516c3e348f8daaa79c369b3de4359a19918320ab82e2e586a1c624ef/multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d", size = 35175, upload-time = "2025-05-19T14:14:14.805Z" }, - { url = "https://files.pythonhosted.org/packages/86/5a/4ed8fec642d113fa653777cda30ef67aa5c8a38303c091e24c521278a6c6/multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04", size = 38678, upload-time = "2025-05-19T14:14:16.949Z" }, - { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515, upload-time = "2025-05-19T14:14:19.767Z" }, - { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609, upload-time = "2025-05-19T14:14:21.538Z" }, - { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871, upload-time = "2025-05-19T14:14:22.666Z" }, - { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661, upload-time = "2025-05-19T14:14:24.124Z" }, - { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422, upload-time = "2025-05-19T14:14:25.437Z" }, - { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447, upload-time = "2025-05-19T14:14:26.793Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455, upload-time = "2025-05-19T14:14:28.149Z" }, - { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666, upload-time = "2025-05-19T14:14:29.584Z" }, - { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392, upload-time = "2025-05-19T14:14:30.961Z" }, - { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969, upload-time = "2025-05-19T14:14:32.672Z" }, - { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433, upload-time = "2025-05-19T14:14:34.016Z" }, - { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418, upload-time = "2025-05-19T14:14:35.376Z" }, - { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042, upload-time = "2025-05-19T14:14:36.723Z" }, - { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280, upload-time = "2025-05-19T14:14:38.194Z" }, - { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322, upload-time = "2025-05-19T14:14:40.015Z" }, - { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070, upload-time = "2025-05-19T14:14:41.904Z" }, - { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667, upload-time = "2025-05-19T14:14:43.534Z" }, - { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293, upload-time = "2025-05-19T14:14:44.724Z" }, - { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096, upload-time = "2025-05-19T14:14:45.95Z" }, - { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214, upload-time = "2025-05-19T14:14:47.158Z" }, - { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686, upload-time = "2025-05-19T14:14:48.366Z" }, - { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061, upload-time = "2025-05-19T14:14:49.952Z" }, - { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412, upload-time = "2025-05-19T14:14:51.812Z" }, - { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563, upload-time = "2025-05-19T14:14:53.262Z" }, - { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811, upload-time = "2025-05-19T14:14:55.232Z" }, - { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524, upload-time = "2025-05-19T14:14:57.226Z" }, - { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012, upload-time = "2025-05-19T14:14:58.597Z" }, - { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765, upload-time = "2025-05-19T14:15:00.048Z" }, - { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888, upload-time = "2025-05-19T14:15:01.568Z" }, - { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041, upload-time = "2025-05-19T14:15:03.759Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046, upload-time = "2025-05-19T14:15:05.698Z" }, - { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106, upload-time = "2025-05-19T14:15:07.124Z" }, - { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351, upload-time = "2025-05-19T14:15:08.556Z" }, - { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791, upload-time = "2025-05-19T14:15:09.825Z" }, - { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123, upload-time = "2025-05-19T14:15:11.044Z" }, - { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049, upload-time = "2025-05-19T14:15:12.902Z" }, - { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078, upload-time = "2025-05-19T14:15:14.282Z" }, - { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097, upload-time = "2025-05-19T14:15:15.566Z" }, - { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768, upload-time = "2025-05-19T14:15:17.308Z" }, - { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331, upload-time = "2025-05-19T14:15:18.73Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169, upload-time = "2025-05-19T14:15:20.179Z" }, - { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947, upload-time = "2025-05-19T14:15:21.714Z" }, - { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761, upload-time = "2025-05-19T14:15:23.242Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605, upload-time = "2025-05-19T14:15:24.763Z" }, - { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144, upload-time = "2025-05-19T14:15:26.249Z" }, - { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100, upload-time = "2025-05-19T14:15:28.303Z" }, - { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731, upload-time = "2025-05-19T14:15:30.263Z" }, - { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637, upload-time = "2025-05-19T14:15:33.337Z" }, - { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594, upload-time = "2025-05-19T14:15:34.832Z" }, - { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359, upload-time = "2025-05-19T14:15:36.246Z" }, - { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903, upload-time = "2025-05-19T14:15:37.507Z" }, - { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895, upload-time = "2025-05-19T14:15:38.856Z" }, - { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183, upload-time = "2025-05-19T14:15:40.197Z" }, - { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592, upload-time = "2025-05-19T14:15:41.508Z" }, - { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071, upload-time = "2025-05-19T14:15:42.877Z" }, - { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597, upload-time = "2025-05-19T14:15:44.412Z" }, - { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253, upload-time = "2025-05-19T14:15:46.474Z" }, - { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146, upload-time = "2025-05-19T14:15:48.003Z" }, - { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585, upload-time = "2025-05-19T14:15:49.546Z" }, - { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080, upload-time = "2025-05-19T14:15:51.151Z" }, - { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558, upload-time = "2025-05-19T14:15:52.665Z" }, - { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168, upload-time = "2025-05-19T14:15:55.279Z" }, - { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970, upload-time = "2025-05-19T14:15:56.806Z" }, - { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980, upload-time = "2025-05-19T14:15:58.313Z" }, - { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641, upload-time = "2025-05-19T14:15:59.866Z" }, - { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728, upload-time = "2025-05-19T14:16:01.535Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913, upload-time = "2025-05-19T14:16:03.199Z" }, - { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112, upload-time = "2025-05-19T14:16:04.909Z" }, - { url = "https://files.pythonhosted.org/packages/18/5c/92607a79e7fd0361c90b3c5d79bbd186e3968e8a4832dbefcd7808f1c823/multidict-6.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:603f39bd1cf85705c6c1ba59644b480dfe495e6ee2b877908de93322705ad7cf", size = 66007, upload-time = "2025-05-19T14:16:06.25Z" }, - { url = "https://files.pythonhosted.org/packages/32/1e/212a154926a9290d8ae432e761d1c98ed95fccce84b1b938eaf1bf17378e/multidict-6.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc60f91c02e11dfbe3ff4e1219c085695c339af72d1641800fe6075b91850c8f", size = 38824, upload-time = "2025-05-19T14:16:07.61Z" }, - { url = "https://files.pythonhosted.org/packages/8b/64/5ca6fb5dbc7d5aa352cd2d013c86ae44133c3f4f6b83a80dacd42ee5c568/multidict-6.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:496bcf01c76a70a31c3d746fd39383aad8d685ce6331e4c709e9af4ced5fa221", size = 38117, upload-time = "2025-05-19T14:16:08.966Z" }, - { url = "https://files.pythonhosted.org/packages/aa/20/3aee7910260e7b6f0045b6f48b97ebf041de0cab513c12f87cf6e4e514d3/multidict-6.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4219390fb5bf8e548e77b428bb36a21d9382960db5321b74d9d9987148074d6b", size = 218106, upload-time = "2025-05-19T14:16:10.962Z" }, - { url = "https://files.pythonhosted.org/packages/a9/79/15f5a65b8de8ae8f3c5da1591a322620675e4fec8d39995b04101d2b2e2c/multidict-6.4.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef4e9096ff86dfdcbd4a78253090ba13b1d183daa11b973e842465d94ae1772", size = 213817, upload-time = "2025-05-19T14:16:12.486Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a7/90de36db90ce2936fbb1639ca51508965861a8ad5dc2947531d18f3363b9/multidict-6.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49a29d7133b1fc214e818bbe025a77cc6025ed9a4f407d2850373ddde07fd04a", size = 228133, upload-time = "2025-05-19T14:16:14.48Z" }, - { url = "https://files.pythonhosted.org/packages/df/25/5fcd66fda3c8b7d6d6f658a871017791c46824e965dfa20a4c46d4167ad4/multidict-6.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e32053d6d3a8b0dfe49fde05b496731a0e6099a4df92154641c00aa76786aef5", size = 224271, upload-time = "2025-05-19T14:16:16.314Z" }, - { url = "https://files.pythonhosted.org/packages/fd/9a/1011812091fd99b2dddd9d2dbde4b7d69bbf8070e0291fe49c3bb40c2d55/multidict-6.4.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc403092a49509e8ef2d2fd636a8ecefc4698cc57bbe894606b14579bc2a955", size = 216448, upload-time = "2025-05-19T14:16:18.263Z" }, - { url = "https://files.pythonhosted.org/packages/cf/cc/916e066b7e2686999f95dde87f588be26fa1c2f05e70d9fd472fe2289c0b/multidict-6.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5363f9b2a7f3910e5c87d8b1855c478c05a2dc559ac57308117424dfaad6805c", size = 210080, upload-time = "2025-05-19T14:16:20.326Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ff/15034b18f2e4179cd559aa13bc3b376a95c22e1fd7c3b88884e078ad5466/multidict-6.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e543a40e4946cf70a88a3be87837a3ae0aebd9058ba49e91cacb0b2cd631e2b", size = 221926, upload-time = "2025-05-19T14:16:22.227Z" }, - { url = "https://files.pythonhosted.org/packages/17/43/4243298a6b0b869a83b6331f3fcc12a2a0544c0995292ee96badf0fec6aa/multidict-6.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:60d849912350da557fe7de20aa8cf394aada6980d0052cc829eeda4a0db1c1db", size = 211318, upload-time = "2025-05-19T14:16:23.914Z" }, - { url = "https://files.pythonhosted.org/packages/fe/80/bc43c87d60138e401c7d1818a47e5a0f748904c9f3be99012cdab5e31446/multidict-6.4.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:19d08b4f22eae45bb018b9f06e2838c1e4b853c67628ef8ae126d99de0da6395", size = 217611, upload-time = "2025-05-19T14:16:25.647Z" }, - { url = "https://files.pythonhosted.org/packages/1e/5d/2ec94209254e48910911ac2404d71b37f06fd97ec83948a92d0c87a11d3c/multidict-6.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d693307856d1ef08041e8b6ff01d5b4618715007d288490ce2c7e29013c12b9a", size = 227893, upload-time = "2025-05-19T14:16:27.721Z" }, - { url = "https://files.pythonhosted.org/packages/71/83/89344adc0cf08fd89d82d43de1a17a2635b03a57dfa680f6cdf2a24d481f/multidict-6.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fad6daaed41021934917f4fb03ca2db8d8a4d79bf89b17ebe77228eb6710c003", size = 221956, upload-time = "2025-05-19T14:16:29.307Z" }, - { url = "https://files.pythonhosted.org/packages/f0/ea/81382bb59cd3a1047d1c2ea9339d2107fc918a63491bbb9399eb1aceda91/multidict-6.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c10d17371bff801af0daf8b073c30b6cf14215784dc08cd5c43ab5b7b8029bbc", size = 216850, upload-time = "2025-05-19T14:16:30.913Z" }, - { url = "https://files.pythonhosted.org/packages/0f/90/c848d62de66c2958932ce155adae418cbf79d96cfaf992e5255819f8f1d9/multidict-6.4.4-cp39-cp39-win32.whl", hash = "sha256:7e23f2f841fcb3ebd4724a40032d32e0892fbba4143e43d2a9e7695c5e50e6bd", size = 35235, upload-time = "2025-05-19T14:16:32.85Z" }, - { url = "https://files.pythonhosted.org/packages/d4/19/dd625207c92889c1ae7b89fcbde760d99853265cfe7ffb0826393151acd1/multidict-6.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d7b50b673ffb4ff4366e7ab43cf1f0aef4bd3608735c5fbdf0bdb6f690da411", size = 38821, upload-time = "2025-05-19T14:16:34.288Z" }, - { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481, upload-time = "2025-05-19T14:16:36.024Z" }, + { url = "https://files.pythonhosted.org/packages/1f/92/0926a5baafa164b5d0ade3cd7932be39310375d7e25c9d7ceca05cb26a45/multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff", size = 66052 }, + { url = "https://files.pythonhosted.org/packages/b2/54/8a857ae4f8f643ec444d91f419fdd49cc7a90a2ca0e42d86482b604b63bd/multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028", size = 38867 }, + { url = "https://files.pythonhosted.org/packages/9e/5f/63add9069f945c19bc8b217ea6b0f8a1ad9382eab374bb44fae4354b3baf/multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0", size = 38138 }, + { url = "https://files.pythonhosted.org/packages/97/8b/fbd9c0fc13966efdb4a47f5bcffff67a4f2a3189fbeead5766eaa4250b20/multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772", size = 220433 }, + { url = "https://files.pythonhosted.org/packages/a9/c4/5132b2d75b3ea2daedb14d10f91028f09f74f5b4d373b242c1b8eec47571/multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7", size = 218059 }, + { url = "https://files.pythonhosted.org/packages/1a/70/f1e818c7a29b908e2d7b4fafb1d7939a41c64868e79de2982eea0a13193f/multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299", size = 231120 }, + { url = "https://files.pythonhosted.org/packages/b4/7e/95a194d85f27d5ef9cbe48dff9ded722fc6d12fedf641ec6e1e680890be7/multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc", size = 227457 }, + { url = "https://files.pythonhosted.org/packages/25/2b/590ad220968d1babb42f265debe7be5c5c616df6c5688c995a06d8a9b025/multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad", size = 219111 }, + { url = "https://files.pythonhosted.org/packages/e0/f0/b07682b995d3fb5313f339b59d7de02db19ba0c02d1f77c27bdf8212d17c/multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915", size = 213012 }, + { url = "https://files.pythonhosted.org/packages/24/56/c77b5f36feef2ec92f1119756e468ac9c3eebc35aa8a4c9e51df664cbbc9/multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01", size = 225408 }, + { url = "https://files.pythonhosted.org/packages/cc/b3/e8189b82af9b198b47bc637766208fc917189eea91d674bad417e657bbdf/multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598", size = 214396 }, + { url = "https://files.pythonhosted.org/packages/20/e0/200d14c84e35ae13ee99fd65dc106e1a1acb87a301f15e906fc7d5b30c17/multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f", size = 222237 }, + { url = "https://files.pythonhosted.org/packages/13/f3/bb3df40045ca8262694a3245298732ff431dc781414a89a6a364ebac6840/multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145", size = 231425 }, + { url = "https://files.pythonhosted.org/packages/85/3b/538563dc18514384dac169bcba938753ad9ab4d4c8d49b55d6ae49fb2579/multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c", size = 226251 }, + { url = "https://files.pythonhosted.org/packages/56/79/77e1a65513f09142358f1beb1d4cbc06898590b34a7de2e47023e3c5a3a2/multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683", size = 220363 }, + { url = "https://files.pythonhosted.org/packages/16/57/67b0516c3e348f8daaa79c369b3de4359a19918320ab82e2e586a1c624ef/multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d", size = 35175 }, + { url = "https://files.pythonhosted.org/packages/86/5a/4ed8fec642d113fa653777cda30ef67aa5c8a38303c091e24c521278a6c6/multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04", size = 38678 }, + { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515 }, + { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609 }, + { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871 }, + { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661 }, + { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422 }, + { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447 }, + { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455 }, + { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666 }, + { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392 }, + { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969 }, + { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433 }, + { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418 }, + { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042 }, + { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280 }, + { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322 }, + { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070 }, + { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667 }, + { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293 }, + { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096 }, + { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214 }, + { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686 }, + { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061 }, + { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412 }, + { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563 }, + { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811 }, + { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524 }, + { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012 }, + { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765 }, + { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888 }, + { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041 }, + { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046 }, + { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106 }, + { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351 }, + { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791 }, + { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123 }, + { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049 }, + { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078 }, + { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097 }, + { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768 }, + { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331 }, + { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169 }, + { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947 }, + { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761 }, + { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605 }, + { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144 }, + { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100 }, + { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731 }, + { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637 }, + { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594 }, + { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359 }, + { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903 }, + { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895 }, + { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183 }, + { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592 }, + { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071 }, + { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597 }, + { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253 }, + { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146 }, + { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585 }, + { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080 }, + { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558 }, + { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168 }, + { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970 }, + { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980 }, + { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641 }, + { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728 }, + { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913 }, + { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112 }, + { url = "https://files.pythonhosted.org/packages/18/5c/92607a79e7fd0361c90b3c5d79bbd186e3968e8a4832dbefcd7808f1c823/multidict-6.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:603f39bd1cf85705c6c1ba59644b480dfe495e6ee2b877908de93322705ad7cf", size = 66007 }, + { url = "https://files.pythonhosted.org/packages/32/1e/212a154926a9290d8ae432e761d1c98ed95fccce84b1b938eaf1bf17378e/multidict-6.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc60f91c02e11dfbe3ff4e1219c085695c339af72d1641800fe6075b91850c8f", size = 38824 }, + { url = "https://files.pythonhosted.org/packages/8b/64/5ca6fb5dbc7d5aa352cd2d013c86ae44133c3f4f6b83a80dacd42ee5c568/multidict-6.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:496bcf01c76a70a31c3d746fd39383aad8d685ce6331e4c709e9af4ced5fa221", size = 38117 }, + { url = "https://files.pythonhosted.org/packages/aa/20/3aee7910260e7b6f0045b6f48b97ebf041de0cab513c12f87cf6e4e514d3/multidict-6.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4219390fb5bf8e548e77b428bb36a21d9382960db5321b74d9d9987148074d6b", size = 218106 }, + { url = "https://files.pythonhosted.org/packages/a9/79/15f5a65b8de8ae8f3c5da1591a322620675e4fec8d39995b04101d2b2e2c/multidict-6.4.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef4e9096ff86dfdcbd4a78253090ba13b1d183daa11b973e842465d94ae1772", size = 213817 }, + { url = "https://files.pythonhosted.org/packages/ab/a7/90de36db90ce2936fbb1639ca51508965861a8ad5dc2947531d18f3363b9/multidict-6.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49a29d7133b1fc214e818bbe025a77cc6025ed9a4f407d2850373ddde07fd04a", size = 228133 }, + { url = "https://files.pythonhosted.org/packages/df/25/5fcd66fda3c8b7d6d6f658a871017791c46824e965dfa20a4c46d4167ad4/multidict-6.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e32053d6d3a8b0dfe49fde05b496731a0e6099a4df92154641c00aa76786aef5", size = 224271 }, + { url = "https://files.pythonhosted.org/packages/fd/9a/1011812091fd99b2dddd9d2dbde4b7d69bbf8070e0291fe49c3bb40c2d55/multidict-6.4.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc403092a49509e8ef2d2fd636a8ecefc4698cc57bbe894606b14579bc2a955", size = 216448 }, + { url = "https://files.pythonhosted.org/packages/cf/cc/916e066b7e2686999f95dde87f588be26fa1c2f05e70d9fd472fe2289c0b/multidict-6.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5363f9b2a7f3910e5c87d8b1855c478c05a2dc559ac57308117424dfaad6805c", size = 210080 }, + { url = "https://files.pythonhosted.org/packages/f8/ff/15034b18f2e4179cd559aa13bc3b376a95c22e1fd7c3b88884e078ad5466/multidict-6.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e543a40e4946cf70a88a3be87837a3ae0aebd9058ba49e91cacb0b2cd631e2b", size = 221926 }, + { url = "https://files.pythonhosted.org/packages/17/43/4243298a6b0b869a83b6331f3fcc12a2a0544c0995292ee96badf0fec6aa/multidict-6.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:60d849912350da557fe7de20aa8cf394aada6980d0052cc829eeda4a0db1c1db", size = 211318 }, + { url = "https://files.pythonhosted.org/packages/fe/80/bc43c87d60138e401c7d1818a47e5a0f748904c9f3be99012cdab5e31446/multidict-6.4.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:19d08b4f22eae45bb018b9f06e2838c1e4b853c67628ef8ae126d99de0da6395", size = 217611 }, + { url = "https://files.pythonhosted.org/packages/1e/5d/2ec94209254e48910911ac2404d71b37f06fd97ec83948a92d0c87a11d3c/multidict-6.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d693307856d1ef08041e8b6ff01d5b4618715007d288490ce2c7e29013c12b9a", size = 227893 }, + { url = "https://files.pythonhosted.org/packages/71/83/89344adc0cf08fd89d82d43de1a17a2635b03a57dfa680f6cdf2a24d481f/multidict-6.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fad6daaed41021934917f4fb03ca2db8d8a4d79bf89b17ebe77228eb6710c003", size = 221956 }, + { url = "https://files.pythonhosted.org/packages/f0/ea/81382bb59cd3a1047d1c2ea9339d2107fc918a63491bbb9399eb1aceda91/multidict-6.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c10d17371bff801af0daf8b073c30b6cf14215784dc08cd5c43ab5b7b8029bbc", size = 216850 }, + { url = "https://files.pythonhosted.org/packages/0f/90/c848d62de66c2958932ce155adae418cbf79d96cfaf992e5255819f8f1d9/multidict-6.4.4-cp39-cp39-win32.whl", hash = "sha256:7e23f2f841fcb3ebd4724a40032d32e0892fbba4143e43d2a9e7695c5e50e6bd", size = 35235 }, + { url = "https://files.pythonhosted.org/packages/d4/19/dd625207c92889c1ae7b89fcbde760d99853265cfe7ffb0826393151acd1/multidict-6.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d7b50b673ffb4ff4366e7ab43cf1f0aef4bd3608735c5fbdf0bdb6f690da411", size = 38821 }, + { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481 }, ] [[package]] @@ -580,54 +582,54 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/22/ea637422dedf0bf36f3ef238eab4e455e2a0dcc3082b5cc067615347ab8e/mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01", size = 3352570, upload-time = "2025-07-31T07:54:19.204Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/22/ea637422dedf0bf36f3ef238eab4e455e2a0dcc3082b5cc067615347ab8e/mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01", size = 3352570 } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/a9/3d7aa83955617cdf02f94e50aab5c830d205cfa4320cf124ff64acce3a8e/mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972", size = 11003299, upload-time = "2025-07-31T07:54:06.425Z" }, - { url = "https://files.pythonhosted.org/packages/83/e8/72e62ff837dd5caaac2b4a5c07ce769c8e808a00a65e5d8f94ea9c6f20ab/mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7", size = 10125451, upload-time = "2025-07-31T07:53:52.974Z" }, - { url = "https://files.pythonhosted.org/packages/7d/10/f3f3543f6448db11881776f26a0ed079865926b0c841818ee22de2c6bbab/mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df", size = 11916211, upload-time = "2025-07-31T07:53:18.879Z" }, - { url = "https://files.pythonhosted.org/packages/06/bf/63e83ed551282d67bb3f7fea2cd5561b08d2bb6eb287c096539feb5ddbc5/mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390", size = 12652687, upload-time = "2025-07-31T07:53:30.544Z" }, - { url = "https://files.pythonhosted.org/packages/69/66/68f2eeef11facf597143e85b694a161868b3b006a5fbad50e09ea117ef24/mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94", size = 12896322, upload-time = "2025-07-31T07:53:50.74Z" }, - { url = "https://files.pythonhosted.org/packages/a3/87/8e3e9c2c8bd0d7e071a89c71be28ad088aaecbadf0454f46a540bda7bca6/mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b", size = 9507962, upload-time = "2025-07-31T07:53:08.431Z" }, - { url = "https://files.pythonhosted.org/packages/46/cf/eadc80c4e0a70db1c08921dcc220357ba8ab2faecb4392e3cebeb10edbfa/mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58", size = 10921009, upload-time = "2025-07-31T07:53:23.037Z" }, - { url = "https://files.pythonhosted.org/packages/5d/c1/c869d8c067829ad30d9bdae051046561552516cfb3a14f7f0347b7d973ee/mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5", size = 10047482, upload-time = "2025-07-31T07:53:26.151Z" }, - { url = "https://files.pythonhosted.org/packages/98/b9/803672bab3fe03cee2e14786ca056efda4bb511ea02dadcedde6176d06d0/mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd", size = 11832883, upload-time = "2025-07-31T07:53:47.948Z" }, - { url = "https://files.pythonhosted.org/packages/88/fb/fcdac695beca66800918c18697b48833a9a6701de288452b6715a98cfee1/mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b", size = 12566215, upload-time = "2025-07-31T07:54:04.031Z" }, - { url = "https://files.pythonhosted.org/packages/7f/37/a932da3d3dace99ee8eb2043b6ab03b6768c36eb29a02f98f46c18c0da0e/mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5", size = 12751956, upload-time = "2025-07-31T07:53:36.263Z" }, - { url = "https://files.pythonhosted.org/packages/8c/cf/6438a429e0f2f5cab8bc83e53dbebfa666476f40ee322e13cac5e64b79e7/mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b", size = 9507307, upload-time = "2025-07-31T07:53:59.734Z" }, - { url = "https://files.pythonhosted.org/packages/17/a2/7034d0d61af8098ec47902108553122baa0f438df8a713be860f7407c9e6/mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb", size = 11086295, upload-time = "2025-07-31T07:53:28.124Z" }, - { url = "https://files.pythonhosted.org/packages/14/1f/19e7e44b594d4b12f6ba8064dbe136505cec813549ca3e5191e40b1d3cc2/mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403", size = 10112355, upload-time = "2025-07-31T07:53:21.121Z" }, - { url = "https://files.pythonhosted.org/packages/5b/69/baa33927e29e6b4c55d798a9d44db5d394072eef2bdc18c3e2048c9ed1e9/mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056", size = 11875285, upload-time = "2025-07-31T07:53:55.293Z" }, - { url = "https://files.pythonhosted.org/packages/90/13/f3a89c76b0a41e19490b01e7069713a30949d9a6c147289ee1521bcea245/mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341", size = 12737895, upload-time = "2025-07-31T07:53:43.623Z" }, - { url = "https://files.pythonhosted.org/packages/23/a1/c4ee79ac484241301564072e6476c5a5be2590bc2e7bfd28220033d2ef8f/mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb", size = 12931025, upload-time = "2025-07-31T07:54:17.125Z" }, - { url = "https://files.pythonhosted.org/packages/89/b8/7409477be7919a0608900e6320b155c72caab4fef46427c5cc75f85edadd/mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19", size = 9584664, upload-time = "2025-07-31T07:54:12.842Z" }, - { url = "https://files.pythonhosted.org/packages/5b/82/aec2fc9b9b149f372850291827537a508d6c4d3664b1750a324b91f71355/mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7", size = 11075338, upload-time = "2025-07-31T07:53:38.873Z" }, - { url = "https://files.pythonhosted.org/packages/07/ac/ee93fbde9d2242657128af8c86f5d917cd2887584cf948a8e3663d0cd737/mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81", size = 10113066, upload-time = "2025-07-31T07:54:14.707Z" }, - { url = "https://files.pythonhosted.org/packages/5a/68/946a1e0be93f17f7caa56c45844ec691ca153ee8b62f21eddda336a2d203/mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6", size = 11875473, upload-time = "2025-07-31T07:53:14.504Z" }, - { url = "https://files.pythonhosted.org/packages/9f/0f/478b4dce1cb4f43cf0f0d00fba3030b21ca04a01b74d1cd272a528cf446f/mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849", size = 12744296, upload-time = "2025-07-31T07:53:03.896Z" }, - { url = "https://files.pythonhosted.org/packages/ca/70/afa5850176379d1b303f992a828de95fc14487429a7139a4e0bdd17a8279/mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14", size = 12914657, upload-time = "2025-07-31T07:54:08.576Z" }, - { url = "https://files.pythonhosted.org/packages/53/f9/4a83e1c856a3d9c8f6edaa4749a4864ee98486e9b9dbfbc93842891029c2/mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a", size = 9593320, upload-time = "2025-07-31T07:53:01.341Z" }, - { url = "https://files.pythonhosted.org/packages/38/56/79c2fac86da57c7d8c48622a05873eaab40b905096c33597462713f5af90/mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733", size = 11040037, upload-time = "2025-07-31T07:54:10.942Z" }, - { url = "https://files.pythonhosted.org/packages/4d/c3/adabe6ff53638e3cad19e3547268482408323b1e68bf082c9119000cd049/mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd", size = 10131550, upload-time = "2025-07-31T07:53:41.307Z" }, - { url = "https://files.pythonhosted.org/packages/b8/c5/2e234c22c3bdeb23a7817af57a58865a39753bde52c74e2c661ee0cfc640/mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0", size = 11872963, upload-time = "2025-07-31T07:53:16.878Z" }, - { url = "https://files.pythonhosted.org/packages/ab/26/c13c130f35ca8caa5f2ceab68a247775648fdcd6c9a18f158825f2bc2410/mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a", size = 12710189, upload-time = "2025-07-31T07:54:01.962Z" }, - { url = "https://files.pythonhosted.org/packages/82/df/c7d79d09f6de8383fe800521d066d877e54d30b4fb94281c262be2df84ef/mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91", size = 12900322, upload-time = "2025-07-31T07:53:10.551Z" }, - { url = "https://files.pythonhosted.org/packages/b8/98/3d5a48978b4f708c55ae832619addc66d677f6dc59f3ebad71bae8285ca6/mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed", size = 9751879, upload-time = "2025-07-31T07:52:56.683Z" }, - { url = "https://files.pythonhosted.org/packages/29/cb/673e3d34e5d8de60b3a61f44f80150a738bff568cd6b7efb55742a605e98/mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9", size = 10992466, upload-time = "2025-07-31T07:53:57.574Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d0/fe1895836eea3a33ab801561987a10569df92f2d3d4715abf2cfeaa29cb2/mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99", size = 10117638, upload-time = "2025-07-31T07:53:34.256Z" }, - { url = "https://files.pythonhosted.org/packages/97/f3/514aa5532303aafb95b9ca400a31054a2bd9489de166558c2baaeea9c522/mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8", size = 11915673, upload-time = "2025-07-31T07:52:59.361Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c3/c0805f0edec96fe8e2c048b03769a6291523d509be8ee7f56ae922fa3882/mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8", size = 12649022, upload-time = "2025-07-31T07:53:45.92Z" }, - { url = "https://files.pythonhosted.org/packages/45/3e/d646b5a298ada21a8512fa7e5531f664535a495efa672601702398cea2b4/mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259", size = 12895536, upload-time = "2025-07-31T07:53:06.17Z" }, - { url = "https://files.pythonhosted.org/packages/14/55/e13d0dcd276975927d1f4e9e2ec4fd409e199f01bdc671717e673cc63a22/mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d", size = 9512564, upload-time = "2025-07-31T07:53:12.346Z" }, - { url = "https://files.pythonhosted.org/packages/1d/f3/8fcd2af0f5b806f6cf463efaffd3c9548a28f84220493ecd38d127b6b66d/mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9", size = 2283411, upload-time = "2025-07-31T07:53:24.664Z" }, + { url = "https://files.pythonhosted.org/packages/77/a9/3d7aa83955617cdf02f94e50aab5c830d205cfa4320cf124ff64acce3a8e/mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972", size = 11003299 }, + { url = "https://files.pythonhosted.org/packages/83/e8/72e62ff837dd5caaac2b4a5c07ce769c8e808a00a65e5d8f94ea9c6f20ab/mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7", size = 10125451 }, + { url = "https://files.pythonhosted.org/packages/7d/10/f3f3543f6448db11881776f26a0ed079865926b0c841818ee22de2c6bbab/mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df", size = 11916211 }, + { url = "https://files.pythonhosted.org/packages/06/bf/63e83ed551282d67bb3f7fea2cd5561b08d2bb6eb287c096539feb5ddbc5/mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390", size = 12652687 }, + { url = "https://files.pythonhosted.org/packages/69/66/68f2eeef11facf597143e85b694a161868b3b006a5fbad50e09ea117ef24/mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94", size = 12896322 }, + { url = "https://files.pythonhosted.org/packages/a3/87/8e3e9c2c8bd0d7e071a89c71be28ad088aaecbadf0454f46a540bda7bca6/mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b", size = 9507962 }, + { url = "https://files.pythonhosted.org/packages/46/cf/eadc80c4e0a70db1c08921dcc220357ba8ab2faecb4392e3cebeb10edbfa/mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58", size = 10921009 }, + { url = "https://files.pythonhosted.org/packages/5d/c1/c869d8c067829ad30d9bdae051046561552516cfb3a14f7f0347b7d973ee/mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5", size = 10047482 }, + { url = "https://files.pythonhosted.org/packages/98/b9/803672bab3fe03cee2e14786ca056efda4bb511ea02dadcedde6176d06d0/mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd", size = 11832883 }, + { url = "https://files.pythonhosted.org/packages/88/fb/fcdac695beca66800918c18697b48833a9a6701de288452b6715a98cfee1/mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b", size = 12566215 }, + { url = "https://files.pythonhosted.org/packages/7f/37/a932da3d3dace99ee8eb2043b6ab03b6768c36eb29a02f98f46c18c0da0e/mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5", size = 12751956 }, + { url = "https://files.pythonhosted.org/packages/8c/cf/6438a429e0f2f5cab8bc83e53dbebfa666476f40ee322e13cac5e64b79e7/mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b", size = 9507307 }, + { url = "https://files.pythonhosted.org/packages/17/a2/7034d0d61af8098ec47902108553122baa0f438df8a713be860f7407c9e6/mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb", size = 11086295 }, + { url = "https://files.pythonhosted.org/packages/14/1f/19e7e44b594d4b12f6ba8064dbe136505cec813549ca3e5191e40b1d3cc2/mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403", size = 10112355 }, + { url = "https://files.pythonhosted.org/packages/5b/69/baa33927e29e6b4c55d798a9d44db5d394072eef2bdc18c3e2048c9ed1e9/mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056", size = 11875285 }, + { url = "https://files.pythonhosted.org/packages/90/13/f3a89c76b0a41e19490b01e7069713a30949d9a6c147289ee1521bcea245/mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341", size = 12737895 }, + { url = "https://files.pythonhosted.org/packages/23/a1/c4ee79ac484241301564072e6476c5a5be2590bc2e7bfd28220033d2ef8f/mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb", size = 12931025 }, + { url = "https://files.pythonhosted.org/packages/89/b8/7409477be7919a0608900e6320b155c72caab4fef46427c5cc75f85edadd/mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19", size = 9584664 }, + { url = "https://files.pythonhosted.org/packages/5b/82/aec2fc9b9b149f372850291827537a508d6c4d3664b1750a324b91f71355/mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7", size = 11075338 }, + { url = "https://files.pythonhosted.org/packages/07/ac/ee93fbde9d2242657128af8c86f5d917cd2887584cf948a8e3663d0cd737/mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81", size = 10113066 }, + { url = "https://files.pythonhosted.org/packages/5a/68/946a1e0be93f17f7caa56c45844ec691ca153ee8b62f21eddda336a2d203/mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6", size = 11875473 }, + { url = "https://files.pythonhosted.org/packages/9f/0f/478b4dce1cb4f43cf0f0d00fba3030b21ca04a01b74d1cd272a528cf446f/mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849", size = 12744296 }, + { url = "https://files.pythonhosted.org/packages/ca/70/afa5850176379d1b303f992a828de95fc14487429a7139a4e0bdd17a8279/mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14", size = 12914657 }, + { url = "https://files.pythonhosted.org/packages/53/f9/4a83e1c856a3d9c8f6edaa4749a4864ee98486e9b9dbfbc93842891029c2/mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a", size = 9593320 }, + { url = "https://files.pythonhosted.org/packages/38/56/79c2fac86da57c7d8c48622a05873eaab40b905096c33597462713f5af90/mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733", size = 11040037 }, + { url = "https://files.pythonhosted.org/packages/4d/c3/adabe6ff53638e3cad19e3547268482408323b1e68bf082c9119000cd049/mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd", size = 10131550 }, + { url = "https://files.pythonhosted.org/packages/b8/c5/2e234c22c3bdeb23a7817af57a58865a39753bde52c74e2c661ee0cfc640/mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0", size = 11872963 }, + { url = "https://files.pythonhosted.org/packages/ab/26/c13c130f35ca8caa5f2ceab68a247775648fdcd6c9a18f158825f2bc2410/mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a", size = 12710189 }, + { url = "https://files.pythonhosted.org/packages/82/df/c7d79d09f6de8383fe800521d066d877e54d30b4fb94281c262be2df84ef/mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91", size = 12900322 }, + { url = "https://files.pythonhosted.org/packages/b8/98/3d5a48978b4f708c55ae832619addc66d677f6dc59f3ebad71bae8285ca6/mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed", size = 9751879 }, + { url = "https://files.pythonhosted.org/packages/29/cb/673e3d34e5d8de60b3a61f44f80150a738bff568cd6b7efb55742a605e98/mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9", size = 10992466 }, + { url = "https://files.pythonhosted.org/packages/0c/d0/fe1895836eea3a33ab801561987a10569df92f2d3d4715abf2cfeaa29cb2/mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99", size = 10117638 }, + { url = "https://files.pythonhosted.org/packages/97/f3/514aa5532303aafb95b9ca400a31054a2bd9489de166558c2baaeea9c522/mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8", size = 11915673 }, + { url = "https://files.pythonhosted.org/packages/ab/c3/c0805f0edec96fe8e2c048b03769a6291523d509be8ee7f56ae922fa3882/mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8", size = 12649022 }, + { url = "https://files.pythonhosted.org/packages/45/3e/d646b5a298ada21a8512fa7e5531f664535a495efa672601702398cea2b4/mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259", size = 12895536 }, + { url = "https://files.pythonhosted.org/packages/14/55/e13d0dcd276975927d1f4e9e2ec4fd409e199f01bdc671717e673cc63a22/mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d", size = 9512564 }, + { url = "https://files.pythonhosted.org/packages/1d/f3/8fcd2af0f5b806f6cf463efaffd3c9548a28f84220493ecd38d127b6b66d/mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9", size = 2283411 }, ] [[package]] name = "mypy-extensions" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, ] [[package]] @@ -638,52 +640,52 @@ resolution-markers = [ "python_full_version < '3.10' and platform_python_implementation == 'PyPy'", "python_full_version < '3.10' and platform_python_implementation != 'PyPy'", ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015, upload-time = "2024-08-26T20:19:40.945Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015 } wheels = [ - { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245, upload-time = "2024-08-26T20:04:14.625Z" }, - { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540, upload-time = "2024-08-26T20:04:36.784Z" }, - { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623, upload-time = "2024-08-26T20:04:46.491Z" }, - { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774, upload-time = "2024-08-26T20:04:58.173Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081, upload-time = "2024-08-26T20:05:19.098Z" }, - { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451, upload-time = "2024-08-26T20:05:47.479Z" }, - { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572, upload-time = "2024-08-26T20:06:17.137Z" }, - { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722, upload-time = "2024-08-26T20:06:39.16Z" }, - { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170, upload-time = "2024-08-26T20:06:50.361Z" }, - { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558, upload-time = "2024-08-26T20:07:13.881Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137, upload-time = "2024-08-26T20:07:45.345Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552, upload-time = "2024-08-26T20:08:06.666Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957, upload-time = "2024-08-26T20:08:15.83Z" }, - { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573, upload-time = "2024-08-26T20:08:27.185Z" }, - { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330, upload-time = "2024-08-26T20:08:48.058Z" }, - { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895, upload-time = "2024-08-26T20:09:16.536Z" }, - { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253, upload-time = "2024-08-26T20:09:46.263Z" }, - { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074, upload-time = "2024-08-26T20:10:08.483Z" }, - { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640, upload-time = "2024-08-26T20:10:19.732Z" }, - { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230, upload-time = "2024-08-26T20:10:43.413Z" }, - { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803, upload-time = "2024-08-26T20:11:13.916Z" }, - { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835, upload-time = "2024-08-26T20:11:34.779Z" }, - { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499, upload-time = "2024-08-26T20:11:43.902Z" }, - { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497, upload-time = "2024-08-26T20:11:55.09Z" }, - { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158, upload-time = "2024-08-26T20:12:14.95Z" }, - { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173, upload-time = "2024-08-26T20:12:44.049Z" }, - { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174, upload-time = "2024-08-26T20:13:13.634Z" }, - { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701, upload-time = "2024-08-26T20:13:34.851Z" }, - { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313, upload-time = "2024-08-26T20:13:45.653Z" }, - { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179, upload-time = "2024-08-26T20:14:08.786Z" }, - { url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942, upload-time = "2024-08-26T20:14:40.108Z" }, - { url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512, upload-time = "2024-08-26T20:15:00.985Z" }, - { url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976, upload-time = "2024-08-26T20:15:10.876Z" }, - { url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494, upload-time = "2024-08-26T20:15:22.055Z" }, - { url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596, upload-time = "2024-08-26T20:15:42.452Z" }, - { url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099, upload-time = "2024-08-26T20:16:11.048Z" }, - { url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823, upload-time = "2024-08-26T20:16:40.171Z" }, - { url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424, upload-time = "2024-08-26T20:17:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809, upload-time = "2024-08-26T20:17:13.553Z" }, - { url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314, upload-time = "2024-08-26T20:17:36.72Z" }, - { url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288, upload-time = "2024-08-26T20:18:07.732Z" }, - { url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793, upload-time = "2024-08-26T20:18:19.125Z" }, - { url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885, upload-time = "2024-08-26T20:18:47.237Z" }, - { url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784, upload-time = "2024-08-26T20:19:11.19Z" }, + { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245 }, + { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540 }, + { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623 }, + { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774 }, + { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081 }, + { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451 }, + { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572 }, + { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722 }, + { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170 }, + { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558 }, + { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137 }, + { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552 }, + { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957 }, + { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573 }, + { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330 }, + { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895 }, + { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253 }, + { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640 }, + { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230 }, + { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803 }, + { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835 }, + { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499 }, + { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497 }, + { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158 }, + { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174 }, + { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701 }, + { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313 }, + { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179 }, + { url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942 }, + { url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512 }, + { url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976 }, + { url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494 }, + { url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596 }, + { url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099 }, + { url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823 }, + { url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424 }, + { url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809 }, + { url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314 }, + { url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288 }, + { url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793 }, + { url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885 }, + { url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784 }, ] [[package]] @@ -698,285 +700,285 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.12.4' and platform_python_implementation == 'PyPy'", "python_full_version >= '3.10' and python_full_version < '3.12.4' and platform_python_implementation != 'PyPy'", ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/78/31103410a57bc2c2b93a3597340a8119588571f6a4539067546cb9a0bfac/numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f", size = 20270701, upload-time = "2025-03-16T18:27:00.648Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/78/31103410a57bc2c2b93a3597340a8119588571f6a4539067546cb9a0bfac/numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f", size = 20270701 } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/89/a79e86e5c1433926ed7d60cb267fb64aa578b6101ab645800fd43b4801de/numpy-2.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9", size = 21250661, upload-time = "2025-03-16T18:02:13.017Z" }, - { url = "https://files.pythonhosted.org/packages/79/c2/f50921beb8afd60ed9589ad880332cfefdb805422210d327fb48f12b7a81/numpy-2.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae", size = 14389926, upload-time = "2025-03-16T18:02:39.022Z" }, - { url = "https://files.pythonhosted.org/packages/c7/b9/2c4e96130b0b0f97b0ef4a06d6dae3b39d058b21a5e2fa2decd7fd6b1c8f/numpy-2.2.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775", size = 5428329, upload-time = "2025-03-16T18:02:50.032Z" }, - { url = "https://files.pythonhosted.org/packages/7f/a5/3d7094aa898f4fc5c84cdfb26beeae780352d43f5d8bdec966c4393d644c/numpy-2.2.4-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9", size = 6963559, upload-time = "2025-03-16T18:03:02.523Z" }, - { url = "https://files.pythonhosted.org/packages/4c/22/fb1be710a14434c09080dd4a0acc08939f612ec02efcb04b9e210474782d/numpy-2.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2", size = 14368066, upload-time = "2025-03-16T18:03:27.146Z" }, - { url = "https://files.pythonhosted.org/packages/c2/07/2e5cc71193e3ef3a219ffcf6ca4858e46ea2be09c026ddd480d596b32867/numpy-2.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020", size = 16417040, upload-time = "2025-03-16T18:03:55.999Z" }, - { url = "https://files.pythonhosted.org/packages/1a/97/3b1537776ad9a6d1a41813818343745e8dd928a2916d4c9edcd9a8af1dac/numpy-2.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3", size = 15879862, upload-time = "2025-03-16T18:04:23.56Z" }, - { url = "https://files.pythonhosted.org/packages/b0/b7/4472f603dd45ef36ff3d8e84e84fe02d9467c78f92cc121633dce6da307b/numpy-2.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017", size = 18206032, upload-time = "2025-03-16T18:04:53.694Z" }, - { url = "https://files.pythonhosted.org/packages/0d/bd/6a092963fb82e6c5aa0d0440635827bbb2910da229545473bbb58c537ed3/numpy-2.2.4-cp310-cp310-win32.whl", hash = "sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a", size = 6608517, upload-time = "2025-03-16T18:05:06.647Z" }, - { url = "https://files.pythonhosted.org/packages/01/e3/cb04627bc2a1638948bc13e818df26495aa18e20d5be1ed95ab2b10b6847/numpy-2.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542", size = 12943498, upload-time = "2025-03-16T18:05:28.591Z" }, - { url = "https://files.pythonhosted.org/packages/16/fb/09e778ee3a8ea0d4dc8329cca0a9c9e65fed847d08e37eba74cb7ed4b252/numpy-2.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4", size = 21254989, upload-time = "2025-03-16T18:06:04.092Z" }, - { url = "https://files.pythonhosted.org/packages/a2/0a/1212befdbecab5d80eca3cde47d304cad986ad4eec7d85a42e0b6d2cc2ef/numpy-2.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4", size = 14425910, upload-time = "2025-03-16T18:06:29.062Z" }, - { url = "https://files.pythonhosted.org/packages/2b/3e/e7247c1d4f15086bb106c8d43c925b0b2ea20270224f5186fa48d4fb5cbd/numpy-2.2.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f", size = 5426490, upload-time = "2025-03-16T18:06:39.901Z" }, - { url = "https://files.pythonhosted.org/packages/5d/fa/aa7cd6be51419b894c5787a8a93c3302a1ed4f82d35beb0613ec15bdd0e2/numpy-2.2.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880", size = 6967754, upload-time = "2025-03-16T18:06:52.658Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ee/96457c943265de9fadeb3d2ffdbab003f7fba13d971084a9876affcda095/numpy-2.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1", size = 14373079, upload-time = "2025-03-16T18:07:16.297Z" }, - { url = "https://files.pythonhosted.org/packages/c5/5c/ceefca458559f0ccc7a982319f37ed07b0d7b526964ae6cc61f8ad1b6119/numpy-2.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5", size = 16428819, upload-time = "2025-03-16T18:07:44.188Z" }, - { url = "https://files.pythonhosted.org/packages/22/31/9b2ac8eee99e001eb6add9fa27514ef5e9faf176169057a12860af52704c/numpy-2.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687", size = 15881470, upload-time = "2025-03-16T18:08:11.545Z" }, - { url = "https://files.pythonhosted.org/packages/f0/dc/8569b5f25ff30484b555ad8a3f537e0225d091abec386c9420cf5f7a2976/numpy-2.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6", size = 18218144, upload-time = "2025-03-16T18:08:42.042Z" }, - { url = "https://files.pythonhosted.org/packages/5e/05/463c023a39bdeb9bb43a99e7dee2c664cb68d5bb87d14f92482b9f6011cc/numpy-2.2.4-cp311-cp311-win32.whl", hash = "sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09", size = 6606368, upload-time = "2025-03-16T18:08:55.074Z" }, - { url = "https://files.pythonhosted.org/packages/8b/72/10c1d2d82101c468a28adc35de6c77b308f288cfd0b88e1070f15b98e00c/numpy-2.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91", size = 12947526, upload-time = "2025-03-16T18:09:16.844Z" }, - { url = "https://files.pythonhosted.org/packages/a2/30/182db21d4f2a95904cec1a6f779479ea1ac07c0647f064dea454ec650c42/numpy-2.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4", size = 20947156, upload-time = "2025-03-16T18:09:51.975Z" }, - { url = "https://files.pythonhosted.org/packages/24/6d/9483566acfbda6c62c6bc74b6e981c777229d2af93c8eb2469b26ac1b7bc/numpy-2.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854", size = 14133092, upload-time = "2025-03-16T18:10:16.329Z" }, - { url = "https://files.pythonhosted.org/packages/27/f6/dba8a258acbf9d2bed2525cdcbb9493ef9bae5199d7a9cb92ee7e9b2aea6/numpy-2.2.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24", size = 5163515, upload-time = "2025-03-16T18:10:26.19Z" }, - { url = "https://files.pythonhosted.org/packages/62/30/82116199d1c249446723c68f2c9da40d7f062551036f50b8c4caa42ae252/numpy-2.2.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee", size = 6696558, upload-time = "2025-03-16T18:10:38.996Z" }, - { url = "https://files.pythonhosted.org/packages/0e/b2/54122b3c6df5df3e87582b2e9430f1bdb63af4023c739ba300164c9ae503/numpy-2.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba", size = 14084742, upload-time = "2025-03-16T18:11:02.76Z" }, - { url = "https://files.pythonhosted.org/packages/02/e2/e2cbb8d634151aab9528ef7b8bab52ee4ab10e076509285602c2a3a686e0/numpy-2.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592", size = 16134051, upload-time = "2025-03-16T18:11:32.767Z" }, - { url = "https://files.pythonhosted.org/packages/8e/21/efd47800e4affc993e8be50c1b768de038363dd88865920439ef7b422c60/numpy-2.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb", size = 15578972, upload-time = "2025-03-16T18:11:59.877Z" }, - { url = "https://files.pythonhosted.org/packages/04/1e/f8bb88f6157045dd5d9b27ccf433d016981032690969aa5c19e332b138c0/numpy-2.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f", size = 17898106, upload-time = "2025-03-16T18:12:31.487Z" }, - { url = "https://files.pythonhosted.org/packages/2b/93/df59a5a3897c1f036ae8ff845e45f4081bb06943039ae28a3c1c7c780f22/numpy-2.2.4-cp312-cp312-win32.whl", hash = "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00", size = 6311190, upload-time = "2025-03-16T18:12:44.46Z" }, - { url = "https://files.pythonhosted.org/packages/46/69/8c4f928741c2a8efa255fdc7e9097527c6dc4e4df147e3cadc5d9357ce85/numpy-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146", size = 12644305, upload-time = "2025-03-16T18:13:06.864Z" }, - { url = "https://files.pythonhosted.org/packages/2a/d0/bd5ad792e78017f5decfb2ecc947422a3669a34f775679a76317af671ffc/numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", size = 20933623, upload-time = "2025-03-16T18:13:43.231Z" }, - { url = "https://files.pythonhosted.org/packages/c3/bc/2b3545766337b95409868f8e62053135bdc7fa2ce630aba983a2aa60b559/numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", size = 14148681, upload-time = "2025-03-16T18:14:08.031Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/67b24d68a56551d43a6ec9fe8c5f91b526d4c1a46a6387b956bf2d64744e/numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", size = 5148759, upload-time = "2025-03-16T18:14:18.613Z" }, - { url = "https://files.pythonhosted.org/packages/1c/8b/e2fc8a75fcb7be12d90b31477c9356c0cbb44abce7ffb36be39a0017afad/numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", size = 6683092, upload-time = "2025-03-16T18:14:31.386Z" }, - { url = "https://files.pythonhosted.org/packages/13/73/41b7b27f169ecf368b52533edb72e56a133f9e86256e809e169362553b49/numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", size = 14081422, upload-time = "2025-03-16T18:14:54.83Z" }, - { url = "https://files.pythonhosted.org/packages/4b/04/e208ff3ae3ddfbafc05910f89546382f15a3f10186b1f56bd99f159689c2/numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7", size = 16132202, upload-time = "2025-03-16T18:15:22.035Z" }, - { url = "https://files.pythonhosted.org/packages/fe/bc/2218160574d862d5e55f803d88ddcad88beff94791f9c5f86d67bd8fbf1c/numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", size = 15573131, upload-time = "2025-03-16T18:15:48.546Z" }, - { url = "https://files.pythonhosted.org/packages/a5/78/97c775bc4f05abc8a8426436b7cb1be806a02a2994b195945600855e3a25/numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", size = 17894270, upload-time = "2025-03-16T18:16:20.274Z" }, - { url = "https://files.pythonhosted.org/packages/b9/eb/38c06217a5f6de27dcb41524ca95a44e395e6a1decdc0c99fec0832ce6ae/numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c", size = 6308141, upload-time = "2025-03-16T18:20:15.297Z" }, - { url = "https://files.pythonhosted.org/packages/52/17/d0dd10ab6d125c6d11ffb6dfa3423c3571befab8358d4f85cd4471964fcd/numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", size = 12636885, upload-time = "2025-03-16T18:20:36.982Z" }, - { url = "https://files.pythonhosted.org/packages/fa/e2/793288ede17a0fdc921172916efb40f3cbc2aa97e76c5c84aba6dc7e8747/numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", size = 20961829, upload-time = "2025-03-16T18:16:56.191Z" }, - { url = "https://files.pythonhosted.org/packages/3a/75/bb4573f6c462afd1ea5cbedcc362fe3e9bdbcc57aefd37c681be1155fbaa/numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39", size = 14161419, upload-time = "2025-03-16T18:17:22.811Z" }, - { url = "https://files.pythonhosted.org/packages/03/68/07b4cd01090ca46c7a336958b413cdbe75002286295f2addea767b7f16c9/numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd", size = 5196414, upload-time = "2025-03-16T18:17:34.066Z" }, - { url = "https://files.pythonhosted.org/packages/a5/fd/d4a29478d622fedff5c4b4b4cedfc37a00691079623c0575978d2446db9e/numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0", size = 6709379, upload-time = "2025-03-16T18:17:47.466Z" }, - { url = "https://files.pythonhosted.org/packages/41/78/96dddb75bb9be730b87c72f30ffdd62611aba234e4e460576a068c98eff6/numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960", size = 14051725, upload-time = "2025-03-16T18:18:11.904Z" }, - { url = "https://files.pythonhosted.org/packages/00/06/5306b8199bffac2a29d9119c11f457f6c7d41115a335b78d3f86fad4dbe8/numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8", size = 16101638, upload-time = "2025-03-16T18:18:40.749Z" }, - { url = "https://files.pythonhosted.org/packages/fa/03/74c5b631ee1ded596945c12027649e6344614144369fd3ec1aaced782882/numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc", size = 15571717, upload-time = "2025-03-16T18:19:04.512Z" }, - { url = "https://files.pythonhosted.org/packages/cb/dc/4fc7c0283abe0981e3b89f9b332a134e237dd476b0c018e1e21083310c31/numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff", size = 17879998, upload-time = "2025-03-16T18:19:32.52Z" }, - { url = "https://files.pythonhosted.org/packages/e5/2b/878576190c5cfa29ed896b518cc516aecc7c98a919e20706c12480465f43/numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", size = 6366896, upload-time = "2025-03-16T18:19:43.55Z" }, - { url = "https://files.pythonhosted.org/packages/3e/05/eb7eec66b95cf697f08c754ef26c3549d03ebd682819f794cb039574a0a6/numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", size = 12739119, upload-time = "2025-03-16T18:20:03.94Z" }, - { url = "https://files.pythonhosted.org/packages/b2/5c/f09c33a511aff41a098e6ef3498465d95f6360621034a3d95f47edbc9119/numpy-2.2.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8", size = 21081956, upload-time = "2025-03-16T18:21:12.955Z" }, - { url = "https://files.pythonhosted.org/packages/ba/30/74c48b3b6494c4b820b7fa1781d441e94d87a08daa5b35d222f06ba41a6f/numpy-2.2.4-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c", size = 6827143, upload-time = "2025-03-16T18:21:26.748Z" }, - { url = "https://files.pythonhosted.org/packages/54/f5/ab0d2f48b490535c7a80e05da4a98902b632369efc04f0e47bb31ca97d8f/numpy-2.2.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d", size = 16233350, upload-time = "2025-03-16T18:21:53.902Z" }, - { url = "https://files.pythonhosted.org/packages/3b/3a/2f6d8c1f8e45d496bca6baaec93208035faeb40d5735c25afac092ec9a12/numpy-2.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d", size = 12857565, upload-time = "2025-03-16T18:22:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/04/89/a79e86e5c1433926ed7d60cb267fb64aa578b6101ab645800fd43b4801de/numpy-2.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9", size = 21250661 }, + { url = "https://files.pythonhosted.org/packages/79/c2/f50921beb8afd60ed9589ad880332cfefdb805422210d327fb48f12b7a81/numpy-2.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae", size = 14389926 }, + { url = "https://files.pythonhosted.org/packages/c7/b9/2c4e96130b0b0f97b0ef4a06d6dae3b39d058b21a5e2fa2decd7fd6b1c8f/numpy-2.2.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775", size = 5428329 }, + { url = "https://files.pythonhosted.org/packages/7f/a5/3d7094aa898f4fc5c84cdfb26beeae780352d43f5d8bdec966c4393d644c/numpy-2.2.4-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9", size = 6963559 }, + { url = "https://files.pythonhosted.org/packages/4c/22/fb1be710a14434c09080dd4a0acc08939f612ec02efcb04b9e210474782d/numpy-2.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2", size = 14368066 }, + { url = "https://files.pythonhosted.org/packages/c2/07/2e5cc71193e3ef3a219ffcf6ca4858e46ea2be09c026ddd480d596b32867/numpy-2.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020", size = 16417040 }, + { url = "https://files.pythonhosted.org/packages/1a/97/3b1537776ad9a6d1a41813818343745e8dd928a2916d4c9edcd9a8af1dac/numpy-2.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3", size = 15879862 }, + { url = "https://files.pythonhosted.org/packages/b0/b7/4472f603dd45ef36ff3d8e84e84fe02d9467c78f92cc121633dce6da307b/numpy-2.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017", size = 18206032 }, + { url = "https://files.pythonhosted.org/packages/0d/bd/6a092963fb82e6c5aa0d0440635827bbb2910da229545473bbb58c537ed3/numpy-2.2.4-cp310-cp310-win32.whl", hash = "sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a", size = 6608517 }, + { url = "https://files.pythonhosted.org/packages/01/e3/cb04627bc2a1638948bc13e818df26495aa18e20d5be1ed95ab2b10b6847/numpy-2.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542", size = 12943498 }, + { url = "https://files.pythonhosted.org/packages/16/fb/09e778ee3a8ea0d4dc8329cca0a9c9e65fed847d08e37eba74cb7ed4b252/numpy-2.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4", size = 21254989 }, + { url = "https://files.pythonhosted.org/packages/a2/0a/1212befdbecab5d80eca3cde47d304cad986ad4eec7d85a42e0b6d2cc2ef/numpy-2.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4", size = 14425910 }, + { url = "https://files.pythonhosted.org/packages/2b/3e/e7247c1d4f15086bb106c8d43c925b0b2ea20270224f5186fa48d4fb5cbd/numpy-2.2.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f", size = 5426490 }, + { url = "https://files.pythonhosted.org/packages/5d/fa/aa7cd6be51419b894c5787a8a93c3302a1ed4f82d35beb0613ec15bdd0e2/numpy-2.2.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880", size = 6967754 }, + { url = "https://files.pythonhosted.org/packages/d5/ee/96457c943265de9fadeb3d2ffdbab003f7fba13d971084a9876affcda095/numpy-2.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1", size = 14373079 }, + { url = "https://files.pythonhosted.org/packages/c5/5c/ceefca458559f0ccc7a982319f37ed07b0d7b526964ae6cc61f8ad1b6119/numpy-2.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5", size = 16428819 }, + { url = "https://files.pythonhosted.org/packages/22/31/9b2ac8eee99e001eb6add9fa27514ef5e9faf176169057a12860af52704c/numpy-2.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687", size = 15881470 }, + { url = "https://files.pythonhosted.org/packages/f0/dc/8569b5f25ff30484b555ad8a3f537e0225d091abec386c9420cf5f7a2976/numpy-2.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6", size = 18218144 }, + { url = "https://files.pythonhosted.org/packages/5e/05/463c023a39bdeb9bb43a99e7dee2c664cb68d5bb87d14f92482b9f6011cc/numpy-2.2.4-cp311-cp311-win32.whl", hash = "sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09", size = 6606368 }, + { url = "https://files.pythonhosted.org/packages/8b/72/10c1d2d82101c468a28adc35de6c77b308f288cfd0b88e1070f15b98e00c/numpy-2.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91", size = 12947526 }, + { url = "https://files.pythonhosted.org/packages/a2/30/182db21d4f2a95904cec1a6f779479ea1ac07c0647f064dea454ec650c42/numpy-2.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4", size = 20947156 }, + { url = "https://files.pythonhosted.org/packages/24/6d/9483566acfbda6c62c6bc74b6e981c777229d2af93c8eb2469b26ac1b7bc/numpy-2.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854", size = 14133092 }, + { url = "https://files.pythonhosted.org/packages/27/f6/dba8a258acbf9d2bed2525cdcbb9493ef9bae5199d7a9cb92ee7e9b2aea6/numpy-2.2.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24", size = 5163515 }, + { url = "https://files.pythonhosted.org/packages/62/30/82116199d1c249446723c68f2c9da40d7f062551036f50b8c4caa42ae252/numpy-2.2.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee", size = 6696558 }, + { url = "https://files.pythonhosted.org/packages/0e/b2/54122b3c6df5df3e87582b2e9430f1bdb63af4023c739ba300164c9ae503/numpy-2.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba", size = 14084742 }, + { url = "https://files.pythonhosted.org/packages/02/e2/e2cbb8d634151aab9528ef7b8bab52ee4ab10e076509285602c2a3a686e0/numpy-2.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592", size = 16134051 }, + { url = "https://files.pythonhosted.org/packages/8e/21/efd47800e4affc993e8be50c1b768de038363dd88865920439ef7b422c60/numpy-2.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb", size = 15578972 }, + { url = "https://files.pythonhosted.org/packages/04/1e/f8bb88f6157045dd5d9b27ccf433d016981032690969aa5c19e332b138c0/numpy-2.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f", size = 17898106 }, + { url = "https://files.pythonhosted.org/packages/2b/93/df59a5a3897c1f036ae8ff845e45f4081bb06943039ae28a3c1c7c780f22/numpy-2.2.4-cp312-cp312-win32.whl", hash = "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00", size = 6311190 }, + { url = "https://files.pythonhosted.org/packages/46/69/8c4f928741c2a8efa255fdc7e9097527c6dc4e4df147e3cadc5d9357ce85/numpy-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146", size = 12644305 }, + { url = "https://files.pythonhosted.org/packages/2a/d0/bd5ad792e78017f5decfb2ecc947422a3669a34f775679a76317af671ffc/numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", size = 20933623 }, + { url = "https://files.pythonhosted.org/packages/c3/bc/2b3545766337b95409868f8e62053135bdc7fa2ce630aba983a2aa60b559/numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", size = 14148681 }, + { url = "https://files.pythonhosted.org/packages/6a/70/67b24d68a56551d43a6ec9fe8c5f91b526d4c1a46a6387b956bf2d64744e/numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", size = 5148759 }, + { url = "https://files.pythonhosted.org/packages/1c/8b/e2fc8a75fcb7be12d90b31477c9356c0cbb44abce7ffb36be39a0017afad/numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", size = 6683092 }, + { url = "https://files.pythonhosted.org/packages/13/73/41b7b27f169ecf368b52533edb72e56a133f9e86256e809e169362553b49/numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", size = 14081422 }, + { url = "https://files.pythonhosted.org/packages/4b/04/e208ff3ae3ddfbafc05910f89546382f15a3f10186b1f56bd99f159689c2/numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7", size = 16132202 }, + { url = "https://files.pythonhosted.org/packages/fe/bc/2218160574d862d5e55f803d88ddcad88beff94791f9c5f86d67bd8fbf1c/numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", size = 15573131 }, + { url = "https://files.pythonhosted.org/packages/a5/78/97c775bc4f05abc8a8426436b7cb1be806a02a2994b195945600855e3a25/numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", size = 17894270 }, + { url = "https://files.pythonhosted.org/packages/b9/eb/38c06217a5f6de27dcb41524ca95a44e395e6a1decdc0c99fec0832ce6ae/numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c", size = 6308141 }, + { url = "https://files.pythonhosted.org/packages/52/17/d0dd10ab6d125c6d11ffb6dfa3423c3571befab8358d4f85cd4471964fcd/numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", size = 12636885 }, + { url = "https://files.pythonhosted.org/packages/fa/e2/793288ede17a0fdc921172916efb40f3cbc2aa97e76c5c84aba6dc7e8747/numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", size = 20961829 }, + { url = "https://files.pythonhosted.org/packages/3a/75/bb4573f6c462afd1ea5cbedcc362fe3e9bdbcc57aefd37c681be1155fbaa/numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39", size = 14161419 }, + { url = "https://files.pythonhosted.org/packages/03/68/07b4cd01090ca46c7a336958b413cdbe75002286295f2addea767b7f16c9/numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd", size = 5196414 }, + { url = "https://files.pythonhosted.org/packages/a5/fd/d4a29478d622fedff5c4b4b4cedfc37a00691079623c0575978d2446db9e/numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0", size = 6709379 }, + { url = "https://files.pythonhosted.org/packages/41/78/96dddb75bb9be730b87c72f30ffdd62611aba234e4e460576a068c98eff6/numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960", size = 14051725 }, + { url = "https://files.pythonhosted.org/packages/00/06/5306b8199bffac2a29d9119c11f457f6c7d41115a335b78d3f86fad4dbe8/numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8", size = 16101638 }, + { url = "https://files.pythonhosted.org/packages/fa/03/74c5b631ee1ded596945c12027649e6344614144369fd3ec1aaced782882/numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc", size = 15571717 }, + { url = "https://files.pythonhosted.org/packages/cb/dc/4fc7c0283abe0981e3b89f9b332a134e237dd476b0c018e1e21083310c31/numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff", size = 17879998 }, + { url = "https://files.pythonhosted.org/packages/e5/2b/878576190c5cfa29ed896b518cc516aecc7c98a919e20706c12480465f43/numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", size = 6366896 }, + { url = "https://files.pythonhosted.org/packages/3e/05/eb7eec66b95cf697f08c754ef26c3549d03ebd682819f794cb039574a0a6/numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", size = 12739119 }, + { url = "https://files.pythonhosted.org/packages/b2/5c/f09c33a511aff41a098e6ef3498465d95f6360621034a3d95f47edbc9119/numpy-2.2.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8", size = 21081956 }, + { url = "https://files.pythonhosted.org/packages/ba/30/74c48b3b6494c4b820b7fa1781d441e94d87a08daa5b35d222f06ba41a6f/numpy-2.2.4-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c", size = 6827143 }, + { url = "https://files.pythonhosted.org/packages/54/f5/ab0d2f48b490535c7a80e05da4a98902b632369efc04f0e47bb31ca97d8f/numpy-2.2.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d", size = 16233350 }, + { url = "https://files.pythonhosted.org/packages/3b/3a/2f6d8c1f8e45d496bca6baaec93208035faeb40d5735c25afac092ec9a12/numpy-2.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d", size = 12857565 }, ] [[package]] name = "orjson" version = "3.10.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/5dea21763eeff8c1590076918a446ea3d6140743e0e36f58f369928ed0f4/orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e", size = 5282482, upload-time = "2025-01-18T15:55:28.817Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/5dea21763eeff8c1590076918a446ea3d6140743e0e36f58f369928ed0f4/orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e", size = 5282482 } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/09/e5ff18ad009e6f97eb7edc5f67ef98b3ce0c189da9c3eaca1f9587cd4c61/orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04", size = 249532, upload-time = "2025-01-18T15:53:17.717Z" }, - { url = "https://files.pythonhosted.org/packages/bd/b8/a75883301fe332bd433d9b0ded7d2bb706ccac679602c3516984f8814fb5/orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8", size = 125229, upload-time = "2025-01-18T18:11:48.708Z" }, - { url = "https://files.pythonhosted.org/packages/83/4b/22f053e7a364cc9c685be203b1e40fc5f2b3f164a9b2284547504eec682e/orjson-3.10.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c2c79fa308e6edb0ffab0a31fd75a7841bf2a79a20ef08a3c6e3b26814c8ca8", size = 150148, upload-time = "2025-01-18T15:53:21.254Z" }, - { url = "https://files.pythonhosted.org/packages/63/64/1b54fc75ca328b57dd810541a4035fe48c12a161d466e3cf5b11a8c25649/orjson-3.10.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cb85490aa6bf98abd20607ab5c8324c0acb48d6da7863a51be48505646c814", size = 139748, upload-time = "2025-01-18T15:53:23.629Z" }, - { url = "https://files.pythonhosted.org/packages/5e/ff/ff0c5da781807bb0a5acd789d9a7fbcb57f7b0c6e1916595da1f5ce69f3c/orjson-3.10.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763dadac05e4e9d2bc14938a45a2d0560549561287d41c465d3c58aec818b164", size = 154559, upload-time = "2025-01-18T15:53:25.904Z" }, - { url = "https://files.pythonhosted.org/packages/4e/9a/11e2974383384ace8495810d4a2ebef5f55aacfc97b333b65e789c9d362d/orjson-3.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a330b9b4734f09a623f74a7490db713695e13b67c959713b78369f26b3dee6bf", size = 130349, upload-time = "2025-01-18T18:11:52.164Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c4/dd9583aea6aefee1b64d3aed13f51d2aadb014028bc929fe52936ec5091f/orjson-3.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a61a4622b7ff861f019974f73d8165be1bd9a0855e1cad18ee167acacabeb061", size = 138514, upload-time = "2025-01-18T15:53:28.092Z" }, - { url = "https://files.pythonhosted.org/packages/53/3e/dcf1729230654f5c5594fc752de1f43dcf67e055ac0d300c8cdb1309269a/orjson-3.10.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd271247691574416b3228db667b84775c497b245fa275c6ab90dc1ffbbd2b3", size = 130940, upload-time = "2025-01-18T15:53:30.403Z" }, - { url = "https://files.pythonhosted.org/packages/e8/2b/b9759fe704789937705c8a56a03f6c03e50dff7df87d65cba9a20fec5282/orjson-3.10.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4759b109c37f635aa5c5cc93a1b26927bfde24b254bcc0e1149a9fada253d2d", size = 414713, upload-time = "2025-01-18T15:53:32.779Z" }, - { url = "https://files.pythonhosted.org/packages/a7/6b/b9dfdbd4b6e20a59238319eb203ae07c3f6abf07eef909169b7a37ae3bba/orjson-3.10.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e992fd5cfb8b9f00bfad2fd7a05a4299db2bbe92e6440d9dd2fab27655b3182", size = 141028, upload-time = "2025-01-18T15:53:35.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/b5/40f5bbea619c7caf75eb4d652a9821875a8ed04acc45fe3d3ef054ca69fb/orjson-3.10.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95fb363d79366af56c3f26b71df40b9a583b07bbaaf5b317407c4d58497852e", size = 129715, upload-time = "2025-01-18T15:53:36.665Z" }, - { url = "https://files.pythonhosted.org/packages/38/60/2272514061cbdf4d672edbca6e59c7e01cd1c706e881427d88f3c3e79761/orjson-3.10.15-cp310-cp310-win32.whl", hash = "sha256:f9875f5fea7492da8ec2444839dcc439b0ef298978f311103d0b7dfd775898ab", size = 142473, upload-time = "2025-01-18T15:53:38.855Z" }, - { url = "https://files.pythonhosted.org/packages/11/5d/be1490ff7eafe7fef890eb4527cf5bcd8cfd6117f3efe42a3249ec847b60/orjson-3.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:17085a6aa91e1cd70ca8533989a18b5433e15d29c574582f76f821737c8d5806", size = 133564, upload-time = "2025-01-18T15:53:40.257Z" }, - { url = "https://files.pythonhosted.org/packages/7a/a2/21b25ce4a2c71dbb90948ee81bd7a42b4fbfc63162e57faf83157d5540ae/orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6", size = 249533, upload-time = "2025-01-18T15:53:41.572Z" }, - { url = "https://files.pythonhosted.org/packages/b2/85/2076fc12d8225698a51278009726750c9c65c846eda741e77e1761cfef33/orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef", size = 125230, upload-time = "2025-01-18T18:11:54.582Z" }, - { url = "https://files.pythonhosted.org/packages/06/df/a85a7955f11274191eccf559e8481b2be74a7c6d43075d0a9506aa80284d/orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334", size = 150148, upload-time = "2025-01-18T15:53:44.062Z" }, - { url = "https://files.pythonhosted.org/packages/37/b3/94c55625a29b8767c0eed194cb000b3787e3c23b4cdd13be17bae6ccbb4b/orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d", size = 139749, upload-time = "2025-01-18T15:53:45.526Z" }, - { url = "https://files.pythonhosted.org/packages/53/ba/c608b1e719971e8ddac2379f290404c2e914cf8e976369bae3cad88768b1/orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0", size = 154558, upload-time = "2025-01-18T15:53:47.712Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c4/c1fb835bb23ad788a39aa9ebb8821d51b1c03588d9a9e4ca7de5b354fdd5/orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13", size = 130349, upload-time = "2025-01-18T18:11:56.885Z" }, - { url = "https://files.pythonhosted.org/packages/78/14/bb2b48b26ab3c570b284eb2157d98c1ef331a8397f6c8bd983b270467f5c/orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5", size = 138513, upload-time = "2025-01-18T15:53:50.52Z" }, - { url = "https://files.pythonhosted.org/packages/4a/97/d5b353a5fe532e92c46467aa37e637f81af8468aa894cd77d2ec8a12f99e/orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b", size = 130942, upload-time = "2025-01-18T15:53:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/b5/5d/a067bec55293cca48fea8b9928cfa84c623be0cce8141d47690e64a6ca12/orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399", size = 414717, upload-time = "2025-01-18T15:53:53.215Z" }, - { url = "https://files.pythonhosted.org/packages/6f/9a/1485b8b05c6b4c4db172c438cf5db5dcfd10e72a9bc23c151a1137e763e0/orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388", size = 141033, upload-time = "2025-01-18T15:53:54.664Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d2/fc67523656e43a0c7eaeae9007c8b02e86076b15d591e9be11554d3d3138/orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c", size = 129720, upload-time = "2025-01-18T15:53:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/79/42/f58c7bd4e5b54da2ce2ef0331a39ccbbaa7699b7f70206fbf06737c9ed7d/orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e", size = 142473, upload-time = "2025-01-18T15:53:58.796Z" }, - { url = "https://files.pythonhosted.org/packages/00/f8/bb60a4644287a544ec81df1699d5b965776bc9848d9029d9f9b3402ac8bb/orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e", size = 133570, upload-time = "2025-01-18T15:54:00.98Z" }, - { url = "https://files.pythonhosted.org/packages/66/85/22fe737188905a71afcc4bf7cc4c79cd7f5bbe9ed1fe0aac4ce4c33edc30/orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a", size = 249504, upload-time = "2025-01-18T15:54:02.28Z" }, - { url = "https://files.pythonhosted.org/packages/48/b7/2622b29f3afebe938a0a9037e184660379797d5fd5234e5998345d7a5b43/orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d", size = 125080, upload-time = "2025-01-18T18:11:59.21Z" }, - { url = "https://files.pythonhosted.org/packages/ce/8f/0b72a48f4403d0b88b2a41450c535b3e8989e8a2d7800659a967efc7c115/orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0", size = 150121, upload-time = "2025-01-18T15:54:03.998Z" }, - { url = "https://files.pythonhosted.org/packages/06/ec/acb1a20cd49edb2000be5a0404cd43e3c8aad219f376ac8c60b870518c03/orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4", size = 139796, upload-time = "2025-01-18T15:54:06.551Z" }, - { url = "https://files.pythonhosted.org/packages/33/e1/f7840a2ea852114b23a52a1c0b2bea0a1ea22236efbcdb876402d799c423/orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767", size = 154636, upload-time = "2025-01-18T15:54:08.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/da/31543337febd043b8fa80a3b67de627669b88c7b128d9ad4cc2ece005b7a/orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41", size = 130621, upload-time = "2025-01-18T18:12:00.843Z" }, - { url = "https://files.pythonhosted.org/packages/ed/78/66115dc9afbc22496530d2139f2f4455698be444c7c2475cb48f657cefc9/orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514", size = 138516, upload-time = "2025-01-18T15:54:09.413Z" }, - { url = "https://files.pythonhosted.org/packages/22/84/cd4f5fb5427ffcf823140957a47503076184cb1ce15bcc1165125c26c46c/orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17", size = 130762, upload-time = "2025-01-18T15:54:11.777Z" }, - { url = "https://files.pythonhosted.org/packages/93/1f/67596b711ba9f56dd75d73b60089c5c92057f1130bb3a25a0f53fb9a583b/orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b", size = 414700, upload-time = "2025-01-18T15:54:14.026Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0c/6a3b3271b46443d90efb713c3e4fe83fa8cd71cda0d11a0f69a03f437c6e/orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7", size = 141077, upload-time = "2025-01-18T15:54:15.612Z" }, - { url = "https://files.pythonhosted.org/packages/3b/9b/33c58e0bfc788995eccd0d525ecd6b84b40d7ed182dd0751cd4c1322ac62/orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a", size = 129898, upload-time = "2025-01-18T15:54:17.049Z" }, - { url = "https://files.pythonhosted.org/packages/01/c1/d577ecd2e9fa393366a1ea0a9267f6510d86e6c4bb1cdfb9877104cac44c/orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665", size = 142566, upload-time = "2025-01-18T15:54:18.507Z" }, - { url = "https://files.pythonhosted.org/packages/ed/eb/a85317ee1732d1034b92d56f89f1de4d7bf7904f5c8fb9dcdd5b1c83917f/orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa", size = 133732, upload-time = "2025-01-18T15:54:20.027Z" }, - { url = "https://files.pythonhosted.org/packages/06/10/fe7d60b8da538e8d3d3721f08c1b7bff0491e8fa4dd3bf11a17e34f4730e/orjson-3.10.15-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bae0e6ec2b7ba6895198cd981b7cca95d1487d0147c8ed751e5632ad16f031a6", size = 249399, upload-time = "2025-01-18T15:54:22.46Z" }, - { url = "https://files.pythonhosted.org/packages/6b/83/52c356fd3a61abd829ae7e4366a6fe8e8863c825a60d7ac5156067516edf/orjson-3.10.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f93ce145b2db1252dd86af37d4165b6faa83072b46e3995ecc95d4b2301b725a", size = 125044, upload-time = "2025-01-18T18:12:02.747Z" }, - { url = "https://files.pythonhosted.org/packages/55/b2/d06d5901408e7ded1a74c7c20d70e3a127057a6d21355f50c90c0f337913/orjson-3.10.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c203f6f969210128af3acae0ef9ea6aab9782939f45f6fe02d05958fe761ef9", size = 150066, upload-time = "2025-01-18T15:54:24.752Z" }, - { url = "https://files.pythonhosted.org/packages/75/8c/60c3106e08dc593a861755781c7c675a566445cc39558677d505878d879f/orjson-3.10.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8918719572d662e18b8af66aef699d8c21072e54b6c82a3f8f6404c1f5ccd5e0", size = 139737, upload-time = "2025-01-18T15:54:26.236Z" }, - { url = "https://files.pythonhosted.org/packages/6a/8c/ae00d7d0ab8a4490b1efeb01ad4ab2f1982e69cc82490bf8093407718ff5/orjson-3.10.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f71eae9651465dff70aa80db92586ad5b92df46a9373ee55252109bb6b703307", size = 154804, upload-time = "2025-01-18T15:54:28.275Z" }, - { url = "https://files.pythonhosted.org/packages/22/86/65dc69bd88b6dd254535310e97bc518aa50a39ef9c5a2a5d518e7a223710/orjson-3.10.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e117eb299a35f2634e25ed120c37c641398826c2f5a3d3cc39f5993b96171b9e", size = 130583, upload-time = "2025-01-18T18:12:04.343Z" }, - { url = "https://files.pythonhosted.org/packages/bb/00/6fe01ededb05d52be42fabb13d93a36e51f1fd9be173bd95707d11a8a860/orjson-3.10.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13242f12d295e83c2955756a574ddd6741c81e5b99f2bef8ed8d53e47a01e4b7", size = 138465, upload-time = "2025-01-18T15:54:29.808Z" }, - { url = "https://files.pythonhosted.org/packages/db/2f/4cc151c4b471b0cdc8cb29d3eadbce5007eb0475d26fa26ed123dca93b33/orjson-3.10.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7946922ada8f3e0b7b958cc3eb22cfcf6c0df83d1fe5521b4a100103e3fa84c8", size = 130742, upload-time = "2025-01-18T15:54:31.289Z" }, - { url = "https://files.pythonhosted.org/packages/9f/13/8a6109e4b477c518498ca37963d9c0eb1508b259725553fb53d53b20e2ea/orjson-3.10.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b7155eb1623347f0f22c38c9abdd738b287e39b9982e1da227503387b81b34ca", size = 414669, upload-time = "2025-01-18T15:54:33.687Z" }, - { url = "https://files.pythonhosted.org/packages/22/7b/1d229d6d24644ed4d0a803de1b0e2df832032d5beda7346831c78191b5b2/orjson-3.10.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:208beedfa807c922da4e81061dafa9c8489c6328934ca2a562efa707e049e561", size = 141043, upload-time = "2025-01-18T15:54:35.482Z" }, - { url = "https://files.pythonhosted.org/packages/cc/d3/6dc91156cf12ed86bed383bcb942d84d23304a1e57b7ab030bf60ea130d6/orjson-3.10.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eca81f83b1b8c07449e1d6ff7074e82e3fd6777e588f1a6632127f286a968825", size = 129826, upload-time = "2025-01-18T15:54:37.906Z" }, - { url = "https://files.pythonhosted.org/packages/b3/38/c47c25b86f6996f1343be721b6ea4367bc1c8bc0fc3f6bbcd995d18cb19d/orjson-3.10.15-cp313-cp313-win32.whl", hash = "sha256:c03cd6eea1bd3b949d0d007c8d57049aa2b39bd49f58b4b2af571a5d3833d890", size = 142542, upload-time = "2025-01-18T15:54:40.181Z" }, - { url = "https://files.pythonhosted.org/packages/27/f1/1d7ec15b20f8ce9300bc850de1e059132b88990e46cd0ccac29cbf11e4f9/orjson-3.10.15-cp313-cp313-win_amd64.whl", hash = "sha256:fd56a26a04f6ba5fb2045b0acc487a63162a958ed837648c5781e1fe3316cfbf", size = 133444, upload-time = "2025-01-18T15:54:42.076Z" }, - { url = "https://files.pythonhosted.org/packages/56/39/b2123d8d98a62ee89626dc7ecb782d9b60a5edb0b5721bc894ee3470df5a/orjson-3.10.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ffe19f3e8d68111e8644d4f4e267a069ca427926855582ff01fc012496d19969", size = 250031, upload-time = "2025-01-18T15:55:05.697Z" }, - { url = "https://files.pythonhosted.org/packages/65/4d/a058dc6476713cbd5647e5fd0be8d40c27e9ed77d37a788b594c424caa0e/orjson-3.10.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d433bf32a363823863a96561a555227c18a522a8217a6f9400f00ddc70139ae2", size = 125021, upload-time = "2025-01-18T18:12:11.807Z" }, - { url = "https://files.pythonhosted.org/packages/3d/cb/4d1450bb2c3276f8bf9524df6b01af4d01f55e9a9772555cf119275eb1d0/orjson-3.10.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da03392674f59a95d03fa5fb9fe3a160b0511ad84b7a3914699ea5a1b3a38da2", size = 149957, upload-time = "2025-01-18T15:55:08.843Z" }, - { url = "https://files.pythonhosted.org/packages/93/7b/d1fae6d4393a9fa8f5d3fb173f0a9c778135569c50e5390811b74c45b4b3/orjson-3.10.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a63bb41559b05360ded9132032239e47983a39b151af1201f07ec9370715c82", size = 139515, upload-time = "2025-01-18T15:55:10.567Z" }, - { url = "https://files.pythonhosted.org/packages/7f/b2/e0c0b8197c709983093700f9a59aa64478d80edc55fe620bceadb92004e3/orjson-3.10.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3766ac4702f8f795ff3fa067968e806b4344af257011858cc3d6d8721588b53f", size = 154314, upload-time = "2025-01-18T15:55:12.196Z" }, - { url = "https://files.pythonhosted.org/packages/db/94/eeb94ca3aa7564f753fe352101bcfc8179febaa1888f55ba3cad25b05f71/orjson-3.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1c73dcc8fadbd7c55802d9aa093b36878d34a3b3222c41052ce6b0fc65f8e8", size = 130145, upload-time = "2025-01-18T18:12:13.477Z" }, - { url = "https://files.pythonhosted.org/packages/ca/10/54c0118a38eaa5ae832c27306834bdc13954bd0a443b80da63faebf17ffe/orjson-3.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b299383825eafe642cbab34be762ccff9fd3408d72726a6b2a4506d410a71ab3", size = 138344, upload-time = "2025-01-18T15:55:13.786Z" }, - { url = "https://files.pythonhosted.org/packages/78/87/3c15eeb315171aa27f96bcca87ed54ee292b72d755973a66e3a6800e8ae9/orjson-3.10.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:abc7abecdbf67a173ef1316036ebbf54ce400ef2300b4e26a7b843bd446c2480", size = 130730, upload-time = "2025-01-18T15:55:15.402Z" }, - { url = "https://files.pythonhosted.org/packages/8a/dc/522430fb24445b9cc8301a5954f80ce8ee244c5159ba913578acc36b078f/orjson-3.10.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:3614ea508d522a621384c1d6639016a5a2e4f027f3e4a1c93a51867615d28829", size = 414482, upload-time = "2025-01-18T15:55:16.989Z" }, - { url = "https://files.pythonhosted.org/packages/c8/01/83b2e80b9c96ca9753d06e01d325037b2f3e404b14c7a8e875b2f2b7c171/orjson-3.10.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:295c70f9dc154307777ba30fe29ff15c1bcc9dfc5c48632f37d20a607e9ba85a", size = 140792, upload-time = "2025-01-18T15:55:18.731Z" }, - { url = "https://files.pythonhosted.org/packages/96/40/f211084b0e0267b6b515f05967048d8957839d80ff534bde0dc7f9df9ae0/orjson-3.10.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:63309e3ff924c62404923c80b9e2048c1f74ba4b615e7584584389ada50ed428", size = 129536, upload-time = "2025-01-18T15:55:21.306Z" }, - { url = "https://files.pythonhosted.org/packages/b2/8c/014d96f5c6446adcd2403fe2d4007ff582f8867f5028b0cd994f0174d61c/orjson-3.10.15-cp39-cp39-win32.whl", hash = "sha256:a2f708c62d026fb5340788ba94a55c23df4e1869fec74be455e0b2f5363b8507", size = 142302, upload-time = "2025-01-18T15:55:25.094Z" }, - { url = "https://files.pythonhosted.org/packages/47/bd/81da73ef8e66434c51a4ea7db45e3a0b62bff2c3e7ebc723aa4eeead2feb/orjson-3.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:efcf6c735c3d22ef60c4aa27a5238f1a477df85e9b15f2142f9d669beb2d13fd", size = 133401, upload-time = "2025-01-18T15:55:26.953Z" }, + { url = "https://files.pythonhosted.org/packages/52/09/e5ff18ad009e6f97eb7edc5f67ef98b3ce0c189da9c3eaca1f9587cd4c61/orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04", size = 249532 }, + { url = "https://files.pythonhosted.org/packages/bd/b8/a75883301fe332bd433d9b0ded7d2bb706ccac679602c3516984f8814fb5/orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8", size = 125229 }, + { url = "https://files.pythonhosted.org/packages/83/4b/22f053e7a364cc9c685be203b1e40fc5f2b3f164a9b2284547504eec682e/orjson-3.10.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c2c79fa308e6edb0ffab0a31fd75a7841bf2a79a20ef08a3c6e3b26814c8ca8", size = 150148 }, + { url = "https://files.pythonhosted.org/packages/63/64/1b54fc75ca328b57dd810541a4035fe48c12a161d466e3cf5b11a8c25649/orjson-3.10.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cb85490aa6bf98abd20607ab5c8324c0acb48d6da7863a51be48505646c814", size = 139748 }, + { url = "https://files.pythonhosted.org/packages/5e/ff/ff0c5da781807bb0a5acd789d9a7fbcb57f7b0c6e1916595da1f5ce69f3c/orjson-3.10.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763dadac05e4e9d2bc14938a45a2d0560549561287d41c465d3c58aec818b164", size = 154559 }, + { url = "https://files.pythonhosted.org/packages/4e/9a/11e2974383384ace8495810d4a2ebef5f55aacfc97b333b65e789c9d362d/orjson-3.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a330b9b4734f09a623f74a7490db713695e13b67c959713b78369f26b3dee6bf", size = 130349 }, + { url = "https://files.pythonhosted.org/packages/2d/c4/dd9583aea6aefee1b64d3aed13f51d2aadb014028bc929fe52936ec5091f/orjson-3.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a61a4622b7ff861f019974f73d8165be1bd9a0855e1cad18ee167acacabeb061", size = 138514 }, + { url = "https://files.pythonhosted.org/packages/53/3e/dcf1729230654f5c5594fc752de1f43dcf67e055ac0d300c8cdb1309269a/orjson-3.10.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd271247691574416b3228db667b84775c497b245fa275c6ab90dc1ffbbd2b3", size = 130940 }, + { url = "https://files.pythonhosted.org/packages/e8/2b/b9759fe704789937705c8a56a03f6c03e50dff7df87d65cba9a20fec5282/orjson-3.10.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4759b109c37f635aa5c5cc93a1b26927bfde24b254bcc0e1149a9fada253d2d", size = 414713 }, + { url = "https://files.pythonhosted.org/packages/a7/6b/b9dfdbd4b6e20a59238319eb203ae07c3f6abf07eef909169b7a37ae3bba/orjson-3.10.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e992fd5cfb8b9f00bfad2fd7a05a4299db2bbe92e6440d9dd2fab27655b3182", size = 141028 }, + { url = "https://files.pythonhosted.org/packages/7c/b5/40f5bbea619c7caf75eb4d652a9821875a8ed04acc45fe3d3ef054ca69fb/orjson-3.10.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95fb363d79366af56c3f26b71df40b9a583b07bbaaf5b317407c4d58497852e", size = 129715 }, + { url = "https://files.pythonhosted.org/packages/38/60/2272514061cbdf4d672edbca6e59c7e01cd1c706e881427d88f3c3e79761/orjson-3.10.15-cp310-cp310-win32.whl", hash = "sha256:f9875f5fea7492da8ec2444839dcc439b0ef298978f311103d0b7dfd775898ab", size = 142473 }, + { url = "https://files.pythonhosted.org/packages/11/5d/be1490ff7eafe7fef890eb4527cf5bcd8cfd6117f3efe42a3249ec847b60/orjson-3.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:17085a6aa91e1cd70ca8533989a18b5433e15d29c574582f76f821737c8d5806", size = 133564 }, + { url = "https://files.pythonhosted.org/packages/7a/a2/21b25ce4a2c71dbb90948ee81bd7a42b4fbfc63162e57faf83157d5540ae/orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6", size = 249533 }, + { url = "https://files.pythonhosted.org/packages/b2/85/2076fc12d8225698a51278009726750c9c65c846eda741e77e1761cfef33/orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef", size = 125230 }, + { url = "https://files.pythonhosted.org/packages/06/df/a85a7955f11274191eccf559e8481b2be74a7c6d43075d0a9506aa80284d/orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334", size = 150148 }, + { url = "https://files.pythonhosted.org/packages/37/b3/94c55625a29b8767c0eed194cb000b3787e3c23b4cdd13be17bae6ccbb4b/orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d", size = 139749 }, + { url = "https://files.pythonhosted.org/packages/53/ba/c608b1e719971e8ddac2379f290404c2e914cf8e976369bae3cad88768b1/orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0", size = 154558 }, + { url = "https://files.pythonhosted.org/packages/b2/c4/c1fb835bb23ad788a39aa9ebb8821d51b1c03588d9a9e4ca7de5b354fdd5/orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13", size = 130349 }, + { url = "https://files.pythonhosted.org/packages/78/14/bb2b48b26ab3c570b284eb2157d98c1ef331a8397f6c8bd983b270467f5c/orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5", size = 138513 }, + { url = "https://files.pythonhosted.org/packages/4a/97/d5b353a5fe532e92c46467aa37e637f81af8468aa894cd77d2ec8a12f99e/orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b", size = 130942 }, + { url = "https://files.pythonhosted.org/packages/b5/5d/a067bec55293cca48fea8b9928cfa84c623be0cce8141d47690e64a6ca12/orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399", size = 414717 }, + { url = "https://files.pythonhosted.org/packages/6f/9a/1485b8b05c6b4c4db172c438cf5db5dcfd10e72a9bc23c151a1137e763e0/orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388", size = 141033 }, + { url = "https://files.pythonhosted.org/packages/f8/d2/fc67523656e43a0c7eaeae9007c8b02e86076b15d591e9be11554d3d3138/orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c", size = 129720 }, + { url = "https://files.pythonhosted.org/packages/79/42/f58c7bd4e5b54da2ce2ef0331a39ccbbaa7699b7f70206fbf06737c9ed7d/orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e", size = 142473 }, + { url = "https://files.pythonhosted.org/packages/00/f8/bb60a4644287a544ec81df1699d5b965776bc9848d9029d9f9b3402ac8bb/orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e", size = 133570 }, + { url = "https://files.pythonhosted.org/packages/66/85/22fe737188905a71afcc4bf7cc4c79cd7f5bbe9ed1fe0aac4ce4c33edc30/orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a", size = 249504 }, + { url = "https://files.pythonhosted.org/packages/48/b7/2622b29f3afebe938a0a9037e184660379797d5fd5234e5998345d7a5b43/orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d", size = 125080 }, + { url = "https://files.pythonhosted.org/packages/ce/8f/0b72a48f4403d0b88b2a41450c535b3e8989e8a2d7800659a967efc7c115/orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0", size = 150121 }, + { url = "https://files.pythonhosted.org/packages/06/ec/acb1a20cd49edb2000be5a0404cd43e3c8aad219f376ac8c60b870518c03/orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4", size = 139796 }, + { url = "https://files.pythonhosted.org/packages/33/e1/f7840a2ea852114b23a52a1c0b2bea0a1ea22236efbcdb876402d799c423/orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767", size = 154636 }, + { url = "https://files.pythonhosted.org/packages/fa/da/31543337febd043b8fa80a3b67de627669b88c7b128d9ad4cc2ece005b7a/orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41", size = 130621 }, + { url = "https://files.pythonhosted.org/packages/ed/78/66115dc9afbc22496530d2139f2f4455698be444c7c2475cb48f657cefc9/orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514", size = 138516 }, + { url = "https://files.pythonhosted.org/packages/22/84/cd4f5fb5427ffcf823140957a47503076184cb1ce15bcc1165125c26c46c/orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17", size = 130762 }, + { url = "https://files.pythonhosted.org/packages/93/1f/67596b711ba9f56dd75d73b60089c5c92057f1130bb3a25a0f53fb9a583b/orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b", size = 414700 }, + { url = "https://files.pythonhosted.org/packages/7c/0c/6a3b3271b46443d90efb713c3e4fe83fa8cd71cda0d11a0f69a03f437c6e/orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7", size = 141077 }, + { url = "https://files.pythonhosted.org/packages/3b/9b/33c58e0bfc788995eccd0d525ecd6b84b40d7ed182dd0751cd4c1322ac62/orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a", size = 129898 }, + { url = "https://files.pythonhosted.org/packages/01/c1/d577ecd2e9fa393366a1ea0a9267f6510d86e6c4bb1cdfb9877104cac44c/orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665", size = 142566 }, + { url = "https://files.pythonhosted.org/packages/ed/eb/a85317ee1732d1034b92d56f89f1de4d7bf7904f5c8fb9dcdd5b1c83917f/orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa", size = 133732 }, + { url = "https://files.pythonhosted.org/packages/06/10/fe7d60b8da538e8d3d3721f08c1b7bff0491e8fa4dd3bf11a17e34f4730e/orjson-3.10.15-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bae0e6ec2b7ba6895198cd981b7cca95d1487d0147c8ed751e5632ad16f031a6", size = 249399 }, + { url = "https://files.pythonhosted.org/packages/6b/83/52c356fd3a61abd829ae7e4366a6fe8e8863c825a60d7ac5156067516edf/orjson-3.10.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f93ce145b2db1252dd86af37d4165b6faa83072b46e3995ecc95d4b2301b725a", size = 125044 }, + { url = "https://files.pythonhosted.org/packages/55/b2/d06d5901408e7ded1a74c7c20d70e3a127057a6d21355f50c90c0f337913/orjson-3.10.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c203f6f969210128af3acae0ef9ea6aab9782939f45f6fe02d05958fe761ef9", size = 150066 }, + { url = "https://files.pythonhosted.org/packages/75/8c/60c3106e08dc593a861755781c7c675a566445cc39558677d505878d879f/orjson-3.10.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8918719572d662e18b8af66aef699d8c21072e54b6c82a3f8f6404c1f5ccd5e0", size = 139737 }, + { url = "https://files.pythonhosted.org/packages/6a/8c/ae00d7d0ab8a4490b1efeb01ad4ab2f1982e69cc82490bf8093407718ff5/orjson-3.10.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f71eae9651465dff70aa80db92586ad5b92df46a9373ee55252109bb6b703307", size = 154804 }, + { url = "https://files.pythonhosted.org/packages/22/86/65dc69bd88b6dd254535310e97bc518aa50a39ef9c5a2a5d518e7a223710/orjson-3.10.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e117eb299a35f2634e25ed120c37c641398826c2f5a3d3cc39f5993b96171b9e", size = 130583 }, + { url = "https://files.pythonhosted.org/packages/bb/00/6fe01ededb05d52be42fabb13d93a36e51f1fd9be173bd95707d11a8a860/orjson-3.10.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13242f12d295e83c2955756a574ddd6741c81e5b99f2bef8ed8d53e47a01e4b7", size = 138465 }, + { url = "https://files.pythonhosted.org/packages/db/2f/4cc151c4b471b0cdc8cb29d3eadbce5007eb0475d26fa26ed123dca93b33/orjson-3.10.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7946922ada8f3e0b7b958cc3eb22cfcf6c0df83d1fe5521b4a100103e3fa84c8", size = 130742 }, + { url = "https://files.pythonhosted.org/packages/9f/13/8a6109e4b477c518498ca37963d9c0eb1508b259725553fb53d53b20e2ea/orjson-3.10.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b7155eb1623347f0f22c38c9abdd738b287e39b9982e1da227503387b81b34ca", size = 414669 }, + { url = "https://files.pythonhosted.org/packages/22/7b/1d229d6d24644ed4d0a803de1b0e2df832032d5beda7346831c78191b5b2/orjson-3.10.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:208beedfa807c922da4e81061dafa9c8489c6328934ca2a562efa707e049e561", size = 141043 }, + { url = "https://files.pythonhosted.org/packages/cc/d3/6dc91156cf12ed86bed383bcb942d84d23304a1e57b7ab030bf60ea130d6/orjson-3.10.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eca81f83b1b8c07449e1d6ff7074e82e3fd6777e588f1a6632127f286a968825", size = 129826 }, + { url = "https://files.pythonhosted.org/packages/b3/38/c47c25b86f6996f1343be721b6ea4367bc1c8bc0fc3f6bbcd995d18cb19d/orjson-3.10.15-cp313-cp313-win32.whl", hash = "sha256:c03cd6eea1bd3b949d0d007c8d57049aa2b39bd49f58b4b2af571a5d3833d890", size = 142542 }, + { url = "https://files.pythonhosted.org/packages/27/f1/1d7ec15b20f8ce9300bc850de1e059132b88990e46cd0ccac29cbf11e4f9/orjson-3.10.15-cp313-cp313-win_amd64.whl", hash = "sha256:fd56a26a04f6ba5fb2045b0acc487a63162a958ed837648c5781e1fe3316cfbf", size = 133444 }, + { url = "https://files.pythonhosted.org/packages/56/39/b2123d8d98a62ee89626dc7ecb782d9b60a5edb0b5721bc894ee3470df5a/orjson-3.10.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ffe19f3e8d68111e8644d4f4e267a069ca427926855582ff01fc012496d19969", size = 250031 }, + { url = "https://files.pythonhosted.org/packages/65/4d/a058dc6476713cbd5647e5fd0be8d40c27e9ed77d37a788b594c424caa0e/orjson-3.10.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d433bf32a363823863a96561a555227c18a522a8217a6f9400f00ddc70139ae2", size = 125021 }, + { url = "https://files.pythonhosted.org/packages/3d/cb/4d1450bb2c3276f8bf9524df6b01af4d01f55e9a9772555cf119275eb1d0/orjson-3.10.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da03392674f59a95d03fa5fb9fe3a160b0511ad84b7a3914699ea5a1b3a38da2", size = 149957 }, + { url = "https://files.pythonhosted.org/packages/93/7b/d1fae6d4393a9fa8f5d3fb173f0a9c778135569c50e5390811b74c45b4b3/orjson-3.10.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a63bb41559b05360ded9132032239e47983a39b151af1201f07ec9370715c82", size = 139515 }, + { url = "https://files.pythonhosted.org/packages/7f/b2/e0c0b8197c709983093700f9a59aa64478d80edc55fe620bceadb92004e3/orjson-3.10.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3766ac4702f8f795ff3fa067968e806b4344af257011858cc3d6d8721588b53f", size = 154314 }, + { url = "https://files.pythonhosted.org/packages/db/94/eeb94ca3aa7564f753fe352101bcfc8179febaa1888f55ba3cad25b05f71/orjson-3.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1c73dcc8fadbd7c55802d9aa093b36878d34a3b3222c41052ce6b0fc65f8e8", size = 130145 }, + { url = "https://files.pythonhosted.org/packages/ca/10/54c0118a38eaa5ae832c27306834bdc13954bd0a443b80da63faebf17ffe/orjson-3.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b299383825eafe642cbab34be762ccff9fd3408d72726a6b2a4506d410a71ab3", size = 138344 }, + { url = "https://files.pythonhosted.org/packages/78/87/3c15eeb315171aa27f96bcca87ed54ee292b72d755973a66e3a6800e8ae9/orjson-3.10.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:abc7abecdbf67a173ef1316036ebbf54ce400ef2300b4e26a7b843bd446c2480", size = 130730 }, + { url = "https://files.pythonhosted.org/packages/8a/dc/522430fb24445b9cc8301a5954f80ce8ee244c5159ba913578acc36b078f/orjson-3.10.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:3614ea508d522a621384c1d6639016a5a2e4f027f3e4a1c93a51867615d28829", size = 414482 }, + { url = "https://files.pythonhosted.org/packages/c8/01/83b2e80b9c96ca9753d06e01d325037b2f3e404b14c7a8e875b2f2b7c171/orjson-3.10.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:295c70f9dc154307777ba30fe29ff15c1bcc9dfc5c48632f37d20a607e9ba85a", size = 140792 }, + { url = "https://files.pythonhosted.org/packages/96/40/f211084b0e0267b6b515f05967048d8957839d80ff534bde0dc7f9df9ae0/orjson-3.10.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:63309e3ff924c62404923c80b9e2048c1f74ba4b615e7584584389ada50ed428", size = 129536 }, + { url = "https://files.pythonhosted.org/packages/b2/8c/014d96f5c6446adcd2403fe2d4007ff582f8867f5028b0cd994f0174d61c/orjson-3.10.15-cp39-cp39-win32.whl", hash = "sha256:a2f708c62d026fb5340788ba94a55c23df4e1869fec74be455e0b2f5363b8507", size = 142302 }, + { url = "https://files.pythonhosted.org/packages/47/bd/81da73ef8e66434c51a4ea7db45e3a0b62bff2c3e7ebc723aa4eeead2feb/orjson-3.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:efcf6c735c3d22ef60c4aa27a5238f1a477df85e9b15f2142f9d669beb2d13fd", size = 133401 }, ] [[package]] name = "packaging" version = "24.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, ] [[package]] name = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, ] [[package]] name = "propcache" version = "0.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", size = 43651, upload-time = "2025-03-26T03:06:12.05Z" } +sdist = { url = "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", size = 43651 } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/56/e27c136101addf877c8291dbda1b3b86ae848f3837ce758510a0d806c92f/propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98", size = 80224, upload-time = "2025-03-26T03:03:35.81Z" }, - { url = "https://files.pythonhosted.org/packages/63/bd/88e98836544c4f04db97eefd23b037c2002fa173dd2772301c61cd3085f9/propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180", size = 46491, upload-time = "2025-03-26T03:03:38.107Z" }, - { url = "https://files.pythonhosted.org/packages/15/43/0b8eb2a55753c4a574fc0899885da504b521068d3b08ca56774cad0bea2b/propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71", size = 45927, upload-time = "2025-03-26T03:03:39.394Z" }, - { url = "https://files.pythonhosted.org/packages/ad/6c/d01f9dfbbdc613305e0a831016844987a1fb4861dd221cd4c69b1216b43f/propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649", size = 206135, upload-time = "2025-03-26T03:03:40.757Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8a/e6e1c77394088f4cfdace4a91a7328e398ebed745d59c2f6764135c5342d/propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f", size = 220517, upload-time = "2025-03-26T03:03:42.657Z" }, - { url = "https://files.pythonhosted.org/packages/19/3b/6c44fa59d6418f4239d5db8b1ece757351e85d6f3ca126dfe37d427020c8/propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229", size = 218952, upload-time = "2025-03-26T03:03:44.549Z" }, - { url = "https://files.pythonhosted.org/packages/7c/e4/4aeb95a1cd085e0558ab0de95abfc5187329616193a1012a6c4c930e9f7a/propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46", size = 206593, upload-time = "2025-03-26T03:03:46.114Z" }, - { url = "https://files.pythonhosted.org/packages/da/6a/29fa75de1cbbb302f1e1d684009b969976ca603ee162282ae702287b6621/propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7", size = 196745, upload-time = "2025-03-26T03:03:48.02Z" }, - { url = "https://files.pythonhosted.org/packages/19/7e/2237dad1dbffdd2162de470599fa1a1d55df493b16b71e5d25a0ac1c1543/propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0", size = 203369, upload-time = "2025-03-26T03:03:49.63Z" }, - { url = "https://files.pythonhosted.org/packages/a4/bc/a82c5878eb3afb5c88da86e2cf06e1fe78b7875b26198dbb70fe50a010dc/propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519", size = 198723, upload-time = "2025-03-26T03:03:51.091Z" }, - { url = "https://files.pythonhosted.org/packages/17/76/9632254479c55516f51644ddbf747a45f813031af5adcb8db91c0b824375/propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd", size = 200751, upload-time = "2025-03-26T03:03:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/3e/c3/a90b773cf639bd01d12a9e20c95be0ae978a5a8abe6d2d343900ae76cd71/propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259", size = 210730, upload-time = "2025-03-26T03:03:54.498Z" }, - { url = "https://files.pythonhosted.org/packages/ed/ec/ad5a952cdb9d65c351f88db7c46957edd3d65ffeee72a2f18bd6341433e0/propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e", size = 213499, upload-time = "2025-03-26T03:03:56.054Z" }, - { url = "https://files.pythonhosted.org/packages/83/c0/ea5133dda43e298cd2010ec05c2821b391e10980e64ee72c0a76cdbb813a/propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136", size = 207132, upload-time = "2025-03-26T03:03:57.398Z" }, - { url = "https://files.pythonhosted.org/packages/79/dd/71aae9dec59333064cfdd7eb31a63fa09f64181b979802a67a90b2abfcba/propcache-0.3.1-cp310-cp310-win32.whl", hash = "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42", size = 40952, upload-time = "2025-03-26T03:03:59.146Z" }, - { url = "https://files.pythonhosted.org/packages/31/0a/49ff7e5056c17dfba62cbdcbb90a29daffd199c52f8e65e5cb09d5f53a57/propcache-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833", size = 45163, upload-time = "2025-03-26T03:04:00.672Z" }, - { url = "https://files.pythonhosted.org/packages/90/0f/5a5319ee83bd651f75311fcb0c492c21322a7fc8f788e4eef23f44243427/propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5", size = 80243, upload-time = "2025-03-26T03:04:01.912Z" }, - { url = "https://files.pythonhosted.org/packages/ce/84/3db5537e0879942783e2256616ff15d870a11d7ac26541336fe1b673c818/propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371", size = 46503, upload-time = "2025-03-26T03:04:03.704Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c8/b649ed972433c3f0d827d7f0cf9ea47162f4ef8f4fe98c5f3641a0bc63ff/propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da", size = 45934, upload-time = "2025-03-26T03:04:05.257Z" }, - { url = "https://files.pythonhosted.org/packages/59/f9/4c0a5cf6974c2c43b1a6810c40d889769cc8f84cea676cbe1e62766a45f8/propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744", size = 233633, upload-time = "2025-03-26T03:04:07.044Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/66f2f4d1b4f0007c6e9078bd95b609b633d3957fe6dd23eac33ebde4b584/propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0", size = 241124, upload-time = "2025-03-26T03:04:08.676Z" }, - { url = "https://files.pythonhosted.org/packages/aa/bf/7b8c9fd097d511638fa9b6af3d986adbdf567598a567b46338c925144c1b/propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5", size = 240283, upload-time = "2025-03-26T03:04:10.172Z" }, - { url = "https://files.pythonhosted.org/packages/fa/c9/e85aeeeaae83358e2a1ef32d6ff50a483a5d5248bc38510d030a6f4e2816/propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256", size = 232498, upload-time = "2025-03-26T03:04:11.616Z" }, - { url = "https://files.pythonhosted.org/packages/8e/66/acb88e1f30ef5536d785c283af2e62931cb934a56a3ecf39105887aa8905/propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073", size = 221486, upload-time = "2025-03-26T03:04:13.102Z" }, - { url = "https://files.pythonhosted.org/packages/f5/f9/233ddb05ffdcaee4448508ee1d70aa7deff21bb41469ccdfcc339f871427/propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d", size = 222675, upload-time = "2025-03-26T03:04:14.658Z" }, - { url = "https://files.pythonhosted.org/packages/98/b8/eb977e28138f9e22a5a789daf608d36e05ed93093ef12a12441030da800a/propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f", size = 215727, upload-time = "2025-03-26T03:04:16.207Z" }, - { url = "https://files.pythonhosted.org/packages/89/2d/5f52d9c579f67b8ee1edd9ec073c91b23cc5b7ff7951a1e449e04ed8fdf3/propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0", size = 217878, upload-time = "2025-03-26T03:04:18.11Z" }, - { url = "https://files.pythonhosted.org/packages/7a/fd/5283e5ed8a82b00c7a989b99bb6ea173db1ad750bf0bf8dff08d3f4a4e28/propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a", size = 230558, upload-time = "2025-03-26T03:04:19.562Z" }, - { url = "https://files.pythonhosted.org/packages/90/38/ab17d75938ef7ac87332c588857422ae126b1c76253f0f5b1242032923ca/propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a", size = 233754, upload-time = "2025-03-26T03:04:21.065Z" }, - { url = "https://files.pythonhosted.org/packages/06/5d/3b921b9c60659ae464137508d3b4c2b3f52f592ceb1964aa2533b32fcf0b/propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9", size = 226088, upload-time = "2025-03-26T03:04:22.718Z" }, - { url = "https://files.pythonhosted.org/packages/54/6e/30a11f4417d9266b5a464ac5a8c5164ddc9dd153dfa77bf57918165eb4ae/propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005", size = 40859, upload-time = "2025-03-26T03:04:24.039Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3a/8a68dd867da9ca2ee9dfd361093e9cb08cb0f37e5ddb2276f1b5177d7731/propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7", size = 45153, upload-time = "2025-03-26T03:04:25.211Z" }, - { url = "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", size = 80430, upload-time = "2025-03-26T03:04:26.436Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", size = 46637, upload-time = "2025-03-26T03:04:27.932Z" }, - { url = "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", size = 46123, upload-time = "2025-03-26T03:04:30.659Z" }, - { url = "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", size = 243031, upload-time = "2025-03-26T03:04:31.977Z" }, - { url = "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", size = 249100, upload-time = "2025-03-26T03:04:33.45Z" }, - { url = "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", size = 250170, upload-time = "2025-03-26T03:04:35.542Z" }, - { url = "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", size = 245000, upload-time = "2025-03-26T03:04:37.501Z" }, - { url = "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", size = 230262, upload-time = "2025-03-26T03:04:39.532Z" }, - { url = "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", size = 236772, upload-time = "2025-03-26T03:04:41.109Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", size = 231133, upload-time = "2025-03-26T03:04:42.544Z" }, - { url = "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", size = 230741, upload-time = "2025-03-26T03:04:44.06Z" }, - { url = "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", size = 244047, upload-time = "2025-03-26T03:04:45.983Z" }, - { url = "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", size = 246467, upload-time = "2025-03-26T03:04:47.699Z" }, - { url = "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", size = 241022, upload-time = "2025-03-26T03:04:49.195Z" }, - { url = "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", size = 40647, upload-time = "2025-03-26T03:04:50.595Z" }, - { url = "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", size = 44784, upload-time = "2025-03-26T03:04:51.791Z" }, - { url = "https://files.pythonhosted.org/packages/58/60/f645cc8b570f99be3cf46714170c2de4b4c9d6b827b912811eff1eb8a412/propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8", size = 77865, upload-time = "2025-03-26T03:04:53.406Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d4/c1adbf3901537582e65cf90fd9c26fde1298fde5a2c593f987112c0d0798/propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f", size = 45452, upload-time = "2025-03-26T03:04:54.624Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b5/fe752b2e63f49f727c6c1c224175d21b7d1727ce1d4873ef1c24c9216830/propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111", size = 44800, upload-time = "2025-03-26T03:04:55.844Z" }, - { url = "https://files.pythonhosted.org/packages/62/37/fc357e345bc1971e21f76597028b059c3d795c5ca7690d7a8d9a03c9708a/propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5", size = 225804, upload-time = "2025-03-26T03:04:57.158Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f1/16e12c33e3dbe7f8b737809bad05719cff1dccb8df4dafbcff5575002c0e/propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb", size = 230650, upload-time = "2025-03-26T03:04:58.61Z" }, - { url = "https://files.pythonhosted.org/packages/3e/a2/018b9f2ed876bf5091e60153f727e8f9073d97573f790ff7cdf6bc1d1fb8/propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7", size = 234235, upload-time = "2025-03-26T03:05:00.599Z" }, - { url = "https://files.pythonhosted.org/packages/45/5f/3faee66fc930dfb5da509e34c6ac7128870631c0e3582987fad161fcb4b1/propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120", size = 228249, upload-time = "2025-03-26T03:05:02.11Z" }, - { url = "https://files.pythonhosted.org/packages/62/1e/a0d5ebda5da7ff34d2f5259a3e171a94be83c41eb1e7cd21a2105a84a02e/propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654", size = 214964, upload-time = "2025-03-26T03:05:03.599Z" }, - { url = "https://files.pythonhosted.org/packages/db/a0/d72da3f61ceab126e9be1f3bc7844b4e98c6e61c985097474668e7e52152/propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e", size = 222501, upload-time = "2025-03-26T03:05:05.107Z" }, - { url = "https://files.pythonhosted.org/packages/18/6d/a008e07ad7b905011253adbbd97e5b5375c33f0b961355ca0a30377504ac/propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b", size = 217917, upload-time = "2025-03-26T03:05:06.59Z" }, - { url = "https://files.pythonhosted.org/packages/98/37/02c9343ffe59e590e0e56dc5c97d0da2b8b19fa747ebacf158310f97a79a/propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53", size = 217089, upload-time = "2025-03-26T03:05:08.1Z" }, - { url = "https://files.pythonhosted.org/packages/53/1b/d3406629a2c8a5666d4674c50f757a77be119b113eedd47b0375afdf1b42/propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5", size = 228102, upload-time = "2025-03-26T03:05:09.982Z" }, - { url = "https://files.pythonhosted.org/packages/cd/a7/3664756cf50ce739e5f3abd48febc0be1a713b1f389a502ca819791a6b69/propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7", size = 230122, upload-time = "2025-03-26T03:05:11.408Z" }, - { url = "https://files.pythonhosted.org/packages/35/36/0bbabaacdcc26dac4f8139625e930f4311864251276033a52fd52ff2a274/propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef", size = 226818, upload-time = "2025-03-26T03:05:12.909Z" }, - { url = "https://files.pythonhosted.org/packages/cc/27/4e0ef21084b53bd35d4dae1634b6d0bad35e9c58ed4f032511acca9d4d26/propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24", size = 40112, upload-time = "2025-03-26T03:05:14.289Z" }, - { url = "https://files.pythonhosted.org/packages/a6/2c/a54614d61895ba6dd7ac8f107e2b2a0347259ab29cbf2ecc7b94fa38c4dc/propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037", size = 44034, upload-time = "2025-03-26T03:05:15.616Z" }, - { url = "https://files.pythonhosted.org/packages/5a/a8/0a4fd2f664fc6acc66438370905124ce62e84e2e860f2557015ee4a61c7e/propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f", size = 82613, upload-time = "2025-03-26T03:05:16.913Z" }, - { url = "https://files.pythonhosted.org/packages/4d/e5/5ef30eb2cd81576256d7b6caaa0ce33cd1d2c2c92c8903cccb1af1a4ff2f/propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c", size = 47763, upload-time = "2025-03-26T03:05:18.607Z" }, - { url = "https://files.pythonhosted.org/packages/87/9a/87091ceb048efeba4d28e903c0b15bcc84b7c0bf27dc0261e62335d9b7b8/propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc", size = 47175, upload-time = "2025-03-26T03:05:19.85Z" }, - { url = "https://files.pythonhosted.org/packages/3e/2f/854e653c96ad1161f96194c6678a41bbb38c7947d17768e8811a77635a08/propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de", size = 292265, upload-time = "2025-03-26T03:05:21.654Z" }, - { url = "https://files.pythonhosted.org/packages/40/8d/090955e13ed06bc3496ba4a9fb26c62e209ac41973cb0d6222de20c6868f/propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6", size = 294412, upload-time = "2025-03-26T03:05:23.147Z" }, - { url = "https://files.pythonhosted.org/packages/39/e6/d51601342e53cc7582449e6a3c14a0479fab2f0750c1f4d22302e34219c6/propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7", size = 294290, upload-time = "2025-03-26T03:05:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/3b/4d/be5f1a90abc1881884aa5878989a1acdafd379a91d9c7e5e12cef37ec0d7/propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458", size = 282926, upload-time = "2025-03-26T03:05:26.459Z" }, - { url = "https://files.pythonhosted.org/packages/57/2b/8f61b998c7ea93a2b7eca79e53f3e903db1787fca9373af9e2cf8dc22f9d/propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11", size = 267808, upload-time = "2025-03-26T03:05:28.188Z" }, - { url = "https://files.pythonhosted.org/packages/11/1c/311326c3dfce59c58a6098388ba984b0e5fb0381ef2279ec458ef99bd547/propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c", size = 290916, upload-time = "2025-03-26T03:05:29.757Z" }, - { url = "https://files.pythonhosted.org/packages/4b/74/91939924b0385e54dc48eb2e4edd1e4903ffd053cf1916ebc5347ac227f7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf", size = 262661, upload-time = "2025-03-26T03:05:31.472Z" }, - { url = "https://files.pythonhosted.org/packages/c2/d7/e6079af45136ad325c5337f5dd9ef97ab5dc349e0ff362fe5c5db95e2454/propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27", size = 264384, upload-time = "2025-03-26T03:05:32.984Z" }, - { url = "https://files.pythonhosted.org/packages/b7/d5/ba91702207ac61ae6f1c2da81c5d0d6bf6ce89e08a2b4d44e411c0bbe867/propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757", size = 291420, upload-time = "2025-03-26T03:05:34.496Z" }, - { url = "https://files.pythonhosted.org/packages/58/70/2117780ed7edcd7ba6b8134cb7802aada90b894a9810ec56b7bb6018bee7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18", size = 290880, upload-time = "2025-03-26T03:05:36.256Z" }, - { url = "https://files.pythonhosted.org/packages/4a/1f/ecd9ce27710021ae623631c0146719280a929d895a095f6d85efb6a0be2e/propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a", size = 287407, upload-time = "2025-03-26T03:05:37.799Z" }, - { url = "https://files.pythonhosted.org/packages/3e/66/2e90547d6b60180fb29e23dc87bd8c116517d4255240ec6d3f7dc23d1926/propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d", size = 42573, upload-time = "2025-03-26T03:05:39.193Z" }, - { url = "https://files.pythonhosted.org/packages/cb/8f/50ad8599399d1861b4d2b6b45271f0ef6af1b09b0a2386a46dbaf19c9535/propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e", size = 46757, upload-time = "2025-03-26T03:05:40.811Z" }, - { url = "https://files.pythonhosted.org/packages/aa/e1/4a782cdc7ebc42dfb44224dabf93b481395a0b6cbc9f0149785edbbab19c/propcache-0.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ed5f6d2edbf349bd8d630e81f474d33d6ae5d07760c44d33cd808e2f5c8f4ae6", size = 81368, upload-time = "2025-03-26T03:05:42.15Z" }, - { url = "https://files.pythonhosted.org/packages/18/c6/9a39b2646a71321815d8d616e890851af9fb327af7d1b9fdce7d2d8377ca/propcache-0.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:668ddddc9f3075af019f784456267eb504cb77c2c4bd46cc8402d723b4d200bf", size = 47037, upload-time = "2025-03-26T03:05:44.279Z" }, - { url = "https://files.pythonhosted.org/packages/f3/e2/88ad1c4c42861dd09b45924e468c42a1beb2c5267cb960b7a9f6af67dd04/propcache-0.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c86e7ceea56376216eba345aa1fc6a8a6b27ac236181f840d1d7e6a1ea9ba5c", size = 46462, upload-time = "2025-03-26T03:05:45.569Z" }, - { url = "https://files.pythonhosted.org/packages/ae/7e/3e3b36854e96be2e881bc6e87293d59c74dd734dd038dd4981474be44e26/propcache-0.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83be47aa4e35b87c106fc0c84c0fc069d3f9b9b06d3c494cd404ec6747544894", size = 209214, upload-time = "2025-03-26T03:05:47.366Z" }, - { url = "https://files.pythonhosted.org/packages/11/1a/ac0f757cc0babdc8217056fca85150066cf43bf11db9651e6b7d8e0646d6/propcache-0.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27c6ac6aa9fc7bc662f594ef380707494cb42c22786a558d95fcdedb9aa5d035", size = 224702, upload-time = "2025-03-26T03:05:48.946Z" }, - { url = "https://files.pythonhosted.org/packages/92/0a/0cf77d0e984b7058019ffa5385b3efd6962cbd5340a8f278ae103032863a/propcache-0.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a956dff37080b352c1c40b2966b09defb014347043e740d420ca1eb7c9b908", size = 223085, upload-time = "2025-03-26T03:05:50.472Z" }, - { url = "https://files.pythonhosted.org/packages/05/fc/cb52a0caf803caff9b95b0a99e7c9c87f15b7e34ba0feebfd2572b49013d/propcache-0.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82de5da8c8893056603ac2d6a89eb8b4df49abf1a7c19d536984c8dd63f481d5", size = 209613, upload-time = "2025-03-26T03:05:52.36Z" }, - { url = "https://files.pythonhosted.org/packages/e5/fc/b1d1fdffbe1e0278ab535f8d21fc6b030889417714a545755bdd5ebe9bb0/propcache-0.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3c3a203c375b08fd06a20da3cf7aac293b834b6f4f4db71190e8422750cca5", size = 199931, upload-time = "2025-03-26T03:05:54.302Z" }, - { url = "https://files.pythonhosted.org/packages/23/a9/2a2f8d93d8f526c35dd8dbbc4a1ac22a106712cd821e15e2a6530aea8931/propcache-0.3.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b303b194c2e6f171cfddf8b8ba30baefccf03d36a4d9cab7fd0bb68ba476a3d7", size = 208937, upload-time = "2025-03-26T03:05:56.38Z" }, - { url = "https://files.pythonhosted.org/packages/ef/71/5247a264b95e8d4ba86757cf9ad6a523d764bd4579a2d80007a2d4d2b0ad/propcache-0.3.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:916cd229b0150129d645ec51614d38129ee74c03293a9f3f17537be0029a9641", size = 202577, upload-time = "2025-03-26T03:05:58.325Z" }, - { url = "https://files.pythonhosted.org/packages/6f/4e/c8ec771731f1b1e7d07bd8875f1d13c1564b5d60f7483624d021eaef5687/propcache-0.3.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a461959ead5b38e2581998700b26346b78cd98540b5524796c175722f18b0294", size = 204669, upload-time = "2025-03-26T03:05:59.849Z" }, - { url = "https://files.pythonhosted.org/packages/c5/b8/bdfcb1170a7b8504226064d7c0b4deb61acbcc6bb2e754ee25fb36c1b72a/propcache-0.3.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:069e7212890b0bcf9b2be0a03afb0c2d5161d91e1bf51569a64f629acc7defbf", size = 214334, upload-time = "2025-03-26T03:06:01.905Z" }, - { url = "https://files.pythonhosted.org/packages/72/c6/fdb9e8ba161a4e12c75a7415cb99314cad195d3b8ae9d770783cec54001e/propcache-0.3.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ef2e4e91fb3945769e14ce82ed53007195e616a63aa43b40fb7ebaaf907c8d4c", size = 218052, upload-time = "2025-03-26T03:06:03.586Z" }, - { url = "https://files.pythonhosted.org/packages/67/3f/0dd87220f61598b61b590a8b3562142ae475a9c0f694ee32bf97e4e41d44/propcache-0.3.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8638f99dca15b9dff328fb6273e09f03d1c50d9b6512f3b65a4154588a7595fe", size = 210852, upload-time = "2025-03-26T03:06:05.045Z" }, - { url = "https://files.pythonhosted.org/packages/7b/4e/e332164372af66992c07b470448beb7e36ce7dba6a06c6c2b6131f112e74/propcache-0.3.1-cp39-cp39-win32.whl", hash = "sha256:6f173bbfe976105aaa890b712d1759de339d8a7cef2fc0a1714cc1a1e1c47f64", size = 41481, upload-time = "2025-03-26T03:06:07.507Z" }, - { url = "https://files.pythonhosted.org/packages/61/73/d64abb7bb5d18880ecfac152247c0f1a5807256ea21e4737ce3019afffeb/propcache-0.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:603f1fe4144420374f1a69b907494c3acbc867a581c2d49d4175b0de7cc64566", size = 45720, upload-time = "2025-03-26T03:06:09.139Z" }, - { url = "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", size = 12376, upload-time = "2025-03-26T03:06:10.5Z" }, + { url = "https://files.pythonhosted.org/packages/20/56/e27c136101addf877c8291dbda1b3b86ae848f3837ce758510a0d806c92f/propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98", size = 80224 }, + { url = "https://files.pythonhosted.org/packages/63/bd/88e98836544c4f04db97eefd23b037c2002fa173dd2772301c61cd3085f9/propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180", size = 46491 }, + { url = "https://files.pythonhosted.org/packages/15/43/0b8eb2a55753c4a574fc0899885da504b521068d3b08ca56774cad0bea2b/propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71", size = 45927 }, + { url = "https://files.pythonhosted.org/packages/ad/6c/d01f9dfbbdc613305e0a831016844987a1fb4861dd221cd4c69b1216b43f/propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649", size = 206135 }, + { url = "https://files.pythonhosted.org/packages/9a/8a/e6e1c77394088f4cfdace4a91a7328e398ebed745d59c2f6764135c5342d/propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f", size = 220517 }, + { url = "https://files.pythonhosted.org/packages/19/3b/6c44fa59d6418f4239d5db8b1ece757351e85d6f3ca126dfe37d427020c8/propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229", size = 218952 }, + { url = "https://files.pythonhosted.org/packages/7c/e4/4aeb95a1cd085e0558ab0de95abfc5187329616193a1012a6c4c930e9f7a/propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46", size = 206593 }, + { url = "https://files.pythonhosted.org/packages/da/6a/29fa75de1cbbb302f1e1d684009b969976ca603ee162282ae702287b6621/propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7", size = 196745 }, + { url = "https://files.pythonhosted.org/packages/19/7e/2237dad1dbffdd2162de470599fa1a1d55df493b16b71e5d25a0ac1c1543/propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0", size = 203369 }, + { url = "https://files.pythonhosted.org/packages/a4/bc/a82c5878eb3afb5c88da86e2cf06e1fe78b7875b26198dbb70fe50a010dc/propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519", size = 198723 }, + { url = "https://files.pythonhosted.org/packages/17/76/9632254479c55516f51644ddbf747a45f813031af5adcb8db91c0b824375/propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd", size = 200751 }, + { url = "https://files.pythonhosted.org/packages/3e/c3/a90b773cf639bd01d12a9e20c95be0ae978a5a8abe6d2d343900ae76cd71/propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259", size = 210730 }, + { url = "https://files.pythonhosted.org/packages/ed/ec/ad5a952cdb9d65c351f88db7c46957edd3d65ffeee72a2f18bd6341433e0/propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e", size = 213499 }, + { url = "https://files.pythonhosted.org/packages/83/c0/ea5133dda43e298cd2010ec05c2821b391e10980e64ee72c0a76cdbb813a/propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136", size = 207132 }, + { url = "https://files.pythonhosted.org/packages/79/dd/71aae9dec59333064cfdd7eb31a63fa09f64181b979802a67a90b2abfcba/propcache-0.3.1-cp310-cp310-win32.whl", hash = "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42", size = 40952 }, + { url = "https://files.pythonhosted.org/packages/31/0a/49ff7e5056c17dfba62cbdcbb90a29daffd199c52f8e65e5cb09d5f53a57/propcache-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833", size = 45163 }, + { url = "https://files.pythonhosted.org/packages/90/0f/5a5319ee83bd651f75311fcb0c492c21322a7fc8f788e4eef23f44243427/propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5", size = 80243 }, + { url = "https://files.pythonhosted.org/packages/ce/84/3db5537e0879942783e2256616ff15d870a11d7ac26541336fe1b673c818/propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371", size = 46503 }, + { url = "https://files.pythonhosted.org/packages/e2/c8/b649ed972433c3f0d827d7f0cf9ea47162f4ef8f4fe98c5f3641a0bc63ff/propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da", size = 45934 }, + { url = "https://files.pythonhosted.org/packages/59/f9/4c0a5cf6974c2c43b1a6810c40d889769cc8f84cea676cbe1e62766a45f8/propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744", size = 233633 }, + { url = "https://files.pythonhosted.org/packages/e7/64/66f2f4d1b4f0007c6e9078bd95b609b633d3957fe6dd23eac33ebde4b584/propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0", size = 241124 }, + { url = "https://files.pythonhosted.org/packages/aa/bf/7b8c9fd097d511638fa9b6af3d986adbdf567598a567b46338c925144c1b/propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5", size = 240283 }, + { url = "https://files.pythonhosted.org/packages/fa/c9/e85aeeeaae83358e2a1ef32d6ff50a483a5d5248bc38510d030a6f4e2816/propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256", size = 232498 }, + { url = "https://files.pythonhosted.org/packages/8e/66/acb88e1f30ef5536d785c283af2e62931cb934a56a3ecf39105887aa8905/propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073", size = 221486 }, + { url = "https://files.pythonhosted.org/packages/f5/f9/233ddb05ffdcaee4448508ee1d70aa7deff21bb41469ccdfcc339f871427/propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d", size = 222675 }, + { url = "https://files.pythonhosted.org/packages/98/b8/eb977e28138f9e22a5a789daf608d36e05ed93093ef12a12441030da800a/propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f", size = 215727 }, + { url = "https://files.pythonhosted.org/packages/89/2d/5f52d9c579f67b8ee1edd9ec073c91b23cc5b7ff7951a1e449e04ed8fdf3/propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0", size = 217878 }, + { url = "https://files.pythonhosted.org/packages/7a/fd/5283e5ed8a82b00c7a989b99bb6ea173db1ad750bf0bf8dff08d3f4a4e28/propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a", size = 230558 }, + { url = "https://files.pythonhosted.org/packages/90/38/ab17d75938ef7ac87332c588857422ae126b1c76253f0f5b1242032923ca/propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a", size = 233754 }, + { url = "https://files.pythonhosted.org/packages/06/5d/3b921b9c60659ae464137508d3b4c2b3f52f592ceb1964aa2533b32fcf0b/propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9", size = 226088 }, + { url = "https://files.pythonhosted.org/packages/54/6e/30a11f4417d9266b5a464ac5a8c5164ddc9dd153dfa77bf57918165eb4ae/propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005", size = 40859 }, + { url = "https://files.pythonhosted.org/packages/1d/3a/8a68dd867da9ca2ee9dfd361093e9cb08cb0f37e5ddb2276f1b5177d7731/propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7", size = 45153 }, + { url = "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", size = 80430 }, + { url = "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", size = 46637 }, + { url = "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", size = 46123 }, + { url = "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", size = 243031 }, + { url = "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", size = 249100 }, + { url = "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", size = 250170 }, + { url = "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", size = 245000 }, + { url = "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", size = 230262 }, + { url = "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", size = 236772 }, + { url = "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", size = 231133 }, + { url = "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", size = 230741 }, + { url = "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", size = 244047 }, + { url = "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", size = 246467 }, + { url = "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", size = 241022 }, + { url = "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", size = 40647 }, + { url = "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", size = 44784 }, + { url = "https://files.pythonhosted.org/packages/58/60/f645cc8b570f99be3cf46714170c2de4b4c9d6b827b912811eff1eb8a412/propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8", size = 77865 }, + { url = "https://files.pythonhosted.org/packages/6f/d4/c1adbf3901537582e65cf90fd9c26fde1298fde5a2c593f987112c0d0798/propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f", size = 45452 }, + { url = "https://files.pythonhosted.org/packages/d1/b5/fe752b2e63f49f727c6c1c224175d21b7d1727ce1d4873ef1c24c9216830/propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111", size = 44800 }, + { url = "https://files.pythonhosted.org/packages/62/37/fc357e345bc1971e21f76597028b059c3d795c5ca7690d7a8d9a03c9708a/propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5", size = 225804 }, + { url = "https://files.pythonhosted.org/packages/0d/f1/16e12c33e3dbe7f8b737809bad05719cff1dccb8df4dafbcff5575002c0e/propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb", size = 230650 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/018b9f2ed876bf5091e60153f727e8f9073d97573f790ff7cdf6bc1d1fb8/propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7", size = 234235 }, + { url = "https://files.pythonhosted.org/packages/45/5f/3faee66fc930dfb5da509e34c6ac7128870631c0e3582987fad161fcb4b1/propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120", size = 228249 }, + { url = "https://files.pythonhosted.org/packages/62/1e/a0d5ebda5da7ff34d2f5259a3e171a94be83c41eb1e7cd21a2105a84a02e/propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654", size = 214964 }, + { url = "https://files.pythonhosted.org/packages/db/a0/d72da3f61ceab126e9be1f3bc7844b4e98c6e61c985097474668e7e52152/propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e", size = 222501 }, + { url = "https://files.pythonhosted.org/packages/18/6d/a008e07ad7b905011253adbbd97e5b5375c33f0b961355ca0a30377504ac/propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b", size = 217917 }, + { url = "https://files.pythonhosted.org/packages/98/37/02c9343ffe59e590e0e56dc5c97d0da2b8b19fa747ebacf158310f97a79a/propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53", size = 217089 }, + { url = "https://files.pythonhosted.org/packages/53/1b/d3406629a2c8a5666d4674c50f757a77be119b113eedd47b0375afdf1b42/propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5", size = 228102 }, + { url = "https://files.pythonhosted.org/packages/cd/a7/3664756cf50ce739e5f3abd48febc0be1a713b1f389a502ca819791a6b69/propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7", size = 230122 }, + { url = "https://files.pythonhosted.org/packages/35/36/0bbabaacdcc26dac4f8139625e930f4311864251276033a52fd52ff2a274/propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef", size = 226818 }, + { url = "https://files.pythonhosted.org/packages/cc/27/4e0ef21084b53bd35d4dae1634b6d0bad35e9c58ed4f032511acca9d4d26/propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24", size = 40112 }, + { url = "https://files.pythonhosted.org/packages/a6/2c/a54614d61895ba6dd7ac8f107e2b2a0347259ab29cbf2ecc7b94fa38c4dc/propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037", size = 44034 }, + { url = "https://files.pythonhosted.org/packages/5a/a8/0a4fd2f664fc6acc66438370905124ce62e84e2e860f2557015ee4a61c7e/propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f", size = 82613 }, + { url = "https://files.pythonhosted.org/packages/4d/e5/5ef30eb2cd81576256d7b6caaa0ce33cd1d2c2c92c8903cccb1af1a4ff2f/propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c", size = 47763 }, + { url = "https://files.pythonhosted.org/packages/87/9a/87091ceb048efeba4d28e903c0b15bcc84b7c0bf27dc0261e62335d9b7b8/propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc", size = 47175 }, + { url = "https://files.pythonhosted.org/packages/3e/2f/854e653c96ad1161f96194c6678a41bbb38c7947d17768e8811a77635a08/propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de", size = 292265 }, + { url = "https://files.pythonhosted.org/packages/40/8d/090955e13ed06bc3496ba4a9fb26c62e209ac41973cb0d6222de20c6868f/propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6", size = 294412 }, + { url = "https://files.pythonhosted.org/packages/39/e6/d51601342e53cc7582449e6a3c14a0479fab2f0750c1f4d22302e34219c6/propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7", size = 294290 }, + { url = "https://files.pythonhosted.org/packages/3b/4d/be5f1a90abc1881884aa5878989a1acdafd379a91d9c7e5e12cef37ec0d7/propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458", size = 282926 }, + { url = "https://files.pythonhosted.org/packages/57/2b/8f61b998c7ea93a2b7eca79e53f3e903db1787fca9373af9e2cf8dc22f9d/propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11", size = 267808 }, + { url = "https://files.pythonhosted.org/packages/11/1c/311326c3dfce59c58a6098388ba984b0e5fb0381ef2279ec458ef99bd547/propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c", size = 290916 }, + { url = "https://files.pythonhosted.org/packages/4b/74/91939924b0385e54dc48eb2e4edd1e4903ffd053cf1916ebc5347ac227f7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf", size = 262661 }, + { url = "https://files.pythonhosted.org/packages/c2/d7/e6079af45136ad325c5337f5dd9ef97ab5dc349e0ff362fe5c5db95e2454/propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27", size = 264384 }, + { url = "https://files.pythonhosted.org/packages/b7/d5/ba91702207ac61ae6f1c2da81c5d0d6bf6ce89e08a2b4d44e411c0bbe867/propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757", size = 291420 }, + { url = "https://files.pythonhosted.org/packages/58/70/2117780ed7edcd7ba6b8134cb7802aada90b894a9810ec56b7bb6018bee7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18", size = 290880 }, + { url = "https://files.pythonhosted.org/packages/4a/1f/ecd9ce27710021ae623631c0146719280a929d895a095f6d85efb6a0be2e/propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a", size = 287407 }, + { url = "https://files.pythonhosted.org/packages/3e/66/2e90547d6b60180fb29e23dc87bd8c116517d4255240ec6d3f7dc23d1926/propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d", size = 42573 }, + { url = "https://files.pythonhosted.org/packages/cb/8f/50ad8599399d1861b4d2b6b45271f0ef6af1b09b0a2386a46dbaf19c9535/propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e", size = 46757 }, + { url = "https://files.pythonhosted.org/packages/aa/e1/4a782cdc7ebc42dfb44224dabf93b481395a0b6cbc9f0149785edbbab19c/propcache-0.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ed5f6d2edbf349bd8d630e81f474d33d6ae5d07760c44d33cd808e2f5c8f4ae6", size = 81368 }, + { url = "https://files.pythonhosted.org/packages/18/c6/9a39b2646a71321815d8d616e890851af9fb327af7d1b9fdce7d2d8377ca/propcache-0.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:668ddddc9f3075af019f784456267eb504cb77c2c4bd46cc8402d723b4d200bf", size = 47037 }, + { url = "https://files.pythonhosted.org/packages/f3/e2/88ad1c4c42861dd09b45924e468c42a1beb2c5267cb960b7a9f6af67dd04/propcache-0.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c86e7ceea56376216eba345aa1fc6a8a6b27ac236181f840d1d7e6a1ea9ba5c", size = 46462 }, + { url = "https://files.pythonhosted.org/packages/ae/7e/3e3b36854e96be2e881bc6e87293d59c74dd734dd038dd4981474be44e26/propcache-0.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83be47aa4e35b87c106fc0c84c0fc069d3f9b9b06d3c494cd404ec6747544894", size = 209214 }, + { url = "https://files.pythonhosted.org/packages/11/1a/ac0f757cc0babdc8217056fca85150066cf43bf11db9651e6b7d8e0646d6/propcache-0.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27c6ac6aa9fc7bc662f594ef380707494cb42c22786a558d95fcdedb9aa5d035", size = 224702 }, + { url = "https://files.pythonhosted.org/packages/92/0a/0cf77d0e984b7058019ffa5385b3efd6962cbd5340a8f278ae103032863a/propcache-0.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a956dff37080b352c1c40b2966b09defb014347043e740d420ca1eb7c9b908", size = 223085 }, + { url = "https://files.pythonhosted.org/packages/05/fc/cb52a0caf803caff9b95b0a99e7c9c87f15b7e34ba0feebfd2572b49013d/propcache-0.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82de5da8c8893056603ac2d6a89eb8b4df49abf1a7c19d536984c8dd63f481d5", size = 209613 }, + { url = "https://files.pythonhosted.org/packages/e5/fc/b1d1fdffbe1e0278ab535f8d21fc6b030889417714a545755bdd5ebe9bb0/propcache-0.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3c3a203c375b08fd06a20da3cf7aac293b834b6f4f4db71190e8422750cca5", size = 199931 }, + { url = "https://files.pythonhosted.org/packages/23/a9/2a2f8d93d8f526c35dd8dbbc4a1ac22a106712cd821e15e2a6530aea8931/propcache-0.3.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b303b194c2e6f171cfddf8b8ba30baefccf03d36a4d9cab7fd0bb68ba476a3d7", size = 208937 }, + { url = "https://files.pythonhosted.org/packages/ef/71/5247a264b95e8d4ba86757cf9ad6a523d764bd4579a2d80007a2d4d2b0ad/propcache-0.3.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:916cd229b0150129d645ec51614d38129ee74c03293a9f3f17537be0029a9641", size = 202577 }, + { url = "https://files.pythonhosted.org/packages/6f/4e/c8ec771731f1b1e7d07bd8875f1d13c1564b5d60f7483624d021eaef5687/propcache-0.3.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a461959ead5b38e2581998700b26346b78cd98540b5524796c175722f18b0294", size = 204669 }, + { url = "https://files.pythonhosted.org/packages/c5/b8/bdfcb1170a7b8504226064d7c0b4deb61acbcc6bb2e754ee25fb36c1b72a/propcache-0.3.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:069e7212890b0bcf9b2be0a03afb0c2d5161d91e1bf51569a64f629acc7defbf", size = 214334 }, + { url = "https://files.pythonhosted.org/packages/72/c6/fdb9e8ba161a4e12c75a7415cb99314cad195d3b8ae9d770783cec54001e/propcache-0.3.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ef2e4e91fb3945769e14ce82ed53007195e616a63aa43b40fb7ebaaf907c8d4c", size = 218052 }, + { url = "https://files.pythonhosted.org/packages/67/3f/0dd87220f61598b61b590a8b3562142ae475a9c0f694ee32bf97e4e41d44/propcache-0.3.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8638f99dca15b9dff328fb6273e09f03d1c50d9b6512f3b65a4154588a7595fe", size = 210852 }, + { url = "https://files.pythonhosted.org/packages/7b/4e/e332164372af66992c07b470448beb7e36ce7dba6a06c6c2b6131f112e74/propcache-0.3.1-cp39-cp39-win32.whl", hash = "sha256:6f173bbfe976105aaa890b712d1759de339d8a7cef2fc0a1714cc1a1e1c47f64", size = 41481 }, + { url = "https://files.pythonhosted.org/packages/61/73/d64abb7bb5d18880ecfac152247c0f1a5807256ea21e4737ce3019afffeb/propcache-0.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:603f1fe4144420374f1a69b907494c3acbc867a581c2d49d4175b0de7cc64566", size = 45720 }, + { url = "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", size = 12376 }, ] [[package]] name = "py-cpuinfo" version = "9.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716, upload-time = "2022-10-25T20:38:06.303Z" } +sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335, upload-time = "2022-10-25T20:38:27.636Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335 }, ] [[package]] name = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, ] [[package]] @@ -988,9 +990,9 @@ dependencies = [ { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681, upload-time = "2025-01-24T01:42:12.693Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696, upload-time = "2025-01-24T01:42:10.371Z" }, + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, ] [[package]] @@ -1000,103 +1002,103 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938, upload-time = "2024-12-18T11:27:14.406Z" }, - { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684, upload-time = "2024-12-18T11:27:16.489Z" }, - { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169, upload-time = "2024-12-18T11:27:22.16Z" }, - { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227, upload-time = "2024-12-18T11:27:25.097Z" }, - { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695, upload-time = "2024-12-18T11:27:28.656Z" }, - { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662, upload-time = "2024-12-18T11:27:30.798Z" }, - { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370, upload-time = "2024-12-18T11:27:33.692Z" }, - { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813, upload-time = "2024-12-18T11:27:37.111Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287, upload-time = "2024-12-18T11:27:40.566Z" }, - { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414, upload-time = "2024-12-18T11:27:43.757Z" }, - { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301, upload-time = "2024-12-18T11:27:47.36Z" }, - { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685, upload-time = "2024-12-18T11:27:50.508Z" }, - { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876, upload-time = "2024-12-18T11:27:53.54Z" }, - { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421, upload-time = "2024-12-18T11:27:55.409Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998, upload-time = "2024-12-18T11:27:57.252Z" }, - { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167, upload-time = "2024-12-18T11:27:59.146Z" }, - { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071, upload-time = "2024-12-18T11:28:02.625Z" }, - { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244, upload-time = "2024-12-18T11:28:04.442Z" }, - { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470, upload-time = "2024-12-18T11:28:07.679Z" }, - { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291, upload-time = "2024-12-18T11:28:10.297Z" }, - { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613, upload-time = "2024-12-18T11:28:13.362Z" }, - { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355, upload-time = "2024-12-18T11:28:16.587Z" }, - { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661, upload-time = "2024-12-18T11:28:18.407Z" }, - { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261, upload-time = "2024-12-18T11:28:21.471Z" }, - { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361, upload-time = "2024-12-18T11:28:23.53Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484, upload-time = "2024-12-18T11:28:25.391Z" }, - { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102, upload-time = "2024-12-18T11:28:28.593Z" }, - { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127, upload-time = "2024-12-18T11:28:30.346Z" }, - { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340, upload-time = "2024-12-18T11:28:32.521Z" }, - { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900, upload-time = "2024-12-18T11:28:34.507Z" }, - { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177, upload-time = "2024-12-18T11:28:36.488Z" }, - { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046, upload-time = "2024-12-18T11:28:39.409Z" }, - { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386, upload-time = "2024-12-18T11:28:41.221Z" }, - { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060, upload-time = "2024-12-18T11:28:44.709Z" }, - { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870, upload-time = "2024-12-18T11:28:46.839Z" }, - { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822, upload-time = "2024-12-18T11:28:48.896Z" }, - { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364, upload-time = "2024-12-18T11:28:50.755Z" }, - { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303, upload-time = "2024-12-18T11:28:54.122Z" }, - { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064, upload-time = "2024-12-18T11:28:56.074Z" }, - { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046, upload-time = "2024-12-18T11:28:58.107Z" }, - { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092, upload-time = "2024-12-18T11:29:01.335Z" }, - { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" }, - { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" }, - { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" }, - { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" }, - { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" }, - { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" }, - { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" }, - { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" }, - { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" }, - { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" }, - { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" }, - { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" }, - { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" }, - { url = "https://files.pythonhosted.org/packages/27/97/3aef1ddb65c5ccd6eda9050036c956ff6ecbfe66cb7eb40f280f121a5bb0/pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993", size = 1896475, upload-time = "2024-12-18T11:30:18.316Z" }, - { url = "https://files.pythonhosted.org/packages/ad/d3/5668da70e373c9904ed2f372cb52c0b996426f302e0dee2e65634c92007d/pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308", size = 1772279, upload-time = "2024-12-18T11:30:20.547Z" }, - { url = "https://files.pythonhosted.org/packages/8a/9e/e44b8cb0edf04a2f0a1f6425a65ee089c1d6f9c4c2dcab0209127b6fdfc2/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4", size = 1829112, upload-time = "2024-12-18T11:30:23.255Z" }, - { url = "https://files.pythonhosted.org/packages/1c/90/1160d7ac700102effe11616e8119e268770f2a2aa5afb935f3ee6832987d/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf", size = 1866780, upload-time = "2024-12-18T11:30:25.742Z" }, - { url = "https://files.pythonhosted.org/packages/ee/33/13983426df09a36d22c15980008f8d9c77674fc319351813b5a2739b70f3/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76", size = 2037943, upload-time = "2024-12-18T11:30:28.036Z" }, - { url = "https://files.pythonhosted.org/packages/01/d7/ced164e376f6747e9158c89988c293cd524ab8d215ae4e185e9929655d5c/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118", size = 2740492, upload-time = "2024-12-18T11:30:30.412Z" }, - { url = "https://files.pythonhosted.org/packages/8b/1f/3dc6e769d5b7461040778816aab2b00422427bcaa4b56cc89e9c653b2605/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630", size = 1995714, upload-time = "2024-12-18T11:30:34.358Z" }, - { url = "https://files.pythonhosted.org/packages/07/d7/a0bd09bc39283530b3f7c27033a814ef254ba3bd0b5cfd040b7abf1fe5da/pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54", size = 1997163, upload-time = "2024-12-18T11:30:37.979Z" }, - { url = "https://files.pythonhosted.org/packages/2d/bb/2db4ad1762e1c5699d9b857eeb41959191980de6feb054e70f93085e1bcd/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f", size = 2005217, upload-time = "2024-12-18T11:30:40.367Z" }, - { url = "https://files.pythonhosted.org/packages/53/5f/23a5a3e7b8403f8dd8fc8a6f8b49f6b55c7d715b77dcf1f8ae919eeb5628/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362", size = 2127899, upload-time = "2024-12-18T11:30:42.737Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ae/aa38bb8dd3d89c2f1d8362dd890ee8f3b967330821d03bbe08fa01ce3766/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96", size = 2155726, upload-time = "2024-12-18T11:30:45.279Z" }, - { url = "https://files.pythonhosted.org/packages/98/61/4f784608cc9e98f70839187117ce840480f768fed5d386f924074bf6213c/pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e", size = 1817219, upload-time = "2024-12-18T11:30:47.718Z" }, - { url = "https://files.pythonhosted.org/packages/57/82/bb16a68e4a1a858bb3768c2c8f1ff8d8978014e16598f001ea29a25bf1d1/pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67", size = 1985382, upload-time = "2024-12-18T11:30:51.871Z" }, - { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159, upload-time = "2024-12-18T11:30:54.382Z" }, - { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331, upload-time = "2024-12-18T11:30:58.178Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467, upload-time = "2024-12-18T11:31:00.6Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797, upload-time = "2024-12-18T11:31:07.243Z" }, - { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839, upload-time = "2024-12-18T11:31:09.775Z" }, - { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861, upload-time = "2024-12-18T11:31:13.469Z" }, - { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582, upload-time = "2024-12-18T11:31:17.423Z" }, - { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985, upload-time = "2024-12-18T11:31:19.901Z" }, - { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715, upload-time = "2024-12-18T11:31:22.821Z" }, - { url = "https://files.pythonhosted.org/packages/29/0e/dcaea00c9dbd0348b723cae82b0e0c122e0fa2b43fa933e1622fd237a3ee/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656", size = 1891733, upload-time = "2024-12-18T11:31:26.876Z" }, - { url = "https://files.pythonhosted.org/packages/86/d3/e797bba8860ce650272bda6383a9d8cad1d1c9a75a640c9d0e848076f85e/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278", size = 1768375, upload-time = "2024-12-18T11:31:29.276Z" }, - { url = "https://files.pythonhosted.org/packages/41/f7/f847b15fb14978ca2b30262548f5fc4872b2724e90f116393eb69008299d/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb", size = 1822307, upload-time = "2024-12-18T11:31:33.123Z" }, - { url = "https://files.pythonhosted.org/packages/9c/63/ed80ec8255b587b2f108e514dc03eed1546cd00f0af281e699797f373f38/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd", size = 1979971, upload-time = "2024-12-18T11:31:35.755Z" }, - { url = "https://files.pythonhosted.org/packages/a9/6d/6d18308a45454a0de0e975d70171cadaf454bc7a0bf86b9c7688e313f0bb/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc", size = 1987616, upload-time = "2024-12-18T11:31:38.534Z" }, - { url = "https://files.pythonhosted.org/packages/82/8a/05f8780f2c1081b800a7ca54c1971e291c2d07d1a50fb23c7e4aef4ed403/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b", size = 1998943, upload-time = "2024-12-18T11:31:41.853Z" }, - { url = "https://files.pythonhosted.org/packages/5e/3e/fe5b6613d9e4c0038434396b46c5303f5ade871166900b357ada4766c5b7/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b", size = 2116654, upload-time = "2024-12-18T11:31:44.756Z" }, - { url = "https://files.pythonhosted.org/packages/db/ad/28869f58938fad8cc84739c4e592989730bfb69b7c90a8fff138dff18e1e/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2", size = 2152292, upload-time = "2024-12-18T11:31:48.613Z" }, - { url = "https://files.pythonhosted.org/packages/a1/0c/c5c5cd3689c32ed1fe8c5d234b079c12c281c051759770c05b8bed6412b5/pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", size = 2004961, upload-time = "2024-12-18T11:31:52.446Z" }, + { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 }, + { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 }, + { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 }, + { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 }, + { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 }, + { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 }, + { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 }, + { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 }, + { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 }, + { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 }, + { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 }, + { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 }, + { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 }, + { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, + { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, + { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, + { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, + { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, + { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, + { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, + { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, + { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, + { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, + { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, + { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, + { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, + { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, + { url = "https://files.pythonhosted.org/packages/27/97/3aef1ddb65c5ccd6eda9050036c956ff6ecbfe66cb7eb40f280f121a5bb0/pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993", size = 1896475 }, + { url = "https://files.pythonhosted.org/packages/ad/d3/5668da70e373c9904ed2f372cb52c0b996426f302e0dee2e65634c92007d/pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308", size = 1772279 }, + { url = "https://files.pythonhosted.org/packages/8a/9e/e44b8cb0edf04a2f0a1f6425a65ee089c1d6f9c4c2dcab0209127b6fdfc2/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4", size = 1829112 }, + { url = "https://files.pythonhosted.org/packages/1c/90/1160d7ac700102effe11616e8119e268770f2a2aa5afb935f3ee6832987d/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf", size = 1866780 }, + { url = "https://files.pythonhosted.org/packages/ee/33/13983426df09a36d22c15980008f8d9c77674fc319351813b5a2739b70f3/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76", size = 2037943 }, + { url = "https://files.pythonhosted.org/packages/01/d7/ced164e376f6747e9158c89988c293cd524ab8d215ae4e185e9929655d5c/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118", size = 2740492 }, + { url = "https://files.pythonhosted.org/packages/8b/1f/3dc6e769d5b7461040778816aab2b00422427bcaa4b56cc89e9c653b2605/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630", size = 1995714 }, + { url = "https://files.pythonhosted.org/packages/07/d7/a0bd09bc39283530b3f7c27033a814ef254ba3bd0b5cfd040b7abf1fe5da/pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54", size = 1997163 }, + { url = "https://files.pythonhosted.org/packages/2d/bb/2db4ad1762e1c5699d9b857eeb41959191980de6feb054e70f93085e1bcd/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f", size = 2005217 }, + { url = "https://files.pythonhosted.org/packages/53/5f/23a5a3e7b8403f8dd8fc8a6f8b49f6b55c7d715b77dcf1f8ae919eeb5628/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362", size = 2127899 }, + { url = "https://files.pythonhosted.org/packages/c2/ae/aa38bb8dd3d89c2f1d8362dd890ee8f3b967330821d03bbe08fa01ce3766/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96", size = 2155726 }, + { url = "https://files.pythonhosted.org/packages/98/61/4f784608cc9e98f70839187117ce840480f768fed5d386f924074bf6213c/pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e", size = 1817219 }, + { url = "https://files.pythonhosted.org/packages/57/82/bb16a68e4a1a858bb3768c2c8f1ff8d8978014e16598f001ea29a25bf1d1/pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67", size = 1985382 }, + { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 }, + { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 }, + { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 }, + { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 }, + { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 }, + { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 }, + { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 }, + { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 }, + { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 }, + { url = "https://files.pythonhosted.org/packages/29/0e/dcaea00c9dbd0348b723cae82b0e0c122e0fa2b43fa933e1622fd237a3ee/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656", size = 1891733 }, + { url = "https://files.pythonhosted.org/packages/86/d3/e797bba8860ce650272bda6383a9d8cad1d1c9a75a640c9d0e848076f85e/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278", size = 1768375 }, + { url = "https://files.pythonhosted.org/packages/41/f7/f847b15fb14978ca2b30262548f5fc4872b2724e90f116393eb69008299d/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb", size = 1822307 }, + { url = "https://files.pythonhosted.org/packages/9c/63/ed80ec8255b587b2f108e514dc03eed1546cd00f0af281e699797f373f38/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd", size = 1979971 }, + { url = "https://files.pythonhosted.org/packages/a9/6d/6d18308a45454a0de0e975d70171cadaf454bc7a0bf86b9c7688e313f0bb/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc", size = 1987616 }, + { url = "https://files.pythonhosted.org/packages/82/8a/05f8780f2c1081b800a7ca54c1971e291c2d07d1a50fb23c7e4aef4ed403/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b", size = 1998943 }, + { url = "https://files.pythonhosted.org/packages/5e/3e/fe5b6613d9e4c0038434396b46c5303f5ade871166900b357ada4766c5b7/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b", size = 2116654 }, + { url = "https://files.pythonhosted.org/packages/db/ad/28869f58938fad8cc84739c4e592989730bfb69b7c90a8fff138dff18e1e/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2", size = 2152292 }, + { url = "https://files.pythonhosted.org/packages/a1/0c/c5c5cd3689c32ed1fe8c5d234b079c12c281c051759770c05b8bed6412b5/pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", size = 2004961 }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, ] [[package]] @@ -1111,9 +1113,9 @@ dependencies = [ { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919, upload-time = "2024-12-01T12:54:25.98Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083, upload-time = "2024-12-01T12:54:19.735Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, ] [[package]] @@ -1125,9 +1127,9 @@ dependencies = [ { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, + { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157 }, ] [[package]] @@ -1138,9 +1140,9 @@ dependencies = [ { name = "py-cpuinfo" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/39/d0/a8bd08d641b393db3be3819b03e2d9bb8760ca8479080a26a5f6e540e99c/pytest-benchmark-5.1.0.tar.gz", hash = "sha256:9ea661cdc292e8231f7cd4c10b0319e56a2118e2c09d9f50e1b3d150d2aca105", size = 337810, upload-time = "2024-10-30T11:51:48.521Z" } +sdist = { url = "https://files.pythonhosted.org/packages/39/d0/a8bd08d641b393db3be3819b03e2d9bb8760ca8479080a26a5f6e540e99c/pytest-benchmark-5.1.0.tar.gz", hash = "sha256:9ea661cdc292e8231f7cd4c10b0319e56a2118e2c09d9f50e1b3d150d2aca105", size = 337810 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/d6/b41653199ea09d5969d4e385df9bbfd9a100f28ca7e824ce7c0a016e3053/pytest_benchmark-5.1.0-py3-none-any.whl", hash = "sha256:922de2dfa3033c227c96da942d1878191afa135a29485fb942e85dff1c592c89", size = 44259, upload-time = "2024-10-30T11:51:45.94Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/b41653199ea09d5969d4e385df9bbfd9a100f28ca7e824ce7c0a016e3053/pytest_benchmark-5.1.0-py3-none-any.whl", hash = "sha256:922de2dfa3033c227c96da942d1878191afa135a29485fb942e85dff1c592c89", size = 44259 }, ] [[package]] @@ -1153,19 +1155,19 @@ dependencies = [ { name = "pytest" }, { name = "rich" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/98/16fe3895b1b8a6d537a89eecb120b97358df8f0002c6ecd11555d6304dc8/pytest_codspeed-3.2.0.tar.gz", hash = "sha256:f9d1b1a3b2c69cdc0490a1e8b1ced44bffbd0e8e21d81a7160cfdd923f6e8155", size = 18409, upload-time = "2025-01-31T14:28:26.165Z" } +sdist = { url = "https://files.pythonhosted.org/packages/03/98/16fe3895b1b8a6d537a89eecb120b97358df8f0002c6ecd11555d6304dc8/pytest_codspeed-3.2.0.tar.gz", hash = "sha256:f9d1b1a3b2c69cdc0490a1e8b1ced44bffbd0e8e21d81a7160cfdd923f6e8155", size = 18409 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/31/62b93ee025ca46016d01325f58997d32303752286bf929588c8796a25b13/pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5165774424c7ab8db7e7acdb539763a0e5657996effefdf0664d7fd95158d34", size = 26802, upload-time = "2025-01-31T14:28:10.723Z" }, - { url = "https://files.pythonhosted.org/packages/89/60/2bc46bdf8c8ddb7e59cd9d480dc887d0ac6039f88c856d1ae3d29a4e648d/pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bd55f92d772592c04a55209950c50880413ae46876e66bd349ef157075ca26c", size = 25442, upload-time = "2025-01-31T14:28:11.774Z" }, - { url = "https://files.pythonhosted.org/packages/31/56/1b65ba0ae1af7fd7ce14a66e7599833efe8bbd0fcecd3614db0017ca224a/pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf6f56067538f4892baa8d7ab5ef4e45bb59033be1ef18759a2c7fc55b32035", size = 26810, upload-time = "2025-01-31T14:28:12.657Z" }, - { url = "https://files.pythonhosted.org/packages/23/e6/d1fafb09a1c4983372f562d9e158735229cb0b11603a61d4fad05463f977/pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39a687b05c3d145642061b45ea78e47e12f13ce510104d1a2cda00eee0e36f58", size = 25442, upload-time = "2025-01-31T14:28:13.485Z" }, - { url = "https://files.pythonhosted.org/packages/0b/8b/9e95472589d17bb68960f2a09cfa8f02c4d43c82de55b73302bbe0fa4350/pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46a1afaaa1ac4c2ca5b0700d31ac46d80a27612961d031067d73c6ccbd8d3c2b", size = 27182, upload-time = "2025-01-31T14:28:15.828Z" }, - { url = "https://files.pythonhosted.org/packages/2a/18/82aaed8095e84d829f30dda3ac49fce4e69685d769aae463614a8d864cdd/pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c48ce3af3dfa78413ed3d69d1924043aa1519048dbff46edccf8f35a25dab3c2", size = 25933, upload-time = "2025-01-31T14:28:17.151Z" }, - { url = "https://files.pythonhosted.org/packages/e2/15/60b18d40da66e7aa2ce4c4c66d5a17de20a2ae4a89ac09a58baa7a5bc535/pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66692506d33453df48b36a84703448cb8b22953eea51f03fbb2eb758dc2bdc4f", size = 27180, upload-time = "2025-01-31T14:28:18.056Z" }, - { url = "https://files.pythonhosted.org/packages/51/bd/6b164d4ae07d8bea5d02ad664a9762bdb63f83c0805a3c8fe7dc6ec38407/pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:479774f80d0bdfafa16112700df4dbd31bf2a6757fac74795fd79c0a7b3c389b", size = 25923, upload-time = "2025-01-31T14:28:19.725Z" }, - { url = "https://files.pythonhosted.org/packages/90/bb/5d73c59d750264863c25fc202bcc37c5f8a390df640a4760eba54151753e/pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:109f9f4dd1088019c3b3f887d003b7d65f98a7736ca1d457884f5aa293e8e81c", size = 26795, upload-time = "2025-01-31T14:28:22.021Z" }, - { url = "https://files.pythonhosted.org/packages/65/17/d4bf207b63f1edc5b9c06ad77df565d186e0fd40f13459bb124304b54b1d/pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2f69a03b52c9bb041aec1b8ee54b7b6c37a6d0a948786effa4c71157765b6da", size = 25433, upload-time = "2025-01-31T14:28:22.955Z" }, - { url = "https://files.pythonhosted.org/packages/f1/9b/952c70bd1fae9baa58077272e7f191f377c86d812263c21b361195e125e6/pytest_codspeed-3.2.0-py3-none-any.whl", hash = "sha256:54b5c2e986d6a28e7b0af11d610ea57bd5531cec8326abe486f1b55b09d91c39", size = 15007, upload-time = "2025-01-31T14:28:24.458Z" }, + { url = "https://files.pythonhosted.org/packages/b9/31/62b93ee025ca46016d01325f58997d32303752286bf929588c8796a25b13/pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5165774424c7ab8db7e7acdb539763a0e5657996effefdf0664d7fd95158d34", size = 26802 }, + { url = "https://files.pythonhosted.org/packages/89/60/2bc46bdf8c8ddb7e59cd9d480dc887d0ac6039f88c856d1ae3d29a4e648d/pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bd55f92d772592c04a55209950c50880413ae46876e66bd349ef157075ca26c", size = 25442 }, + { url = "https://files.pythonhosted.org/packages/31/56/1b65ba0ae1af7fd7ce14a66e7599833efe8bbd0fcecd3614db0017ca224a/pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf6f56067538f4892baa8d7ab5ef4e45bb59033be1ef18759a2c7fc55b32035", size = 26810 }, + { url = "https://files.pythonhosted.org/packages/23/e6/d1fafb09a1c4983372f562d9e158735229cb0b11603a61d4fad05463f977/pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39a687b05c3d145642061b45ea78e47e12f13ce510104d1a2cda00eee0e36f58", size = 25442 }, + { url = "https://files.pythonhosted.org/packages/0b/8b/9e95472589d17bb68960f2a09cfa8f02c4d43c82de55b73302bbe0fa4350/pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46a1afaaa1ac4c2ca5b0700d31ac46d80a27612961d031067d73c6ccbd8d3c2b", size = 27182 }, + { url = "https://files.pythonhosted.org/packages/2a/18/82aaed8095e84d829f30dda3ac49fce4e69685d769aae463614a8d864cdd/pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c48ce3af3dfa78413ed3d69d1924043aa1519048dbff46edccf8f35a25dab3c2", size = 25933 }, + { url = "https://files.pythonhosted.org/packages/e2/15/60b18d40da66e7aa2ce4c4c66d5a17de20a2ae4a89ac09a58baa7a5bc535/pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66692506d33453df48b36a84703448cb8b22953eea51f03fbb2eb758dc2bdc4f", size = 27180 }, + { url = "https://files.pythonhosted.org/packages/51/bd/6b164d4ae07d8bea5d02ad664a9762bdb63f83c0805a3c8fe7dc6ec38407/pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:479774f80d0bdfafa16112700df4dbd31bf2a6757fac74795fd79c0a7b3c389b", size = 25923 }, + { url = "https://files.pythonhosted.org/packages/90/bb/5d73c59d750264863c25fc202bcc37c5f8a390df640a4760eba54151753e/pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:109f9f4dd1088019c3b3f887d003b7d65f98a7736ca1d457884f5aa293e8e81c", size = 26795 }, + { url = "https://files.pythonhosted.org/packages/65/17/d4bf207b63f1edc5b9c06ad77df565d186e0fd40f13459bb124304b54b1d/pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2f69a03b52c9bb041aec1b8ee54b7b6c37a6d0a948786effa4c71157765b6da", size = 25433 }, + { url = "https://files.pythonhosted.org/packages/f1/9b/952c70bd1fae9baa58077272e7f191f377c86d812263c21b361195e125e6/pytest_codspeed-3.2.0-py3-none-any.whl", hash = "sha256:54b5c2e986d6a28e7b0af11d610ea57bd5531cec8326abe486f1b55b09d91c39", size = 15007 }, ] [[package]] @@ -1176,9 +1178,9 @@ dependencies = [ { name = "pytest" }, { name = "vcrpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/9c/f4027c5f1693847b06d11caf4b4f6bb09f22c1581ada4663877ec166b8c6/pytest_recording-0.13.4.tar.gz", hash = "sha256:568d64b2a85992eec4ae0a419c855d5fd96782c5fb016784d86f18053792768c", size = 26576, upload-time = "2025-05-08T10:41:11.231Z" } +sdist = { url = "https://files.pythonhosted.org/packages/32/9c/f4027c5f1693847b06d11caf4b4f6bb09f22c1581ada4663877ec166b8c6/pytest_recording-0.13.4.tar.gz", hash = "sha256:568d64b2a85992eec4ae0a419c855d5fd96782c5fb016784d86f18053792768c", size = 26576 } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/c2/ce34735972cc42d912173e79f200fe66530225190c06655c5632a9d88f1e/pytest_recording-0.13.4-py3-none-any.whl", hash = "sha256:ad49a434b51b1c4f78e85b1e6b74fdcc2a0a581ca16e52c798c6ace971f7f439", size = 13723, upload-time = "2025-05-08T10:41:09.684Z" }, + { url = "https://files.pythonhosted.org/packages/42/c2/ce34735972cc42d912173e79f200fe66530225190c06655c5632a9d88f1e/pytest_recording-0.13.4-py3-none-any.whl", hash = "sha256:ad49a434b51b1c4f78e85b1e6b74fdcc2a0a581ca16e52c798c6ace971f7f439", size = 13723 }, ] [[package]] @@ -1188,62 +1190,62 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/ff/90c7e1e746baf3d62ce864c479fd53410b534818b9437413903596f81580/pytest_socket-0.7.0.tar.gz", hash = "sha256:71ab048cbbcb085c15a4423b73b619a8b35d6a307f46f78ea46be51b1b7e11b3", size = 12389, upload-time = "2024-01-28T20:17:23.177Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/ff/90c7e1e746baf3d62ce864c479fd53410b534818b9437413903596f81580/pytest_socket-0.7.0.tar.gz", hash = "sha256:71ab048cbbcb085c15a4423b73b619a8b35d6a307f46f78ea46be51b1b7e11b3", size = 12389 } wheels = [ - { url = "https://files.pythonhosted.org/packages/19/58/5d14cb5cb59409e491ebe816c47bf81423cd03098ea92281336320ae5681/pytest_socket-0.7.0-py3-none-any.whl", hash = "sha256:7e0f4642177d55d317bbd58fc68c6bd9048d6eadb2d46a89307fa9221336ce45", size = 6754, upload-time = "2024-01-28T20:17:22.105Z" }, + { url = "https://files.pythonhosted.org/packages/19/58/5d14cb5cb59409e491ebe816c47bf81423cd03098ea92281336320ae5681/pytest_socket-0.7.0-py3-none-any.whl", hash = "sha256:7e0f4642177d55d317bbd58fc68c6bd9048d6eadb2d46a89307fa9221336ce45", size = 6754 }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, - { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, - { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, - { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, - { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, - { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, - { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, - { url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777, upload-time = "2024-08-06T20:33:25.896Z" }, - { url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318, upload-time = "2024-08-06T20:33:27.212Z" }, - { url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891, upload-time = "2024-08-06T20:33:28.974Z" }, - { url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614, upload-time = "2024-08-06T20:33:34.157Z" }, - { url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360, upload-time = "2024-08-06T20:33:35.84Z" }, - { url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006, upload-time = "2024-08-06T20:33:37.501Z" }, - { url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577, upload-time = "2024-08-06T20:33:39.389Z" }, - { url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593, upload-time = "2024-08-06T20:33:46.63Z" }, - { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312, upload-time = "2024-08-06T20:33:49.073Z" }, + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, + { url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777 }, + { url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318 }, + { url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891 }, + { url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614 }, + { url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360 }, + { url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006 }, + { url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577 }, + { url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593 }, + { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312 }, ] [[package]] @@ -1257,9 +1259,9 @@ dependencies = [ { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or platform_python_implementation == 'PyPy'" }, { name = "urllib3", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' and platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] [[package]] @@ -1269,9 +1271,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload-time = "2023-05-01T04:11:33.229Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888 } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 }, ] [[package]] @@ -1283,44 +1285,44 @@ dependencies = [ { name = "pygments" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229 }, ] [[package]] name = "ruff" version = "0.12.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3b/eb/8c073deb376e46ae767f4961390d17545e8535921d2f65101720ed8bd434/ruff-0.12.10.tar.gz", hash = "sha256:189ab65149d11ea69a2d775343adf5f49bb2426fc4780f65ee33b423ad2e47f9", size = 5310076, upload-time = "2025-08-21T18:23:22.595Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/eb/8c073deb376e46ae767f4961390d17545e8535921d2f65101720ed8bd434/ruff-0.12.10.tar.gz", hash = "sha256:189ab65149d11ea69a2d775343adf5f49bb2426fc4780f65ee33b423ad2e47f9", size = 5310076 } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/e7/560d049d15585d6c201f9eeacd2fd130def3741323e5ccf123786e0e3c95/ruff-0.12.10-py3-none-linux_armv6l.whl", hash = "sha256:8b593cb0fb55cc8692dac7b06deb29afda78c721c7ccfed22db941201b7b8f7b", size = 11935161, upload-time = "2025-08-21T18:22:26.965Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b0/ad2464922a1113c365d12b8f80ed70fcfb39764288ac77c995156080488d/ruff-0.12.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ebb7333a45d56efc7c110a46a69a1b32365d5c5161e7244aaf3aa20ce62399c1", size = 12660884, upload-time = "2025-08-21T18:22:30.925Z" }, - { url = "https://files.pythonhosted.org/packages/d7/f1/97f509b4108d7bae16c48389f54f005b62ce86712120fd8b2d8e88a7cb49/ruff-0.12.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d59e58586829f8e4a9920788f6efba97a13d1fa320b047814e8afede381c6839", size = 11872754, upload-time = "2025-08-21T18:22:34.035Z" }, - { url = "https://files.pythonhosted.org/packages/12/ad/44f606d243f744a75adc432275217296095101f83f966842063d78eee2d3/ruff-0.12.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:822d9677b560f1fdeab69b89d1f444bf5459da4aa04e06e766cf0121771ab844", size = 12092276, upload-time = "2025-08-21T18:22:36.764Z" }, - { url = "https://files.pythonhosted.org/packages/06/1f/ed6c265e199568010197909b25c896d66e4ef2c5e1c3808caf461f6f3579/ruff-0.12.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b4a64f4062a50c75019c61c7017ff598cb444984b638511f48539d3a1c98db", size = 11734700, upload-time = "2025-08-21T18:22:39.822Z" }, - { url = "https://files.pythonhosted.org/packages/63/c5/b21cde720f54a1d1db71538c0bc9b73dee4b563a7dd7d2e404914904d7f5/ruff-0.12.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c6f4064c69d2542029b2a61d39920c85240c39837599d7f2e32e80d36401d6e", size = 13468783, upload-time = "2025-08-21T18:22:42.559Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/39369e6ac7f2a1848f22fb0b00b690492f20811a1ac5c1fd1d2798329263/ruff-0.12.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:059e863ea3a9ade41407ad71c1de2badfbe01539117f38f763ba42a1206f7559", size = 14436642, upload-time = "2025-08-21T18:22:45.612Z" }, - { url = "https://files.pythonhosted.org/packages/e3/03/5da8cad4b0d5242a936eb203b58318016db44f5c5d351b07e3f5e211bb89/ruff-0.12.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1bef6161e297c68908b7218fa6e0e93e99a286e5ed9653d4be71e687dff101cf", size = 13859107, upload-time = "2025-08-21T18:22:48.886Z" }, - { url = "https://files.pythonhosted.org/packages/19/19/dd7273b69bf7f93a070c9cec9494a94048325ad18fdcf50114f07e6bf417/ruff-0.12.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4f1345fbf8fb0531cd722285b5f15af49b2932742fc96b633e883da8d841896b", size = 12886521, upload-time = "2025-08-21T18:22:51.567Z" }, - { url = "https://files.pythonhosted.org/packages/c0/1d/b4207ec35e7babaee62c462769e77457e26eb853fbdc877af29417033333/ruff-0.12.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f68433c4fbc63efbfa3ba5db31727db229fa4e61000f452c540474b03de52a9", size = 13097528, upload-time = "2025-08-21T18:22:54.609Z" }, - { url = "https://files.pythonhosted.org/packages/ff/00/58f7b873b21114456e880b75176af3490d7a2836033779ca42f50de3b47a/ruff-0.12.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:141ce3d88803c625257b8a6debf4a0473eb6eed9643a6189b68838b43e78165a", size = 13080443, upload-time = "2025-08-21T18:22:57.413Z" }, - { url = "https://files.pythonhosted.org/packages/12/8c/9e6660007fb10189ccb78a02b41691288038e51e4788bf49b0a60f740604/ruff-0.12.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f3fc21178cd44c98142ae7590f42ddcb587b8e09a3b849cbc84edb62ee95de60", size = 11896759, upload-time = "2025-08-21T18:23:00.473Z" }, - { url = "https://files.pythonhosted.org/packages/67/4c/6d092bb99ea9ea6ebda817a0e7ad886f42a58b4501a7e27cd97371d0ba54/ruff-0.12.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7d1a4e0bdfafcd2e3e235ecf50bf0176f74dd37902f241588ae1f6c827a36c56", size = 11701463, upload-time = "2025-08-21T18:23:03.211Z" }, - { url = "https://files.pythonhosted.org/packages/59/80/d982c55e91df981f3ab62559371380616c57ffd0172d96850280c2b04fa8/ruff-0.12.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e67d96827854f50b9e3e8327b031647e7bcc090dbe7bb11101a81a3a2cbf1cc9", size = 12691603, upload-time = "2025-08-21T18:23:06.935Z" }, - { url = "https://files.pythonhosted.org/packages/ad/37/63a9c788bbe0b0850611669ec6b8589838faf2f4f959647f2d3e320383ae/ruff-0.12.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ae479e1a18b439c59138f066ae79cc0f3ee250712a873d00dbafadaad9481e5b", size = 13164356, upload-time = "2025-08-21T18:23:10.225Z" }, - { url = "https://files.pythonhosted.org/packages/47/d4/1aaa7fb201a74181989970ebccd12f88c0fc074777027e2a21de5a90657e/ruff-0.12.10-py3-none-win32.whl", hash = "sha256:9de785e95dc2f09846c5e6e1d3a3d32ecd0b283a979898ad427a9be7be22b266", size = 11896089, upload-time = "2025-08-21T18:23:14.232Z" }, - { url = "https://files.pythonhosted.org/packages/ad/14/2ad38fd4037daab9e023456a4a40ed0154e9971f8d6aed41bdea390aabd9/ruff-0.12.10-py3-none-win_amd64.whl", hash = "sha256:7837eca8787f076f67aba2ca559cefd9c5cbc3a9852fd66186f4201b87c1563e", size = 13004616, upload-time = "2025-08-21T18:23:17.422Z" }, - { url = "https://files.pythonhosted.org/packages/24/3c/21cf283d67af33a8e6ed242396863af195a8a6134ec581524fd22b9811b6/ruff-0.12.10-py3-none-win_arm64.whl", hash = "sha256:cc138cc06ed9d4bfa9d667a65af7172b47840e1a98b02ce7011c391e54635ffc", size = 12074225, upload-time = "2025-08-21T18:23:20.137Z" }, + { url = "https://files.pythonhosted.org/packages/24/e7/560d049d15585d6c201f9eeacd2fd130def3741323e5ccf123786e0e3c95/ruff-0.12.10-py3-none-linux_armv6l.whl", hash = "sha256:8b593cb0fb55cc8692dac7b06deb29afda78c721c7ccfed22db941201b7b8f7b", size = 11935161 }, + { url = "https://files.pythonhosted.org/packages/d1/b0/ad2464922a1113c365d12b8f80ed70fcfb39764288ac77c995156080488d/ruff-0.12.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ebb7333a45d56efc7c110a46a69a1b32365d5c5161e7244aaf3aa20ce62399c1", size = 12660884 }, + { url = "https://files.pythonhosted.org/packages/d7/f1/97f509b4108d7bae16c48389f54f005b62ce86712120fd8b2d8e88a7cb49/ruff-0.12.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d59e58586829f8e4a9920788f6efba97a13d1fa320b047814e8afede381c6839", size = 11872754 }, + { url = "https://files.pythonhosted.org/packages/12/ad/44f606d243f744a75adc432275217296095101f83f966842063d78eee2d3/ruff-0.12.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:822d9677b560f1fdeab69b89d1f444bf5459da4aa04e06e766cf0121771ab844", size = 12092276 }, + { url = "https://files.pythonhosted.org/packages/06/1f/ed6c265e199568010197909b25c896d66e4ef2c5e1c3808caf461f6f3579/ruff-0.12.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b4a64f4062a50c75019c61c7017ff598cb444984b638511f48539d3a1c98db", size = 11734700 }, + { url = "https://files.pythonhosted.org/packages/63/c5/b21cde720f54a1d1db71538c0bc9b73dee4b563a7dd7d2e404914904d7f5/ruff-0.12.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c6f4064c69d2542029b2a61d39920c85240c39837599d7f2e32e80d36401d6e", size = 13468783 }, + { url = "https://files.pythonhosted.org/packages/02/9e/39369e6ac7f2a1848f22fb0b00b690492f20811a1ac5c1fd1d2798329263/ruff-0.12.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:059e863ea3a9ade41407ad71c1de2badfbe01539117f38f763ba42a1206f7559", size = 14436642 }, + { url = "https://files.pythonhosted.org/packages/e3/03/5da8cad4b0d5242a936eb203b58318016db44f5c5d351b07e3f5e211bb89/ruff-0.12.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1bef6161e297c68908b7218fa6e0e93e99a286e5ed9653d4be71e687dff101cf", size = 13859107 }, + { url = "https://files.pythonhosted.org/packages/19/19/dd7273b69bf7f93a070c9cec9494a94048325ad18fdcf50114f07e6bf417/ruff-0.12.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4f1345fbf8fb0531cd722285b5f15af49b2932742fc96b633e883da8d841896b", size = 12886521 }, + { url = "https://files.pythonhosted.org/packages/c0/1d/b4207ec35e7babaee62c462769e77457e26eb853fbdc877af29417033333/ruff-0.12.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f68433c4fbc63efbfa3ba5db31727db229fa4e61000f452c540474b03de52a9", size = 13097528 }, + { url = "https://files.pythonhosted.org/packages/ff/00/58f7b873b21114456e880b75176af3490d7a2836033779ca42f50de3b47a/ruff-0.12.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:141ce3d88803c625257b8a6debf4a0473eb6eed9643a6189b68838b43e78165a", size = 13080443 }, + { url = "https://files.pythonhosted.org/packages/12/8c/9e6660007fb10189ccb78a02b41691288038e51e4788bf49b0a60f740604/ruff-0.12.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f3fc21178cd44c98142ae7590f42ddcb587b8e09a3b849cbc84edb62ee95de60", size = 11896759 }, + { url = "https://files.pythonhosted.org/packages/67/4c/6d092bb99ea9ea6ebda817a0e7ad886f42a58b4501a7e27cd97371d0ba54/ruff-0.12.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7d1a4e0bdfafcd2e3e235ecf50bf0176f74dd37902f241588ae1f6c827a36c56", size = 11701463 }, + { url = "https://files.pythonhosted.org/packages/59/80/d982c55e91df981f3ab62559371380616c57ffd0172d96850280c2b04fa8/ruff-0.12.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e67d96827854f50b9e3e8327b031647e7bcc090dbe7bb11101a81a3a2cbf1cc9", size = 12691603 }, + { url = "https://files.pythonhosted.org/packages/ad/37/63a9c788bbe0b0850611669ec6b8589838faf2f4f959647f2d3e320383ae/ruff-0.12.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ae479e1a18b439c59138f066ae79cc0f3ee250712a873d00dbafadaad9481e5b", size = 13164356 }, + { url = "https://files.pythonhosted.org/packages/47/d4/1aaa7fb201a74181989970ebccd12f88c0fc074777027e2a21de5a90657e/ruff-0.12.10-py3-none-win32.whl", hash = "sha256:9de785e95dc2f09846c5e6e1d3a3d32ecd0b283a979898ad427a9be7be22b266", size = 11896089 }, + { url = "https://files.pythonhosted.org/packages/ad/14/2ad38fd4037daab9e023456a4a40ed0154e9971f8d6aed41bdea390aabd9/ruff-0.12.10-py3-none-win_amd64.whl", hash = "sha256:7837eca8787f076f67aba2ca559cefd9c5cbc3a9852fd66186f4201b87c1563e", size = 13004616 }, + { url = "https://files.pythonhosted.org/packages/24/3c/21cf283d67af33a8e6ed242396863af195a8a6134ec581524fd22b9811b6/ruff-0.12.10-py3-none-win_arm64.whl", hash = "sha256:cc138cc06ed9d4bfa9d667a65af7172b47840e1a98b02ce7011c391e54635ffc", size = 12074225 }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] [[package]] @@ -1330,66 +1332,75 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c4/32/8b56491ed50ae103c2db14885c29fe765170bdf044fe5868548113da35ef/syrupy-4.8.1.tar.gz", hash = "sha256:8da8c0311e6d92de0b15767768c6ab98982b7b4a4c67083c08fbac3fbad4d44c", size = 50192, upload-time = "2025-01-13T12:09:31.445Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/32/8b56491ed50ae103c2db14885c29fe765170bdf044fe5868548113da35ef/syrupy-4.8.1.tar.gz", hash = "sha256:8da8c0311e6d92de0b15767768c6ab98982b7b4a4c67083c08fbac3fbad4d44c", size = 50192 } wheels = [ - { url = "https://files.pythonhosted.org/packages/80/47/5e8f44ec0f287b08e8c1f3fc63fe1fbe182f07bf606eec903d7827b95e51/syrupy-4.8.1-py3-none-any.whl", hash = "sha256:274f97cbaf44175f5e478a2f3a53559d31f41c66c6bf28131695f94ac893ea00", size = 50326, upload-time = "2025-01-13T12:09:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/80/47/5e8f44ec0f287b08e8c1f3fc63fe1fbe182f07bf606eec903d7827b95e51/syrupy-4.8.1-py3-none-any.whl", hash = "sha256:274f97cbaf44175f5e478a2f3a53559d31f41c66c6bf28131695f94ac893ea00", size = 50326 }, ] [[package]] name = "tenacity" version = "9.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421, upload-time = "2024-07-29T12:12:27.547Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169, upload-time = "2024-07-29T12:12:25.825Z" }, + { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/85/90a442e538359ab5c9e30de415006fb22567aa4301c908c09f19e42975c2/types_pyyaml-6.0.12.20250822.tar.gz", hash = "sha256:259f1d93079d335730a9db7cff2bcaf65d7e04b4a56b5927d49a612199b59413", size = 17481 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/8e/8f0aca667c97c0d76024b37cffa39e76e2ce39ca54a38f285a64e6ae33ba/types_pyyaml-6.0.12.20250822-py3-none-any.whl", hash = "sha256:1fe1a5e146aa315483592d292b72a172b65b946a6d98aa6ddd8e4aa838ab7098", size = 20314 }, ] [[package]] name = "typing-extensions" version = "4.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, ] [[package]] @@ -1403,9 +1414,9 @@ resolution-markers = [ "python_full_version < '3.10' and platform_python_implementation == 'PyPy'", "python_full_version < '3.10' and platform_python_implementation != 'PyPy'", ] -sdist = { url = "https://files.pythonhosted.org/packages/e4/e8/6ff5e6bc22095cfc59b6ea711b687e2b7ed4bdb373f7eeec370a97d7392f/urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32", size = 307380, upload-time = "2024-08-29T15:43:11.37Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/e8/6ff5e6bc22095cfc59b6ea711b687e2b7ed4bdb373f7eeec370a97d7392f/urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32", size = 307380 } wheels = [ - { url = "https://files.pythonhosted.org/packages/33/cf/8435d5a7159e2a9c83a95896ed596f68cf798005fe107cc655b5c5c14704/urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", size = 144225, upload-time = "2024-08-29T15:43:08.921Z" }, + { url = "https://files.pythonhosted.org/packages/33/cf/8435d5a7159e2a9c83a95896ed596f68cf798005fe107cc655b5c5c14704/urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", size = 144225 }, ] [[package]] @@ -1417,9 +1428,9 @@ resolution-markers = [ "python_full_version >= '3.12.4' and python_full_version < '3.13' and platform_python_implementation != 'PyPy'", "python_full_version >= '3.10' and python_full_version < '3.12.4' and platform_python_implementation != 'PyPy'", ] -sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268, upload-time = "2024-12-22T07:47:30.032Z" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369, upload-time = "2024-12-22T07:47:28.074Z" }, + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, ] [[package]] @@ -1433,84 +1444,84 @@ dependencies = [ { name = "wrapt" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/25/d3/856e06184d4572aada1dd559ddec3bedc46df1f2edc5ab2c91121a2cccdb/vcrpy-7.0.0.tar.gz", hash = "sha256:176391ad0425edde1680c5b20738ea3dc7fb942520a48d2993448050986b3a50", size = 85502, upload-time = "2024-12-31T00:07:57.894Z" } +sdist = { url = "https://files.pythonhosted.org/packages/25/d3/856e06184d4572aada1dd559ddec3bedc46df1f2edc5ab2c91121a2cccdb/vcrpy-7.0.0.tar.gz", hash = "sha256:176391ad0425edde1680c5b20738ea3dc7fb942520a48d2993448050986b3a50", size = 85502 } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/5d/1f15b252890c968d42b348d1e9b0aa12d5bf3e776704178ec37cceccdb63/vcrpy-7.0.0-py2.py3-none-any.whl", hash = "sha256:55791e26c18daa363435054d8b35bd41a4ac441b6676167635d1b37a71dbe124", size = 42321, upload-time = "2024-12-31T00:07:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/13/5d/1f15b252890c968d42b348d1e9b0aa12d5bf3e776704178ec37cceccdb63/vcrpy-7.0.0-py2.py3-none-any.whl", hash = "sha256:55791e26c18daa363435054d8b35bd41a4ac441b6676167635d1b37a71dbe124", size = 42321 }, ] [[package]] name = "wrapt" version = "1.17.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531, upload-time = "2025-01-14T10:35:45.465Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/d1/1daec934997e8b160040c78d7b31789f19b122110a75eca3d4e8da0049e1/wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", size = 53307, upload-time = "2025-01-14T10:33:13.616Z" }, - { url = "https://files.pythonhosted.org/packages/1b/7b/13369d42651b809389c1a7153baa01d9700430576c81a2f5c5e460df0ed9/wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", size = 38486, upload-time = "2025-01-14T10:33:15.947Z" }, - { url = "https://files.pythonhosted.org/packages/62/bf/e0105016f907c30b4bd9e377867c48c34dc9c6c0c104556c9c9126bd89ed/wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", size = 38777, upload-time = "2025-01-14T10:33:17.462Z" }, - { url = "https://files.pythonhosted.org/packages/27/70/0f6e0679845cbf8b165e027d43402a55494779295c4b08414097b258ac87/wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", size = 83314, upload-time = "2025-01-14T10:33:21.282Z" }, - { url = "https://files.pythonhosted.org/packages/0f/77/0576d841bf84af8579124a93d216f55d6f74374e4445264cb378a6ed33eb/wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", size = 74947, upload-time = "2025-01-14T10:33:24.414Z" }, - { url = "https://files.pythonhosted.org/packages/90/ec/00759565518f268ed707dcc40f7eeec38637d46b098a1f5143bff488fe97/wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", size = 82778, upload-time = "2025-01-14T10:33:26.152Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5a/7cffd26b1c607b0b0c8a9ca9d75757ad7620c9c0a9b4a25d3f8a1480fafc/wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", size = 81716, upload-time = "2025-01-14T10:33:27.372Z" }, - { url = "https://files.pythonhosted.org/packages/7e/09/dccf68fa98e862df7e6a60a61d43d644b7d095a5fc36dbb591bbd4a1c7b2/wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", size = 74548, upload-time = "2025-01-14T10:33:28.52Z" }, - { url = "https://files.pythonhosted.org/packages/b7/8e/067021fa3c8814952c5e228d916963c1115b983e21393289de15128e867e/wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", size = 81334, upload-time = "2025-01-14T10:33:29.643Z" }, - { url = "https://files.pythonhosted.org/packages/4b/0d/9d4b5219ae4393f718699ca1c05f5ebc0c40d076f7e65fd48f5f693294fb/wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", size = 36427, upload-time = "2025-01-14T10:33:30.832Z" }, - { url = "https://files.pythonhosted.org/packages/72/6a/c5a83e8f61aec1e1aeef939807602fb880e5872371e95df2137142f5c58e/wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", size = 38774, upload-time = "2025-01-14T10:33:32.897Z" }, - { url = "https://files.pythonhosted.org/packages/cd/f7/a2aab2cbc7a665efab072344a8949a71081eed1d2f451f7f7d2b966594a2/wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58", size = 53308, upload-time = "2025-01-14T10:33:33.992Z" }, - { url = "https://files.pythonhosted.org/packages/50/ff/149aba8365fdacef52b31a258c4dc1c57c79759c335eff0b3316a2664a64/wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", size = 38488, upload-time = "2025-01-14T10:33:35.264Z" }, - { url = "https://files.pythonhosted.org/packages/65/46/5a917ce85b5c3b490d35c02bf71aedaa9f2f63f2d15d9949cc4ba56e8ba9/wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", size = 38776, upload-time = "2025-01-14T10:33:38.28Z" }, - { url = "https://files.pythonhosted.org/packages/ca/74/336c918d2915a4943501c77566db41d1bd6e9f4dbc317f356b9a244dfe83/wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", size = 83776, upload-time = "2025-01-14T10:33:40.678Z" }, - { url = "https://files.pythonhosted.org/packages/09/99/c0c844a5ccde0fe5761d4305485297f91d67cf2a1a824c5f282e661ec7ff/wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", size = 75420, upload-time = "2025-01-14T10:33:41.868Z" }, - { url = "https://files.pythonhosted.org/packages/b4/b0/9fc566b0fe08b282c850063591a756057c3247b2362b9286429ec5bf1721/wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", size = 83199, upload-time = "2025-01-14T10:33:43.598Z" }, - { url = "https://files.pythonhosted.org/packages/9d/4b/71996e62d543b0a0bd95dda485219856def3347e3e9380cc0d6cf10cfb2f/wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", size = 82307, upload-time = "2025-01-14T10:33:48.499Z" }, - { url = "https://files.pythonhosted.org/packages/39/35/0282c0d8789c0dc9bcc738911776c762a701f95cfe113fb8f0b40e45c2b9/wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", size = 75025, upload-time = "2025-01-14T10:33:51.191Z" }, - { url = "https://files.pythonhosted.org/packages/4f/6d/90c9fd2c3c6fee181feecb620d95105370198b6b98a0770cba090441a828/wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", size = 81879, upload-time = "2025-01-14T10:33:52.328Z" }, - { url = "https://files.pythonhosted.org/packages/8f/fa/9fb6e594f2ce03ef03eddbdb5f4f90acb1452221a5351116c7c4708ac865/wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", size = 36419, upload-time = "2025-01-14T10:33:53.551Z" }, - { url = "https://files.pythonhosted.org/packages/47/f8/fb1773491a253cbc123c5d5dc15c86041f746ed30416535f2a8df1f4a392/wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", size = 38773, upload-time = "2025-01-14T10:33:56.323Z" }, - { url = "https://files.pythonhosted.org/packages/a1/bd/ab55f849fd1f9a58ed7ea47f5559ff09741b25f00c191231f9f059c83949/wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", size = 53799, upload-time = "2025-01-14T10:33:57.4Z" }, - { url = "https://files.pythonhosted.org/packages/53/18/75ddc64c3f63988f5a1d7e10fb204ffe5762bc663f8023f18ecaf31a332e/wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", size = 38821, upload-time = "2025-01-14T10:33:59.334Z" }, - { url = "https://files.pythonhosted.org/packages/48/2a/97928387d6ed1c1ebbfd4efc4133a0633546bec8481a2dd5ec961313a1c7/wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", size = 38919, upload-time = "2025-01-14T10:34:04.093Z" }, - { url = "https://files.pythonhosted.org/packages/73/54/3bfe5a1febbbccb7a2f77de47b989c0b85ed3a6a41614b104204a788c20e/wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", size = 88721, upload-time = "2025-01-14T10:34:07.163Z" }, - { url = "https://files.pythonhosted.org/packages/25/cb/7262bc1b0300b4b64af50c2720ef958c2c1917525238d661c3e9a2b71b7b/wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", size = 80899, upload-time = "2025-01-14T10:34:09.82Z" }, - { url = "https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", size = 89222, upload-time = "2025-01-14T10:34:11.258Z" }, - { url = "https://files.pythonhosted.org/packages/09/28/2e45a4f4771fcfb109e244d5dbe54259e970362a311b67a965555ba65026/wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", size = 86707, upload-time = "2025-01-14T10:34:12.49Z" }, - { url = "https://files.pythonhosted.org/packages/c6/d2/dcb56bf5f32fcd4bd9aacc77b50a539abdd5b6536872413fd3f428b21bed/wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", size = 79685, upload-time = "2025-01-14T10:34:15.043Z" }, - { url = "https://files.pythonhosted.org/packages/80/4e/eb8b353e36711347893f502ce91c770b0b0929f8f0bed2670a6856e667a9/wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", size = 87567, upload-time = "2025-01-14T10:34:16.563Z" }, - { url = "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", size = 36672, upload-time = "2025-01-14T10:34:17.727Z" }, - { url = "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", size = 38865, upload-time = "2025-01-14T10:34:19.577Z" }, - { url = "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", size = 53800, upload-time = "2025-01-14T10:34:21.571Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", size = 38824, upload-time = "2025-01-14T10:34:22.999Z" }, - { url = "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", size = 38920, upload-time = "2025-01-14T10:34:25.386Z" }, - { url = "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", size = 88690, upload-time = "2025-01-14T10:34:28.058Z" }, - { url = "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", size = 80861, upload-time = "2025-01-14T10:34:29.167Z" }, - { url = "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", size = 89174, upload-time = "2025-01-14T10:34:31.702Z" }, - { url = "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", size = 86721, upload-time = "2025-01-14T10:34:32.91Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", size = 79763, upload-time = "2025-01-14T10:34:34.903Z" }, - { url = "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", size = 87585, upload-time = "2025-01-14T10:34:36.13Z" }, - { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676, upload-time = "2025-01-14T10:34:37.962Z" }, - { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871, upload-time = "2025-01-14T10:34:39.13Z" }, - { url = "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", size = 56312, upload-time = "2025-01-14T10:34:40.604Z" }, - { url = "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", size = 40062, upload-time = "2025-01-14T10:34:45.011Z" }, - { url = "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", size = 40155, upload-time = "2025-01-14T10:34:47.25Z" }, - { url = "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", size = 113471, upload-time = "2025-01-14T10:34:50.934Z" }, - { url = "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", size = 101208, upload-time = "2025-01-14T10:34:52.297Z" }, - { url = "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", size = 109339, upload-time = "2025-01-14T10:34:53.489Z" }, - { url = "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", size = 110232, upload-time = "2025-01-14T10:34:55.327Z" }, - { url = "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", size = 100476, upload-time = "2025-01-14T10:34:58.055Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", size = 106377, upload-time = "2025-01-14T10:34:59.3Z" }, - { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986, upload-time = "2025-01-14T10:35:00.498Z" }, - { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750, upload-time = "2025-01-14T10:35:03.378Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f4/6ed2b8f6f1c832933283974839b88ec7c983fd12905e01e97889dadf7559/wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", size = 53308, upload-time = "2025-01-14T10:35:24.413Z" }, - { url = "https://files.pythonhosted.org/packages/a2/a9/712a53f8f4f4545768ac532619f6e56d5d0364a87b2212531685e89aeef8/wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", size = 38489, upload-time = "2025-01-14T10:35:26.913Z" }, - { url = "https://files.pythonhosted.org/packages/fa/9b/e172c8f28a489a2888df18f953e2f6cb8d33b1a2e78c9dfc52d8bf6a5ead/wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82", size = 38776, upload-time = "2025-01-14T10:35:28.183Z" }, - { url = "https://files.pythonhosted.org/packages/cf/cb/7a07b51762dcd59bdbe07aa97f87b3169766cadf240f48d1cbe70a1be9db/wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", size = 83050, upload-time = "2025-01-14T10:35:30.645Z" }, - { url = "https://files.pythonhosted.org/packages/a5/51/a42757dd41032afd6d8037617aa3bc6803ba971850733b24dfb7d5c627c4/wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", size = 74718, upload-time = "2025-01-14T10:35:32.047Z" }, - { url = "https://files.pythonhosted.org/packages/bf/bb/d552bfe47db02fcfc950fc563073a33500f8108efa5f7b41db2f83a59028/wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", size = 82590, upload-time = "2025-01-14T10:35:33.329Z" }, - { url = "https://files.pythonhosted.org/packages/77/99/77b06b3c3c410dbae411105bf22496facf03a5496bfaca8fbcf9da381889/wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", size = 81462, upload-time = "2025-01-14T10:35:34.933Z" }, - { url = "https://files.pythonhosted.org/packages/2d/21/cf0bd85ae66f92600829ea1de8e1da778e5e9f6e574ccbe74b66db0d95db/wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", size = 74309, upload-time = "2025-01-14T10:35:37.542Z" }, - { url = "https://files.pythonhosted.org/packages/6d/16/112d25e9092398a0dd6fec50ab7ac1b775a0c19b428f049785096067ada9/wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", size = 81081, upload-time = "2025-01-14T10:35:38.9Z" }, - { url = "https://files.pythonhosted.org/packages/2b/49/364a615a0cc0872685646c495c7172e4fc7bf1959e3b12a1807a03014e05/wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", size = 36423, upload-time = "2025-01-14T10:35:40.177Z" }, - { url = "https://files.pythonhosted.org/packages/00/ad/5d2c1b34ba3202cd833d9221833e74d6500ce66730974993a8dc9a94fb8c/wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", size = 38772, upload-time = "2025-01-14T10:35:42.763Z" }, - { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594, upload-time = "2025-01-14T10:35:44.018Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d1/1daec934997e8b160040c78d7b31789f19b122110a75eca3d4e8da0049e1/wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", size = 53307 }, + { url = "https://files.pythonhosted.org/packages/1b/7b/13369d42651b809389c1a7153baa01d9700430576c81a2f5c5e460df0ed9/wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", size = 38486 }, + { url = "https://files.pythonhosted.org/packages/62/bf/e0105016f907c30b4bd9e377867c48c34dc9c6c0c104556c9c9126bd89ed/wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", size = 38777 }, + { url = "https://files.pythonhosted.org/packages/27/70/0f6e0679845cbf8b165e027d43402a55494779295c4b08414097b258ac87/wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", size = 83314 }, + { url = "https://files.pythonhosted.org/packages/0f/77/0576d841bf84af8579124a93d216f55d6f74374e4445264cb378a6ed33eb/wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", size = 74947 }, + { url = "https://files.pythonhosted.org/packages/90/ec/00759565518f268ed707dcc40f7eeec38637d46b098a1f5143bff488fe97/wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", size = 82778 }, + { url = "https://files.pythonhosted.org/packages/f8/5a/7cffd26b1c607b0b0c8a9ca9d75757ad7620c9c0a9b4a25d3f8a1480fafc/wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", size = 81716 }, + { url = "https://files.pythonhosted.org/packages/7e/09/dccf68fa98e862df7e6a60a61d43d644b7d095a5fc36dbb591bbd4a1c7b2/wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", size = 74548 }, + { url = "https://files.pythonhosted.org/packages/b7/8e/067021fa3c8814952c5e228d916963c1115b983e21393289de15128e867e/wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", size = 81334 }, + { url = "https://files.pythonhosted.org/packages/4b/0d/9d4b5219ae4393f718699ca1c05f5ebc0c40d076f7e65fd48f5f693294fb/wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", size = 36427 }, + { url = "https://files.pythonhosted.org/packages/72/6a/c5a83e8f61aec1e1aeef939807602fb880e5872371e95df2137142f5c58e/wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", size = 38774 }, + { url = "https://files.pythonhosted.org/packages/cd/f7/a2aab2cbc7a665efab072344a8949a71081eed1d2f451f7f7d2b966594a2/wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58", size = 53308 }, + { url = "https://files.pythonhosted.org/packages/50/ff/149aba8365fdacef52b31a258c4dc1c57c79759c335eff0b3316a2664a64/wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", size = 38488 }, + { url = "https://files.pythonhosted.org/packages/65/46/5a917ce85b5c3b490d35c02bf71aedaa9f2f63f2d15d9949cc4ba56e8ba9/wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", size = 38776 }, + { url = "https://files.pythonhosted.org/packages/ca/74/336c918d2915a4943501c77566db41d1bd6e9f4dbc317f356b9a244dfe83/wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", size = 83776 }, + { url = "https://files.pythonhosted.org/packages/09/99/c0c844a5ccde0fe5761d4305485297f91d67cf2a1a824c5f282e661ec7ff/wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", size = 75420 }, + { url = "https://files.pythonhosted.org/packages/b4/b0/9fc566b0fe08b282c850063591a756057c3247b2362b9286429ec5bf1721/wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", size = 83199 }, + { url = "https://files.pythonhosted.org/packages/9d/4b/71996e62d543b0a0bd95dda485219856def3347e3e9380cc0d6cf10cfb2f/wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", size = 82307 }, + { url = "https://files.pythonhosted.org/packages/39/35/0282c0d8789c0dc9bcc738911776c762a701f95cfe113fb8f0b40e45c2b9/wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", size = 75025 }, + { url = "https://files.pythonhosted.org/packages/4f/6d/90c9fd2c3c6fee181feecb620d95105370198b6b98a0770cba090441a828/wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", size = 81879 }, + { url = "https://files.pythonhosted.org/packages/8f/fa/9fb6e594f2ce03ef03eddbdb5f4f90acb1452221a5351116c7c4708ac865/wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", size = 36419 }, + { url = "https://files.pythonhosted.org/packages/47/f8/fb1773491a253cbc123c5d5dc15c86041f746ed30416535f2a8df1f4a392/wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", size = 38773 }, + { url = "https://files.pythonhosted.org/packages/a1/bd/ab55f849fd1f9a58ed7ea47f5559ff09741b25f00c191231f9f059c83949/wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", size = 53799 }, + { url = "https://files.pythonhosted.org/packages/53/18/75ddc64c3f63988f5a1d7e10fb204ffe5762bc663f8023f18ecaf31a332e/wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", size = 38821 }, + { url = "https://files.pythonhosted.org/packages/48/2a/97928387d6ed1c1ebbfd4efc4133a0633546bec8481a2dd5ec961313a1c7/wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", size = 38919 }, + { url = "https://files.pythonhosted.org/packages/73/54/3bfe5a1febbbccb7a2f77de47b989c0b85ed3a6a41614b104204a788c20e/wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", size = 88721 }, + { url = "https://files.pythonhosted.org/packages/25/cb/7262bc1b0300b4b64af50c2720ef958c2c1917525238d661c3e9a2b71b7b/wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", size = 80899 }, + { url = "https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", size = 89222 }, + { url = "https://files.pythonhosted.org/packages/09/28/2e45a4f4771fcfb109e244d5dbe54259e970362a311b67a965555ba65026/wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", size = 86707 }, + { url = "https://files.pythonhosted.org/packages/c6/d2/dcb56bf5f32fcd4bd9aacc77b50a539abdd5b6536872413fd3f428b21bed/wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", size = 79685 }, + { url = "https://files.pythonhosted.org/packages/80/4e/eb8b353e36711347893f502ce91c770b0b0929f8f0bed2670a6856e667a9/wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", size = 87567 }, + { url = "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", size = 36672 }, + { url = "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", size = 38865 }, + { url = "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", size = 53800 }, + { url = "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", size = 38824 }, + { url = "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", size = 38920 }, + { url = "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", size = 88690 }, + { url = "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", size = 80861 }, + { url = "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", size = 89174 }, + { url = "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", size = 86721 }, + { url = "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", size = 79763 }, + { url = "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", size = 87585 }, + { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676 }, + { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871 }, + { url = "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", size = 56312 }, + { url = "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", size = 40062 }, + { url = "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", size = 40155 }, + { url = "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", size = 113471 }, + { url = "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", size = 101208 }, + { url = "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", size = 109339 }, + { url = "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", size = 110232 }, + { url = "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", size = 100476 }, + { url = "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", size = 106377 }, + { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986 }, + { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750 }, + { url = "https://files.pythonhosted.org/packages/8a/f4/6ed2b8f6f1c832933283974839b88ec7c983fd12905e01e97889dadf7559/wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", size = 53308 }, + { url = "https://files.pythonhosted.org/packages/a2/a9/712a53f8f4f4545768ac532619f6e56d5d0364a87b2212531685e89aeef8/wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", size = 38489 }, + { url = "https://files.pythonhosted.org/packages/fa/9b/e172c8f28a489a2888df18f953e2f6cb8d33b1a2e78c9dfc52d8bf6a5ead/wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82", size = 38776 }, + { url = "https://files.pythonhosted.org/packages/cf/cb/7a07b51762dcd59bdbe07aa97f87b3169766cadf240f48d1cbe70a1be9db/wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", size = 83050 }, + { url = "https://files.pythonhosted.org/packages/a5/51/a42757dd41032afd6d8037617aa3bc6803ba971850733b24dfb7d5c627c4/wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", size = 74718 }, + { url = "https://files.pythonhosted.org/packages/bf/bb/d552bfe47db02fcfc950fc563073a33500f8108efa5f7b41db2f83a59028/wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", size = 82590 }, + { url = "https://files.pythonhosted.org/packages/77/99/77b06b3c3c410dbae411105bf22496facf03a5496bfaca8fbcf9da381889/wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", size = 81462 }, + { url = "https://files.pythonhosted.org/packages/2d/21/cf0bd85ae66f92600829ea1de8e1da778e5e9f6e574ccbe74b66db0d95db/wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", size = 74309 }, + { url = "https://files.pythonhosted.org/packages/6d/16/112d25e9092398a0dd6fec50ab7ac1b775a0c19b428f049785096067ada9/wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", size = 81081 }, + { url = "https://files.pythonhosted.org/packages/2b/49/364a615a0cc0872685646c495c7172e4fc7bf1959e3b12a1807a03014e05/wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", size = 36423 }, + { url = "https://files.pythonhosted.org/packages/00/ad/5d2c1b34ba3202cd833d9221833e74d6500ce66730974993a8dc9a94fb8c/wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", size = 38772 }, + { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594 }, ] [[package]] @@ -1522,120 +1533,120 @@ dependencies = [ { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/51/c0edba5219027f6eab262e139f73e2417b0f4efffa23bf562f6e18f76ca5/yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307", size = 185258, upload-time = "2025-04-17T00:45:14.661Z" } +sdist = { url = "https://files.pythonhosted.org/packages/62/51/c0edba5219027f6eab262e139f73e2417b0f4efffa23bf562f6e18f76ca5/yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307", size = 185258 } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/ab/66082639f99d7ef647a86b2ff4ca20f8ae13bd68a6237e6e166b8eb92edf/yarl-1.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1f6670b9ae3daedb325fa55fbe31c22c8228f6e0b513772c2e1c623caa6ab22", size = 145054, upload-time = "2025-04-17T00:41:27.071Z" }, - { url = "https://files.pythonhosted.org/packages/3d/c2/4e78185c453c3ca02bd11c7907394d0410d26215f9e4b7378648b3522a30/yarl-1.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85a231fa250dfa3308f3c7896cc007a47bc76e9e8e8595c20b7426cac4884c62", size = 96811, upload-time = "2025-04-17T00:41:30.235Z" }, - { url = "https://files.pythonhosted.org/packages/c7/45/91e31dccdcf5b7232dcace78bd51a1bb2d7b4b96c65eece0078b620587d1/yarl-1.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a06701b647c9939d7019acdfa7ebbfbb78ba6aa05985bb195ad716ea759a569", size = 94566, upload-time = "2025-04-17T00:41:32.023Z" }, - { url = "https://files.pythonhosted.org/packages/c8/21/e0aa650bcee881fb804331faa2c0f9a5d6be7609970b2b6e3cdd414e174b/yarl-1.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7595498d085becc8fb9203aa314b136ab0516c7abd97e7d74f7bb4eb95042abe", size = 327297, upload-time = "2025-04-17T00:41:34.03Z" }, - { url = "https://files.pythonhosted.org/packages/1a/a4/58f10870f5c17595c5a37da4c6a0b321589b7d7976e10570088d445d0f47/yarl-1.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af5607159085dcdb055d5678fc2d34949bd75ae6ea6b4381e784bbab1c3aa195", size = 323578, upload-time = "2025-04-17T00:41:36.492Z" }, - { url = "https://files.pythonhosted.org/packages/07/df/2506b1382cc0c4bb0d22a535dc3e7ccd53da9a59b411079013a7904ac35c/yarl-1.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95b50910e496567434cb77a577493c26bce0f31c8a305135f3bda6a2483b8e10", size = 343212, upload-time = "2025-04-17T00:41:38.396Z" }, - { url = "https://files.pythonhosted.org/packages/ba/4a/d1c901d0e2158ad06bb0b9a92473e32d992f98673b93c8a06293e091bab0/yarl-1.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b594113a301ad537766b4e16a5a6750fcbb1497dcc1bc8a4daae889e6402a634", size = 337956, upload-time = "2025-04-17T00:41:40.519Z" }, - { url = "https://files.pythonhosted.org/packages/8b/fd/10fcf7d86f49b1a11096d6846257485ef32e3d3d322e8a7fdea5b127880c/yarl-1.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:083ce0393ea173cd37834eb84df15b6853b555d20c52703e21fbababa8c129d2", size = 333889, upload-time = "2025-04-17T00:41:42.437Z" }, - { url = "https://files.pythonhosted.org/packages/e2/cd/bae926a25154ba31c5fd15f2aa6e50a545c840e08d85e2e2e0807197946b/yarl-1.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1a350a652bbbe12f666109fbddfdf049b3ff43696d18c9ab1531fbba1c977a", size = 322282, upload-time = "2025-04-17T00:41:44.641Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c6/c3ac3597dfde746c63c637c5422cf3954ebf622a8de7f09892d20a68900d/yarl-1.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fb0caeac4a164aadce342f1597297ec0ce261ec4532bbc5a9ca8da5622f53867", size = 336270, upload-time = "2025-04-17T00:41:46.812Z" }, - { url = "https://files.pythonhosted.org/packages/dd/42/417fd7b8da5846def29712370ea8916a4be2553de42a2c969815153717be/yarl-1.20.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d88cc43e923f324203f6ec14434fa33b85c06d18d59c167a0637164863b8e995", size = 335500, upload-time = "2025-04-17T00:41:48.896Z" }, - { url = "https://files.pythonhosted.org/packages/37/aa/c2339683f8f05f4be16831b6ad58d04406cf1c7730e48a12f755da9f5ac5/yarl-1.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e52d6ed9ea8fd3abf4031325dc714aed5afcbfa19ee4a89898d663c9976eb487", size = 339672, upload-time = "2025-04-17T00:41:50.965Z" }, - { url = "https://files.pythonhosted.org/packages/be/12/ab6c4df95f00d7bc9502bf07a92d5354f11d9d3cb855222a6a8d2bd6e8da/yarl-1.20.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce360ae48a5e9961d0c730cf891d40698a82804e85f6e74658fb175207a77cb2", size = 351840, upload-time = "2025-04-17T00:41:53.074Z" }, - { url = "https://files.pythonhosted.org/packages/83/3c/08d58c51bbd3899be3e7e83cd7a691fdcf3b9f78b8699d663ecc2c090ab7/yarl-1.20.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:06d06c9d5b5bc3eb56542ceeba6658d31f54cf401e8468512447834856fb0e61", size = 359550, upload-time = "2025-04-17T00:41:55.517Z" }, - { url = "https://files.pythonhosted.org/packages/8a/15/de7906c506f85fb476f0edac4bd74569f49e5ffdcf98e246a0313bf593b9/yarl-1.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c27d98f4e5c4060582f44e58309c1e55134880558f1add7a87c1bc36ecfade19", size = 351108, upload-time = "2025-04-17T00:41:57.582Z" }, - { url = "https://files.pythonhosted.org/packages/25/04/c6754f5ae2cdf057ac094ac01137c17875b629b1c29ed75354626a755375/yarl-1.20.0-cp310-cp310-win32.whl", hash = "sha256:f4d3fa9b9f013f7050326e165c3279e22850d02ae544ace285674cb6174b5d6d", size = 86733, upload-time = "2025-04-17T00:41:59.757Z" }, - { url = "https://files.pythonhosted.org/packages/db/1f/5c1952f3d983ac3f5fb079b5b13b62728f8a73fd27d03e1cef7e476addff/yarl-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc906b636239631d42eb8a07df8359905da02704a868983265603887ed68c076", size = 92916, upload-time = "2025-04-17T00:42:02.177Z" }, - { url = "https://files.pythonhosted.org/packages/60/82/a59d8e21b20ffc836775fa7daedac51d16bb8f3010c4fcb495c4496aa922/yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3", size = 145178, upload-time = "2025-04-17T00:42:04.511Z" }, - { url = "https://files.pythonhosted.org/packages/ba/81/315a3f6f95947cfbf37c92d6fbce42a1a6207b6c38e8c2b452499ec7d449/yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a", size = 96859, upload-time = "2025-04-17T00:42:06.43Z" }, - { url = "https://files.pythonhosted.org/packages/ad/17/9b64e575583158551b72272a1023cdbd65af54fe13421d856b2850a6ddb7/yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2", size = 94647, upload-time = "2025-04-17T00:42:07.976Z" }, - { url = "https://files.pythonhosted.org/packages/2c/29/8f291e7922a58a21349683f6120a85701aeefaa02e9f7c8a2dc24fe3f431/yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e", size = 355788, upload-time = "2025-04-17T00:42:09.902Z" }, - { url = "https://files.pythonhosted.org/packages/26/6d/b4892c80b805c42c228c6d11e03cafabf81662d371b0853e7f0f513837d5/yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9", size = 344613, upload-time = "2025-04-17T00:42:11.768Z" }, - { url = "https://files.pythonhosted.org/packages/d7/0e/517aa28d3f848589bae9593717b063a544b86ba0a807d943c70f48fcf3bb/yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a", size = 370953, upload-time = "2025-04-17T00:42:13.983Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9b/5bd09d2f1ad6e6f7c2beae9e50db78edd2cca4d194d227b958955573e240/yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2", size = 369204, upload-time = "2025-04-17T00:42:16.386Z" }, - { url = "https://files.pythonhosted.org/packages/9c/85/d793a703cf4bd0d4cd04e4b13cc3d44149470f790230430331a0c1f52df5/yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2", size = 358108, upload-time = "2025-04-17T00:42:18.622Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/b6c71e13549c1f6048fbc14ce8d930ac5fb8bafe4f1a252e621a24f3f1f9/yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8", size = 346610, upload-time = "2025-04-17T00:42:20.9Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1a/d6087d58bdd0d8a2a37bbcdffac9d9721af6ebe50d85304d9f9b57dfd862/yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902", size = 365378, upload-time = "2025-04-17T00:42:22.926Z" }, - { url = "https://files.pythonhosted.org/packages/02/84/e25ddff4cbc001dbc4af76f8d41a3e23818212dd1f0a52044cbc60568872/yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791", size = 356919, upload-time = "2025-04-17T00:42:25.145Z" }, - { url = "https://files.pythonhosted.org/packages/04/76/898ae362353bf8f64636495d222c8014c8e5267df39b1a9fe1e1572fb7d0/yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f", size = 364248, upload-time = "2025-04-17T00:42:27.475Z" }, - { url = "https://files.pythonhosted.org/packages/1b/b0/9d9198d83a622f1c40fdbf7bd13b224a6979f2e1fc2cf50bfb1d8773c495/yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da", size = 378418, upload-time = "2025-04-17T00:42:29.333Z" }, - { url = "https://files.pythonhosted.org/packages/c7/ce/1f50c1cc594cf5d3f5bf4a9b616fca68680deaec8ad349d928445ac52eb8/yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4", size = 383850, upload-time = "2025-04-17T00:42:31.668Z" }, - { url = "https://files.pythonhosted.org/packages/89/1e/a59253a87b35bfec1a25bb5801fb69943330b67cfd266278eb07e0609012/yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5", size = 381218, upload-time = "2025-04-17T00:42:33.523Z" }, - { url = "https://files.pythonhosted.org/packages/85/b0/26f87df2b3044b0ef1a7cf66d321102bdca091db64c5ae853fcb2171c031/yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6", size = 86606, upload-time = "2025-04-17T00:42:35.873Z" }, - { url = "https://files.pythonhosted.org/packages/33/46/ca335c2e1f90446a77640a45eeb1cd8f6934f2c6e4df7db0f0f36ef9f025/yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb", size = 93374, upload-time = "2025-04-17T00:42:37.586Z" }, - { url = "https://files.pythonhosted.org/packages/c3/e8/3efdcb83073df978bb5b1a9cc0360ce596680e6c3fac01f2a994ccbb8939/yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f", size = 147089, upload-time = "2025-04-17T00:42:39.602Z" }, - { url = "https://files.pythonhosted.org/packages/60/c3/9e776e98ea350f76f94dd80b408eaa54e5092643dbf65fd9babcffb60509/yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e", size = 97706, upload-time = "2025-04-17T00:42:41.469Z" }, - { url = "https://files.pythonhosted.org/packages/0c/5b/45cdfb64a3b855ce074ae607b9fc40bc82e7613b94e7612b030255c93a09/yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e", size = 95719, upload-time = "2025-04-17T00:42:43.666Z" }, - { url = "https://files.pythonhosted.org/packages/2d/4e/929633b249611eeed04e2f861a14ed001acca3ef9ec2a984a757b1515889/yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33", size = 343972, upload-time = "2025-04-17T00:42:45.391Z" }, - { url = "https://files.pythonhosted.org/packages/49/fd/047535d326c913f1a90407a3baf7ff535b10098611eaef2c527e32e81ca1/yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58", size = 339639, upload-time = "2025-04-17T00:42:47.552Z" }, - { url = "https://files.pythonhosted.org/packages/48/2f/11566f1176a78f4bafb0937c0072410b1b0d3640b297944a6a7a556e1d0b/yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f", size = 353745, upload-time = "2025-04-17T00:42:49.406Z" }, - { url = "https://files.pythonhosted.org/packages/26/17/07dfcf034d6ae8837b33988be66045dd52f878dfb1c4e8f80a7343f677be/yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae", size = 354178, upload-time = "2025-04-17T00:42:51.588Z" }, - { url = "https://files.pythonhosted.org/packages/15/45/212604d3142d84b4065d5f8cab6582ed3d78e4cc250568ef2a36fe1cf0a5/yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018", size = 349219, upload-time = "2025-04-17T00:42:53.674Z" }, - { url = "https://files.pythonhosted.org/packages/e6/e0/a10b30f294111c5f1c682461e9459935c17d467a760c21e1f7db400ff499/yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672", size = 337266, upload-time = "2025-04-17T00:42:55.49Z" }, - { url = "https://files.pythonhosted.org/packages/33/a6/6efa1d85a675d25a46a167f9f3e80104cde317dfdf7f53f112ae6b16a60a/yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8", size = 360873, upload-time = "2025-04-17T00:42:57.895Z" }, - { url = "https://files.pythonhosted.org/packages/77/67/c8ab718cb98dfa2ae9ba0f97bf3cbb7d45d37f13fe1fbad25ac92940954e/yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7", size = 360524, upload-time = "2025-04-17T00:43:00.094Z" }, - { url = "https://files.pythonhosted.org/packages/bd/e8/c3f18660cea1bc73d9f8a2b3ef423def8dadbbae6c4afabdb920b73e0ead/yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594", size = 365370, upload-time = "2025-04-17T00:43:02.242Z" }, - { url = "https://files.pythonhosted.org/packages/c9/99/33f3b97b065e62ff2d52817155a89cfa030a1a9b43fee7843ef560ad9603/yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6", size = 373297, upload-time = "2025-04-17T00:43:04.189Z" }, - { url = "https://files.pythonhosted.org/packages/3d/89/7519e79e264a5f08653d2446b26d4724b01198a93a74d2e259291d538ab1/yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1", size = 378771, upload-time = "2025-04-17T00:43:06.609Z" }, - { url = "https://files.pythonhosted.org/packages/3a/58/6c460bbb884abd2917c3eef6f663a4a873f8dc6f498561fc0ad92231c113/yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b", size = 375000, upload-time = "2025-04-17T00:43:09.01Z" }, - { url = "https://files.pythonhosted.org/packages/3b/2a/dd7ed1aa23fea996834278d7ff178f215b24324ee527df53d45e34d21d28/yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64", size = 86355, upload-time = "2025-04-17T00:43:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/ca/c6/333fe0338305c0ac1c16d5aa7cc4841208d3252bbe62172e0051006b5445/yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c", size = 92904, upload-time = "2025-04-17T00:43:13.087Z" }, - { url = "https://files.pythonhosted.org/packages/0f/6f/514c9bff2900c22a4f10e06297714dbaf98707143b37ff0bcba65a956221/yarl-1.20.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2137810a20b933b1b1b7e5cf06a64c3ed3b4747b0e5d79c9447c00db0e2f752f", size = 145030, upload-time = "2025-04-17T00:43:15.083Z" }, - { url = "https://files.pythonhosted.org/packages/4e/9d/f88da3fa319b8c9c813389bfb3463e8d777c62654c7168e580a13fadff05/yarl-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:447c5eadd750db8389804030d15f43d30435ed47af1313303ed82a62388176d3", size = 96894, upload-time = "2025-04-17T00:43:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/cd/57/92e83538580a6968b2451d6c89c5579938a7309d4785748e8ad42ddafdce/yarl-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42fbe577272c203528d402eec8bf4b2d14fd49ecfec92272334270b850e9cd7d", size = 94457, upload-time = "2025-04-17T00:43:19.431Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ee/7ee43bd4cf82dddd5da97fcaddb6fa541ab81f3ed564c42f146c83ae17ce/yarl-1.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e321617de4ab170226cd15006a565d0fa0d908f11f724a2c9142d6b2812ab0", size = 343070, upload-time = "2025-04-17T00:43:21.426Z" }, - { url = "https://files.pythonhosted.org/packages/4a/12/b5eccd1109e2097bcc494ba7dc5de156e41cf8309fab437ebb7c2b296ce3/yarl-1.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4345f58719825bba29895011e8e3b545e6e00257abb984f9f27fe923afca2501", size = 337739, upload-time = "2025-04-17T00:43:23.634Z" }, - { url = "https://files.pythonhosted.org/packages/7d/6b/0eade8e49af9fc2585552f63c76fa59ef469c724cc05b29519b19aa3a6d5/yarl-1.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d9b980d7234614bc4674468ab173ed77d678349c860c3af83b1fffb6a837ddc", size = 351338, upload-time = "2025-04-17T00:43:25.695Z" }, - { url = "https://files.pythonhosted.org/packages/45/cb/aaaa75d30087b5183c7b8a07b4fb16ae0682dd149a1719b3a28f54061754/yarl-1.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af4baa8a445977831cbaa91a9a84cc09debb10bc8391f128da2f7bd070fc351d", size = 353636, upload-time = "2025-04-17T00:43:27.876Z" }, - { url = "https://files.pythonhosted.org/packages/98/9d/d9cb39ec68a91ba6e66fa86d97003f58570327d6713833edf7ad6ce9dde5/yarl-1.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123393db7420e71d6ce40d24885a9e65eb1edefc7a5228db2d62bcab3386a5c0", size = 348061, upload-time = "2025-04-17T00:43:29.788Z" }, - { url = "https://files.pythonhosted.org/packages/72/6b/103940aae893d0cc770b4c36ce80e2ed86fcb863d48ea80a752b8bda9303/yarl-1.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab47acc9332f3de1b39e9b702d9c916af7f02656b2a86a474d9db4e53ef8fd7a", size = 334150, upload-time = "2025-04-17T00:43:31.742Z" }, - { url = "https://files.pythonhosted.org/packages/ef/b2/986bd82aa222c3e6b211a69c9081ba46484cffa9fab2a5235e8d18ca7a27/yarl-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4a34c52ed158f89876cba9c600b2c964dfc1ca52ba7b3ab6deb722d1d8be6df2", size = 362207, upload-time = "2025-04-17T00:43:34.099Z" }, - { url = "https://files.pythonhosted.org/packages/14/7c/63f5922437b873795d9422cbe7eb2509d4b540c37ae5548a4bb68fd2c546/yarl-1.20.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:04d8cfb12714158abf2618f792c77bc5c3d8c5f37353e79509608be4f18705c9", size = 361277, upload-time = "2025-04-17T00:43:36.202Z" }, - { url = "https://files.pythonhosted.org/packages/81/83/450938cccf732466953406570bdb42c62b5ffb0ac7ac75a1f267773ab5c8/yarl-1.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7dc63ad0d541c38b6ae2255aaa794434293964677d5c1ec5d0116b0e308031f5", size = 364990, upload-time = "2025-04-17T00:43:38.551Z" }, - { url = "https://files.pythonhosted.org/packages/b4/de/af47d3a47e4a833693b9ec8e87debb20f09d9fdc9139b207b09a3e6cbd5a/yarl-1.20.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d02b591a64e4e6ca18c5e3d925f11b559c763b950184a64cf47d74d7e41877", size = 374684, upload-time = "2025-04-17T00:43:40.481Z" }, - { url = "https://files.pythonhosted.org/packages/62/0b/078bcc2d539f1faffdc7d32cb29a2d7caa65f1a6f7e40795d8485db21851/yarl-1.20.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95fc9876f917cac7f757df80a5dda9de59d423568460fe75d128c813b9af558e", size = 382599, upload-time = "2025-04-17T00:43:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/74/a9/4fdb1a7899f1fb47fd1371e7ba9e94bff73439ce87099d5dd26d285fffe0/yarl-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb769ae5760cd1c6a712135ee7915f9d43f11d9ef769cb3f75a23e398a92d384", size = 378573, upload-time = "2025-04-17T00:43:44.797Z" }, - { url = "https://files.pythonhosted.org/packages/fd/be/29f5156b7a319e4d2e5b51ce622b4dfb3aa8d8204cd2a8a339340fbfad40/yarl-1.20.0-cp313-cp313-win32.whl", hash = "sha256:70e0c580a0292c7414a1cead1e076c9786f685c1fc4757573d2967689b370e62", size = 86051, upload-time = "2025-04-17T00:43:47.076Z" }, - { url = "https://files.pythonhosted.org/packages/52/56/05fa52c32c301da77ec0b5f63d2d9605946fe29defacb2a7ebd473c23b81/yarl-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:4c43030e4b0af775a85be1fa0433119b1565673266a70bf87ef68a9d5ba3174c", size = 92742, upload-time = "2025-04-17T00:43:49.193Z" }, - { url = "https://files.pythonhosted.org/packages/d4/2f/422546794196519152fc2e2f475f0e1d4d094a11995c81a465faf5673ffd/yarl-1.20.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b6c4c3d0d6a0ae9b281e492b1465c72de433b782e6b5001c8e7249e085b69051", size = 163575, upload-time = "2025-04-17T00:43:51.533Z" }, - { url = "https://files.pythonhosted.org/packages/90/fc/67c64ddab6c0b4a169d03c637fb2d2a212b536e1989dec8e7e2c92211b7f/yarl-1.20.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8681700f4e4df891eafa4f69a439a6e7d480d64e52bf460918f58e443bd3da7d", size = 106121, upload-time = "2025-04-17T00:43:53.506Z" }, - { url = "https://files.pythonhosted.org/packages/6d/00/29366b9eba7b6f6baed7d749f12add209b987c4cfbfa418404dbadc0f97c/yarl-1.20.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:84aeb556cb06c00652dbf87c17838eb6d92cfd317799a8092cee0e570ee11229", size = 103815, upload-time = "2025-04-17T00:43:55.41Z" }, - { url = "https://files.pythonhosted.org/packages/28/f4/a2a4c967c8323c03689383dff73396281ced3b35d0ed140580825c826af7/yarl-1.20.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f166eafa78810ddb383e930d62e623d288fb04ec566d1b4790099ae0f31485f1", size = 408231, upload-time = "2025-04-17T00:43:57.825Z" }, - { url = "https://files.pythonhosted.org/packages/0f/a1/66f7ffc0915877d726b70cc7a896ac30b6ac5d1d2760613603b022173635/yarl-1.20.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5d3d6d14754aefc7a458261027a562f024d4f6b8a798adb472277f675857b1eb", size = 390221, upload-time = "2025-04-17T00:44:00.526Z" }, - { url = "https://files.pythonhosted.org/packages/41/15/cc248f0504610283271615e85bf38bc014224122498c2016d13a3a1b8426/yarl-1.20.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a8f64df8ed5d04c51260dbae3cc82e5649834eebea9eadfd829837b8093eb00", size = 411400, upload-time = "2025-04-17T00:44:02.853Z" }, - { url = "https://files.pythonhosted.org/packages/5c/af/f0823d7e092bfb97d24fce6c7269d67fcd1aefade97d0a8189c4452e4d5e/yarl-1.20.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d9949eaf05b4d30e93e4034a7790634bbb41b8be2d07edd26754f2e38e491de", size = 411714, upload-time = "2025-04-17T00:44:04.904Z" }, - { url = "https://files.pythonhosted.org/packages/83/70/be418329eae64b9f1b20ecdaac75d53aef098797d4c2299d82ae6f8e4663/yarl-1.20.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c366b254082d21cc4f08f522ac201d0d83a8b8447ab562732931d31d80eb2a5", size = 404279, upload-time = "2025-04-17T00:44:07.721Z" }, - { url = "https://files.pythonhosted.org/packages/19/f5/52e02f0075f65b4914eb890eea1ba97e6fd91dd821cc33a623aa707b2f67/yarl-1.20.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91bc450c80a2e9685b10e34e41aef3d44ddf99b3a498717938926d05ca493f6a", size = 384044, upload-time = "2025-04-17T00:44:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/6a/36/b0fa25226b03d3f769c68d46170b3e92b00ab3853d73127273ba22474697/yarl-1.20.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c2aa4387de4bc3a5fe158080757748d16567119bef215bec643716b4fbf53f9", size = 416236, upload-time = "2025-04-17T00:44:11.734Z" }, - { url = "https://files.pythonhosted.org/packages/cb/3a/54c828dd35f6831dfdd5a79e6c6b4302ae2c5feca24232a83cb75132b205/yarl-1.20.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d2cbca6760a541189cf87ee54ff891e1d9ea6406079c66341008f7ef6ab61145", size = 402034, upload-time = "2025-04-17T00:44:13.975Z" }, - { url = "https://files.pythonhosted.org/packages/10/97/c7bf5fba488f7e049f9ad69c1b8fdfe3daa2e8916b3d321aa049e361a55a/yarl-1.20.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:798a5074e656f06b9fad1a162be5a32da45237ce19d07884d0b67a0aa9d5fdda", size = 407943, upload-time = "2025-04-17T00:44:16.052Z" }, - { url = "https://files.pythonhosted.org/packages/fd/a4/022d2555c1e8fcff08ad7f0f43e4df3aba34f135bff04dd35d5526ce54ab/yarl-1.20.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f106e75c454288472dbe615accef8248c686958c2e7dd3b8d8ee2669770d020f", size = 423058, upload-time = "2025-04-17T00:44:18.547Z" }, - { url = "https://files.pythonhosted.org/packages/4c/f6/0873a05563e5df29ccf35345a6ae0ac9e66588b41fdb7043a65848f03139/yarl-1.20.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3b60a86551669c23dc5445010534d2c5d8a4e012163218fc9114e857c0586fdd", size = 423792, upload-time = "2025-04-17T00:44:20.639Z" }, - { url = "https://files.pythonhosted.org/packages/9e/35/43fbbd082708fa42e923f314c24f8277a28483d219e049552e5007a9aaca/yarl-1.20.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e429857e341d5e8e15806118e0294f8073ba9c4580637e59ab7b238afca836f", size = 422242, upload-time = "2025-04-17T00:44:22.851Z" }, - { url = "https://files.pythonhosted.org/packages/ed/f7/f0f2500cf0c469beb2050b522c7815c575811627e6d3eb9ec7550ddd0bfe/yarl-1.20.0-cp313-cp313t-win32.whl", hash = "sha256:65a4053580fe88a63e8e4056b427224cd01edfb5f951498bfefca4052f0ce0ac", size = 93816, upload-time = "2025-04-17T00:44:25.491Z" }, - { url = "https://files.pythonhosted.org/packages/3f/93/f73b61353b2a699d489e782c3f5998b59f974ec3156a2050a52dfd7e8946/yarl-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:53b2da3a6ca0a541c1ae799c349788d480e5144cac47dba0266c7cb6c76151fe", size = 101093, upload-time = "2025-04-17T00:44:27.418Z" }, - { url = "https://files.pythonhosted.org/packages/bc/95/3d22e1d2fa6dce3670d820a859f4fc5526400c58019650d2da4e19b9924d/yarl-1.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:119bca25e63a7725b0c9d20ac67ca6d98fa40e5a894bd5d4686010ff73397914", size = 146680, upload-time = "2025-04-17T00:44:29.739Z" }, - { url = "https://files.pythonhosted.org/packages/12/43/37f2d17e0b82d4f01b2da1fe53a19ff95be6d7d9902cad11d3ebbef5bc9d/yarl-1.20.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:35d20fb919546995f1d8c9e41f485febd266f60e55383090010f272aca93edcc", size = 97707, upload-time = "2025-04-17T00:44:32.288Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3e/665501121ba7c712a0f1b58d8ee01d7633096671fbeec4cf3dc4e4357a95/yarl-1.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:484e7a08f72683c0f160270566b4395ea5412b4359772b98659921411d32ad26", size = 95385, upload-time = "2025-04-17T00:44:34.472Z" }, - { url = "https://files.pythonhosted.org/packages/bf/8d/48edf4d49ca38e5229faf793276bdd6f01704740dcf519cf1d282acac6c6/yarl-1.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d8a3d54a090e0fff5837cd3cc305dd8a07d3435a088ddb1f65e33b322f66a94", size = 332687, upload-time = "2025-04-17T00:44:36.855Z" }, - { url = "https://files.pythonhosted.org/packages/e0/c1/112c516bead873c83abe30e08143714d702d1fffdfed43dc103312b81666/yarl-1.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f0cf05ae2d3d87a8c9022f3885ac6dea2b751aefd66a4f200e408a61ae9b7f0d", size = 325390, upload-time = "2025-04-17T00:44:38.956Z" }, - { url = "https://files.pythonhosted.org/packages/0b/4c/07aef11f7f23a41049eb0b3b357ceb32bd9798f62042858e0168be9f6f49/yarl-1.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a884b8974729e3899d9287df46f015ce53f7282d8d3340fa0ed57536b440621c", size = 348497, upload-time = "2025-04-17T00:44:42.453Z" }, - { url = "https://files.pythonhosted.org/packages/56/d9/00d5525a2c5e5c66967eaa03866bef6317da4b129ae016582c6641826974/yarl-1.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8d8aa8dd89ffb9a831fedbcb27d00ffd9f4842107d52dc9d57e64cb34073d5c", size = 343670, upload-time = "2025-04-17T00:44:44.822Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7c/2fc733090c6fce82ea5c50f431e70f5dff196d7b54da93b9d6e801031dd2/yarl-1.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4e88d6c3c8672f45a30867817e4537df1bbc6f882a91581faf1f6d9f0f1b5a", size = 335738, upload-time = "2025-04-17T00:44:47.352Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ce/6b22de535b7bc7b19f3cf23c4e744cd2368fa11a0c8f218dfd2ef46b6c3a/yarl-1.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdb77efde644d6f1ad27be8a5d67c10b7f769804fff7a966ccb1da5a4de4b656", size = 328203, upload-time = "2025-04-17T00:44:49.728Z" }, - { url = "https://files.pythonhosted.org/packages/6b/c8/3fc10db34e731a426baaff348aa1b2c0eb9cb93ff723af4e930e767c058e/yarl-1.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4ba5e59f14bfe8d261a654278a0f6364feef64a794bd456a8c9e823071e5061c", size = 341922, upload-time = "2025-04-17T00:44:52.233Z" }, - { url = "https://files.pythonhosted.org/packages/37/59/f607a63c24b31c66cf288cb819d8dbcac2bd9ec90f39bd03986f33a866b3/yarl-1.20.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d0bf955b96ea44ad914bc792c26a0edcd71b4668b93cbcd60f5b0aeaaed06c64", size = 338163, upload-time = "2025-04-17T00:44:54.511Z" }, - { url = "https://files.pythonhosted.org/packages/01/b2/5fd461fe8ab3bb788e19ef6c35a3453f44a5c0d6973f847a08060c4d6183/yarl-1.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:27359776bc359ee6eaefe40cb19060238f31228799e43ebd3884e9c589e63b20", size = 343096, upload-time = "2025-04-17T00:44:56.789Z" }, - { url = "https://files.pythonhosted.org/packages/71/d3/7102efd34ed22e6839361f30a27bdad341c0a01f66fcbf09822a1d90b853/yarl-1.20.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:04d9c7a1dc0a26efb33e1acb56c8849bd57a693b85f44774356c92d610369efa", size = 358520, upload-time = "2025-04-17T00:44:58.974Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ab/754b60a5c8be8abaa746543555612b2205ba60c194fc3a0547a34e0b6a53/yarl-1.20.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:faa709b66ae0e24c8e5134033187a972d849d87ed0a12a0366bedcc6b5dc14a5", size = 359635, upload-time = "2025-04-17T00:45:01.457Z" }, - { url = "https://files.pythonhosted.org/packages/e0/d5/369f994369a7233fcd81f642553062d4f6c657a93069b58258b9046bb87d/yarl-1.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:44869ee8538208fe5d9342ed62c11cc6a7a1af1b3d0bb79bb795101b6e77f6e0", size = 353906, upload-time = "2025-04-17T00:45:04.217Z" }, - { url = "https://files.pythonhosted.org/packages/1b/59/c7f929d7cd7c1f0c918c38aca06d07cac2e4f3577a95fe3a836b3079a3ca/yarl-1.20.0-cp39-cp39-win32.whl", hash = "sha256:b7fa0cb9fd27ffb1211cde944b41f5c67ab1c13a13ebafe470b1e206b8459da8", size = 87243, upload-time = "2025-04-17T00:45:06.961Z" }, - { url = "https://files.pythonhosted.org/packages/1c/bc/80f16fc58cb3b61b15450eaf6c874d9c984c96453d9024b9d0aa4655dac9/yarl-1.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:d4fad6e5189c847820288286732075f213eabf81be4d08d6cc309912e62be5b7", size = 93457, upload-time = "2025-04-17T00:45:09.651Z" }, - { url = "https://files.pythonhosted.org/packages/ea/1f/70c57b3d7278e94ed22d85e09685d3f0a38ebdd8c5c73b65ba4c0d0fe002/yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124", size = 46124, upload-time = "2025-04-17T00:45:12.199Z" }, + { url = "https://files.pythonhosted.org/packages/00/ab/66082639f99d7ef647a86b2ff4ca20f8ae13bd68a6237e6e166b8eb92edf/yarl-1.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1f6670b9ae3daedb325fa55fbe31c22c8228f6e0b513772c2e1c623caa6ab22", size = 145054 }, + { url = "https://files.pythonhosted.org/packages/3d/c2/4e78185c453c3ca02bd11c7907394d0410d26215f9e4b7378648b3522a30/yarl-1.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85a231fa250dfa3308f3c7896cc007a47bc76e9e8e8595c20b7426cac4884c62", size = 96811 }, + { url = "https://files.pythonhosted.org/packages/c7/45/91e31dccdcf5b7232dcace78bd51a1bb2d7b4b96c65eece0078b620587d1/yarl-1.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a06701b647c9939d7019acdfa7ebbfbb78ba6aa05985bb195ad716ea759a569", size = 94566 }, + { url = "https://files.pythonhosted.org/packages/c8/21/e0aa650bcee881fb804331faa2c0f9a5d6be7609970b2b6e3cdd414e174b/yarl-1.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7595498d085becc8fb9203aa314b136ab0516c7abd97e7d74f7bb4eb95042abe", size = 327297 }, + { url = "https://files.pythonhosted.org/packages/1a/a4/58f10870f5c17595c5a37da4c6a0b321589b7d7976e10570088d445d0f47/yarl-1.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af5607159085dcdb055d5678fc2d34949bd75ae6ea6b4381e784bbab1c3aa195", size = 323578 }, + { url = "https://files.pythonhosted.org/packages/07/df/2506b1382cc0c4bb0d22a535dc3e7ccd53da9a59b411079013a7904ac35c/yarl-1.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95b50910e496567434cb77a577493c26bce0f31c8a305135f3bda6a2483b8e10", size = 343212 }, + { url = "https://files.pythonhosted.org/packages/ba/4a/d1c901d0e2158ad06bb0b9a92473e32d992f98673b93c8a06293e091bab0/yarl-1.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b594113a301ad537766b4e16a5a6750fcbb1497dcc1bc8a4daae889e6402a634", size = 337956 }, + { url = "https://files.pythonhosted.org/packages/8b/fd/10fcf7d86f49b1a11096d6846257485ef32e3d3d322e8a7fdea5b127880c/yarl-1.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:083ce0393ea173cd37834eb84df15b6853b555d20c52703e21fbababa8c129d2", size = 333889 }, + { url = "https://files.pythonhosted.org/packages/e2/cd/bae926a25154ba31c5fd15f2aa6e50a545c840e08d85e2e2e0807197946b/yarl-1.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1a350a652bbbe12f666109fbddfdf049b3ff43696d18c9ab1531fbba1c977a", size = 322282 }, + { url = "https://files.pythonhosted.org/packages/e2/c6/c3ac3597dfde746c63c637c5422cf3954ebf622a8de7f09892d20a68900d/yarl-1.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fb0caeac4a164aadce342f1597297ec0ce261ec4532bbc5a9ca8da5622f53867", size = 336270 }, + { url = "https://files.pythonhosted.org/packages/dd/42/417fd7b8da5846def29712370ea8916a4be2553de42a2c969815153717be/yarl-1.20.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d88cc43e923f324203f6ec14434fa33b85c06d18d59c167a0637164863b8e995", size = 335500 }, + { url = "https://files.pythonhosted.org/packages/37/aa/c2339683f8f05f4be16831b6ad58d04406cf1c7730e48a12f755da9f5ac5/yarl-1.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e52d6ed9ea8fd3abf4031325dc714aed5afcbfa19ee4a89898d663c9976eb487", size = 339672 }, + { url = "https://files.pythonhosted.org/packages/be/12/ab6c4df95f00d7bc9502bf07a92d5354f11d9d3cb855222a6a8d2bd6e8da/yarl-1.20.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce360ae48a5e9961d0c730cf891d40698a82804e85f6e74658fb175207a77cb2", size = 351840 }, + { url = "https://files.pythonhosted.org/packages/83/3c/08d58c51bbd3899be3e7e83cd7a691fdcf3b9f78b8699d663ecc2c090ab7/yarl-1.20.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:06d06c9d5b5bc3eb56542ceeba6658d31f54cf401e8468512447834856fb0e61", size = 359550 }, + { url = "https://files.pythonhosted.org/packages/8a/15/de7906c506f85fb476f0edac4bd74569f49e5ffdcf98e246a0313bf593b9/yarl-1.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c27d98f4e5c4060582f44e58309c1e55134880558f1add7a87c1bc36ecfade19", size = 351108 }, + { url = "https://files.pythonhosted.org/packages/25/04/c6754f5ae2cdf057ac094ac01137c17875b629b1c29ed75354626a755375/yarl-1.20.0-cp310-cp310-win32.whl", hash = "sha256:f4d3fa9b9f013f7050326e165c3279e22850d02ae544ace285674cb6174b5d6d", size = 86733 }, + { url = "https://files.pythonhosted.org/packages/db/1f/5c1952f3d983ac3f5fb079b5b13b62728f8a73fd27d03e1cef7e476addff/yarl-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc906b636239631d42eb8a07df8359905da02704a868983265603887ed68c076", size = 92916 }, + { url = "https://files.pythonhosted.org/packages/60/82/a59d8e21b20ffc836775fa7daedac51d16bb8f3010c4fcb495c4496aa922/yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3", size = 145178 }, + { url = "https://files.pythonhosted.org/packages/ba/81/315a3f6f95947cfbf37c92d6fbce42a1a6207b6c38e8c2b452499ec7d449/yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a", size = 96859 }, + { url = "https://files.pythonhosted.org/packages/ad/17/9b64e575583158551b72272a1023cdbd65af54fe13421d856b2850a6ddb7/yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2", size = 94647 }, + { url = "https://files.pythonhosted.org/packages/2c/29/8f291e7922a58a21349683f6120a85701aeefaa02e9f7c8a2dc24fe3f431/yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e", size = 355788 }, + { url = "https://files.pythonhosted.org/packages/26/6d/b4892c80b805c42c228c6d11e03cafabf81662d371b0853e7f0f513837d5/yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9", size = 344613 }, + { url = "https://files.pythonhosted.org/packages/d7/0e/517aa28d3f848589bae9593717b063a544b86ba0a807d943c70f48fcf3bb/yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a", size = 370953 }, + { url = "https://files.pythonhosted.org/packages/5f/9b/5bd09d2f1ad6e6f7c2beae9e50db78edd2cca4d194d227b958955573e240/yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2", size = 369204 }, + { url = "https://files.pythonhosted.org/packages/9c/85/d793a703cf4bd0d4cd04e4b13cc3d44149470f790230430331a0c1f52df5/yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2", size = 358108 }, + { url = "https://files.pythonhosted.org/packages/6f/54/b6c71e13549c1f6048fbc14ce8d930ac5fb8bafe4f1a252e621a24f3f1f9/yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8", size = 346610 }, + { url = "https://files.pythonhosted.org/packages/a0/1a/d6087d58bdd0d8a2a37bbcdffac9d9721af6ebe50d85304d9f9b57dfd862/yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902", size = 365378 }, + { url = "https://files.pythonhosted.org/packages/02/84/e25ddff4cbc001dbc4af76f8d41a3e23818212dd1f0a52044cbc60568872/yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791", size = 356919 }, + { url = "https://files.pythonhosted.org/packages/04/76/898ae362353bf8f64636495d222c8014c8e5267df39b1a9fe1e1572fb7d0/yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f", size = 364248 }, + { url = "https://files.pythonhosted.org/packages/1b/b0/9d9198d83a622f1c40fdbf7bd13b224a6979f2e1fc2cf50bfb1d8773c495/yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da", size = 378418 }, + { url = "https://files.pythonhosted.org/packages/c7/ce/1f50c1cc594cf5d3f5bf4a9b616fca68680deaec8ad349d928445ac52eb8/yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4", size = 383850 }, + { url = "https://files.pythonhosted.org/packages/89/1e/a59253a87b35bfec1a25bb5801fb69943330b67cfd266278eb07e0609012/yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5", size = 381218 }, + { url = "https://files.pythonhosted.org/packages/85/b0/26f87df2b3044b0ef1a7cf66d321102bdca091db64c5ae853fcb2171c031/yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6", size = 86606 }, + { url = "https://files.pythonhosted.org/packages/33/46/ca335c2e1f90446a77640a45eeb1cd8f6934f2c6e4df7db0f0f36ef9f025/yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb", size = 93374 }, + { url = "https://files.pythonhosted.org/packages/c3/e8/3efdcb83073df978bb5b1a9cc0360ce596680e6c3fac01f2a994ccbb8939/yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f", size = 147089 }, + { url = "https://files.pythonhosted.org/packages/60/c3/9e776e98ea350f76f94dd80b408eaa54e5092643dbf65fd9babcffb60509/yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e", size = 97706 }, + { url = "https://files.pythonhosted.org/packages/0c/5b/45cdfb64a3b855ce074ae607b9fc40bc82e7613b94e7612b030255c93a09/yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e", size = 95719 }, + { url = "https://files.pythonhosted.org/packages/2d/4e/929633b249611eeed04e2f861a14ed001acca3ef9ec2a984a757b1515889/yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33", size = 343972 }, + { url = "https://files.pythonhosted.org/packages/49/fd/047535d326c913f1a90407a3baf7ff535b10098611eaef2c527e32e81ca1/yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58", size = 339639 }, + { url = "https://files.pythonhosted.org/packages/48/2f/11566f1176a78f4bafb0937c0072410b1b0d3640b297944a6a7a556e1d0b/yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f", size = 353745 }, + { url = "https://files.pythonhosted.org/packages/26/17/07dfcf034d6ae8837b33988be66045dd52f878dfb1c4e8f80a7343f677be/yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae", size = 354178 }, + { url = "https://files.pythonhosted.org/packages/15/45/212604d3142d84b4065d5f8cab6582ed3d78e4cc250568ef2a36fe1cf0a5/yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018", size = 349219 }, + { url = "https://files.pythonhosted.org/packages/e6/e0/a10b30f294111c5f1c682461e9459935c17d467a760c21e1f7db400ff499/yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672", size = 337266 }, + { url = "https://files.pythonhosted.org/packages/33/a6/6efa1d85a675d25a46a167f9f3e80104cde317dfdf7f53f112ae6b16a60a/yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8", size = 360873 }, + { url = "https://files.pythonhosted.org/packages/77/67/c8ab718cb98dfa2ae9ba0f97bf3cbb7d45d37f13fe1fbad25ac92940954e/yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7", size = 360524 }, + { url = "https://files.pythonhosted.org/packages/bd/e8/c3f18660cea1bc73d9f8a2b3ef423def8dadbbae6c4afabdb920b73e0ead/yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594", size = 365370 }, + { url = "https://files.pythonhosted.org/packages/c9/99/33f3b97b065e62ff2d52817155a89cfa030a1a9b43fee7843ef560ad9603/yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6", size = 373297 }, + { url = "https://files.pythonhosted.org/packages/3d/89/7519e79e264a5f08653d2446b26d4724b01198a93a74d2e259291d538ab1/yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1", size = 378771 }, + { url = "https://files.pythonhosted.org/packages/3a/58/6c460bbb884abd2917c3eef6f663a4a873f8dc6f498561fc0ad92231c113/yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b", size = 375000 }, + { url = "https://files.pythonhosted.org/packages/3b/2a/dd7ed1aa23fea996834278d7ff178f215b24324ee527df53d45e34d21d28/yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64", size = 86355 }, + { url = "https://files.pythonhosted.org/packages/ca/c6/333fe0338305c0ac1c16d5aa7cc4841208d3252bbe62172e0051006b5445/yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c", size = 92904 }, + { url = "https://files.pythonhosted.org/packages/0f/6f/514c9bff2900c22a4f10e06297714dbaf98707143b37ff0bcba65a956221/yarl-1.20.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2137810a20b933b1b1b7e5cf06a64c3ed3b4747b0e5d79c9447c00db0e2f752f", size = 145030 }, + { url = "https://files.pythonhosted.org/packages/4e/9d/f88da3fa319b8c9c813389bfb3463e8d777c62654c7168e580a13fadff05/yarl-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:447c5eadd750db8389804030d15f43d30435ed47af1313303ed82a62388176d3", size = 96894 }, + { url = "https://files.pythonhosted.org/packages/cd/57/92e83538580a6968b2451d6c89c5579938a7309d4785748e8ad42ddafdce/yarl-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42fbe577272c203528d402eec8bf4b2d14fd49ecfec92272334270b850e9cd7d", size = 94457 }, + { url = "https://files.pythonhosted.org/packages/e9/ee/7ee43bd4cf82dddd5da97fcaddb6fa541ab81f3ed564c42f146c83ae17ce/yarl-1.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e321617de4ab170226cd15006a565d0fa0d908f11f724a2c9142d6b2812ab0", size = 343070 }, + { url = "https://files.pythonhosted.org/packages/4a/12/b5eccd1109e2097bcc494ba7dc5de156e41cf8309fab437ebb7c2b296ce3/yarl-1.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4345f58719825bba29895011e8e3b545e6e00257abb984f9f27fe923afca2501", size = 337739 }, + { url = "https://files.pythonhosted.org/packages/7d/6b/0eade8e49af9fc2585552f63c76fa59ef469c724cc05b29519b19aa3a6d5/yarl-1.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d9b980d7234614bc4674468ab173ed77d678349c860c3af83b1fffb6a837ddc", size = 351338 }, + { url = "https://files.pythonhosted.org/packages/45/cb/aaaa75d30087b5183c7b8a07b4fb16ae0682dd149a1719b3a28f54061754/yarl-1.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af4baa8a445977831cbaa91a9a84cc09debb10bc8391f128da2f7bd070fc351d", size = 353636 }, + { url = "https://files.pythonhosted.org/packages/98/9d/d9cb39ec68a91ba6e66fa86d97003f58570327d6713833edf7ad6ce9dde5/yarl-1.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123393db7420e71d6ce40d24885a9e65eb1edefc7a5228db2d62bcab3386a5c0", size = 348061 }, + { url = "https://files.pythonhosted.org/packages/72/6b/103940aae893d0cc770b4c36ce80e2ed86fcb863d48ea80a752b8bda9303/yarl-1.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab47acc9332f3de1b39e9b702d9c916af7f02656b2a86a474d9db4e53ef8fd7a", size = 334150 }, + { url = "https://files.pythonhosted.org/packages/ef/b2/986bd82aa222c3e6b211a69c9081ba46484cffa9fab2a5235e8d18ca7a27/yarl-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4a34c52ed158f89876cba9c600b2c964dfc1ca52ba7b3ab6deb722d1d8be6df2", size = 362207 }, + { url = "https://files.pythonhosted.org/packages/14/7c/63f5922437b873795d9422cbe7eb2509d4b540c37ae5548a4bb68fd2c546/yarl-1.20.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:04d8cfb12714158abf2618f792c77bc5c3d8c5f37353e79509608be4f18705c9", size = 361277 }, + { url = "https://files.pythonhosted.org/packages/81/83/450938cccf732466953406570bdb42c62b5ffb0ac7ac75a1f267773ab5c8/yarl-1.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7dc63ad0d541c38b6ae2255aaa794434293964677d5c1ec5d0116b0e308031f5", size = 364990 }, + { url = "https://files.pythonhosted.org/packages/b4/de/af47d3a47e4a833693b9ec8e87debb20f09d9fdc9139b207b09a3e6cbd5a/yarl-1.20.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d02b591a64e4e6ca18c5e3d925f11b559c763b950184a64cf47d74d7e41877", size = 374684 }, + { url = "https://files.pythonhosted.org/packages/62/0b/078bcc2d539f1faffdc7d32cb29a2d7caa65f1a6f7e40795d8485db21851/yarl-1.20.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95fc9876f917cac7f757df80a5dda9de59d423568460fe75d128c813b9af558e", size = 382599 }, + { url = "https://files.pythonhosted.org/packages/74/a9/4fdb1a7899f1fb47fd1371e7ba9e94bff73439ce87099d5dd26d285fffe0/yarl-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb769ae5760cd1c6a712135ee7915f9d43f11d9ef769cb3f75a23e398a92d384", size = 378573 }, + { url = "https://files.pythonhosted.org/packages/fd/be/29f5156b7a319e4d2e5b51ce622b4dfb3aa8d8204cd2a8a339340fbfad40/yarl-1.20.0-cp313-cp313-win32.whl", hash = "sha256:70e0c580a0292c7414a1cead1e076c9786f685c1fc4757573d2967689b370e62", size = 86051 }, + { url = "https://files.pythonhosted.org/packages/52/56/05fa52c32c301da77ec0b5f63d2d9605946fe29defacb2a7ebd473c23b81/yarl-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:4c43030e4b0af775a85be1fa0433119b1565673266a70bf87ef68a9d5ba3174c", size = 92742 }, + { url = "https://files.pythonhosted.org/packages/d4/2f/422546794196519152fc2e2f475f0e1d4d094a11995c81a465faf5673ffd/yarl-1.20.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b6c4c3d0d6a0ae9b281e492b1465c72de433b782e6b5001c8e7249e085b69051", size = 163575 }, + { url = "https://files.pythonhosted.org/packages/90/fc/67c64ddab6c0b4a169d03c637fb2d2a212b536e1989dec8e7e2c92211b7f/yarl-1.20.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8681700f4e4df891eafa4f69a439a6e7d480d64e52bf460918f58e443bd3da7d", size = 106121 }, + { url = "https://files.pythonhosted.org/packages/6d/00/29366b9eba7b6f6baed7d749f12add209b987c4cfbfa418404dbadc0f97c/yarl-1.20.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:84aeb556cb06c00652dbf87c17838eb6d92cfd317799a8092cee0e570ee11229", size = 103815 }, + { url = "https://files.pythonhosted.org/packages/28/f4/a2a4c967c8323c03689383dff73396281ced3b35d0ed140580825c826af7/yarl-1.20.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f166eafa78810ddb383e930d62e623d288fb04ec566d1b4790099ae0f31485f1", size = 408231 }, + { url = "https://files.pythonhosted.org/packages/0f/a1/66f7ffc0915877d726b70cc7a896ac30b6ac5d1d2760613603b022173635/yarl-1.20.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5d3d6d14754aefc7a458261027a562f024d4f6b8a798adb472277f675857b1eb", size = 390221 }, + { url = "https://files.pythonhosted.org/packages/41/15/cc248f0504610283271615e85bf38bc014224122498c2016d13a3a1b8426/yarl-1.20.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a8f64df8ed5d04c51260dbae3cc82e5649834eebea9eadfd829837b8093eb00", size = 411400 }, + { url = "https://files.pythonhosted.org/packages/5c/af/f0823d7e092bfb97d24fce6c7269d67fcd1aefade97d0a8189c4452e4d5e/yarl-1.20.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d9949eaf05b4d30e93e4034a7790634bbb41b8be2d07edd26754f2e38e491de", size = 411714 }, + { url = "https://files.pythonhosted.org/packages/83/70/be418329eae64b9f1b20ecdaac75d53aef098797d4c2299d82ae6f8e4663/yarl-1.20.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c366b254082d21cc4f08f522ac201d0d83a8b8447ab562732931d31d80eb2a5", size = 404279 }, + { url = "https://files.pythonhosted.org/packages/19/f5/52e02f0075f65b4914eb890eea1ba97e6fd91dd821cc33a623aa707b2f67/yarl-1.20.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91bc450c80a2e9685b10e34e41aef3d44ddf99b3a498717938926d05ca493f6a", size = 384044 }, + { url = "https://files.pythonhosted.org/packages/6a/36/b0fa25226b03d3f769c68d46170b3e92b00ab3853d73127273ba22474697/yarl-1.20.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c2aa4387de4bc3a5fe158080757748d16567119bef215bec643716b4fbf53f9", size = 416236 }, + { url = "https://files.pythonhosted.org/packages/cb/3a/54c828dd35f6831dfdd5a79e6c6b4302ae2c5feca24232a83cb75132b205/yarl-1.20.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d2cbca6760a541189cf87ee54ff891e1d9ea6406079c66341008f7ef6ab61145", size = 402034 }, + { url = "https://files.pythonhosted.org/packages/10/97/c7bf5fba488f7e049f9ad69c1b8fdfe3daa2e8916b3d321aa049e361a55a/yarl-1.20.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:798a5074e656f06b9fad1a162be5a32da45237ce19d07884d0b67a0aa9d5fdda", size = 407943 }, + { url = "https://files.pythonhosted.org/packages/fd/a4/022d2555c1e8fcff08ad7f0f43e4df3aba34f135bff04dd35d5526ce54ab/yarl-1.20.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f106e75c454288472dbe615accef8248c686958c2e7dd3b8d8ee2669770d020f", size = 423058 }, + { url = "https://files.pythonhosted.org/packages/4c/f6/0873a05563e5df29ccf35345a6ae0ac9e66588b41fdb7043a65848f03139/yarl-1.20.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3b60a86551669c23dc5445010534d2c5d8a4e012163218fc9114e857c0586fdd", size = 423792 }, + { url = "https://files.pythonhosted.org/packages/9e/35/43fbbd082708fa42e923f314c24f8277a28483d219e049552e5007a9aaca/yarl-1.20.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e429857e341d5e8e15806118e0294f8073ba9c4580637e59ab7b238afca836f", size = 422242 }, + { url = "https://files.pythonhosted.org/packages/ed/f7/f0f2500cf0c469beb2050b522c7815c575811627e6d3eb9ec7550ddd0bfe/yarl-1.20.0-cp313-cp313t-win32.whl", hash = "sha256:65a4053580fe88a63e8e4056b427224cd01edfb5f951498bfefca4052f0ce0ac", size = 93816 }, + { url = "https://files.pythonhosted.org/packages/3f/93/f73b61353b2a699d489e782c3f5998b59f974ec3156a2050a52dfd7e8946/yarl-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:53b2da3a6ca0a541c1ae799c349788d480e5144cac47dba0266c7cb6c76151fe", size = 101093 }, + { url = "https://files.pythonhosted.org/packages/bc/95/3d22e1d2fa6dce3670d820a859f4fc5526400c58019650d2da4e19b9924d/yarl-1.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:119bca25e63a7725b0c9d20ac67ca6d98fa40e5a894bd5d4686010ff73397914", size = 146680 }, + { url = "https://files.pythonhosted.org/packages/12/43/37f2d17e0b82d4f01b2da1fe53a19ff95be6d7d9902cad11d3ebbef5bc9d/yarl-1.20.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:35d20fb919546995f1d8c9e41f485febd266f60e55383090010f272aca93edcc", size = 97707 }, + { url = "https://files.pythonhosted.org/packages/8c/3e/665501121ba7c712a0f1b58d8ee01d7633096671fbeec4cf3dc4e4357a95/yarl-1.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:484e7a08f72683c0f160270566b4395ea5412b4359772b98659921411d32ad26", size = 95385 }, + { url = "https://files.pythonhosted.org/packages/bf/8d/48edf4d49ca38e5229faf793276bdd6f01704740dcf519cf1d282acac6c6/yarl-1.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d8a3d54a090e0fff5837cd3cc305dd8a07d3435a088ddb1f65e33b322f66a94", size = 332687 }, + { url = "https://files.pythonhosted.org/packages/e0/c1/112c516bead873c83abe30e08143714d702d1fffdfed43dc103312b81666/yarl-1.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f0cf05ae2d3d87a8c9022f3885ac6dea2b751aefd66a4f200e408a61ae9b7f0d", size = 325390 }, + { url = "https://files.pythonhosted.org/packages/0b/4c/07aef11f7f23a41049eb0b3b357ceb32bd9798f62042858e0168be9f6f49/yarl-1.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a884b8974729e3899d9287df46f015ce53f7282d8d3340fa0ed57536b440621c", size = 348497 }, + { url = "https://files.pythonhosted.org/packages/56/d9/00d5525a2c5e5c66967eaa03866bef6317da4b129ae016582c6641826974/yarl-1.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8d8aa8dd89ffb9a831fedbcb27d00ffd9f4842107d52dc9d57e64cb34073d5c", size = 343670 }, + { url = "https://files.pythonhosted.org/packages/e8/7c/2fc733090c6fce82ea5c50f431e70f5dff196d7b54da93b9d6e801031dd2/yarl-1.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4e88d6c3c8672f45a30867817e4537df1bbc6f882a91581faf1f6d9f0f1b5a", size = 335738 }, + { url = "https://files.pythonhosted.org/packages/4b/ce/6b22de535b7bc7b19f3cf23c4e744cd2368fa11a0c8f218dfd2ef46b6c3a/yarl-1.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdb77efde644d6f1ad27be8a5d67c10b7f769804fff7a966ccb1da5a4de4b656", size = 328203 }, + { url = "https://files.pythonhosted.org/packages/6b/c8/3fc10db34e731a426baaff348aa1b2c0eb9cb93ff723af4e930e767c058e/yarl-1.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4ba5e59f14bfe8d261a654278a0f6364feef64a794bd456a8c9e823071e5061c", size = 341922 }, + { url = "https://files.pythonhosted.org/packages/37/59/f607a63c24b31c66cf288cb819d8dbcac2bd9ec90f39bd03986f33a866b3/yarl-1.20.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d0bf955b96ea44ad914bc792c26a0edcd71b4668b93cbcd60f5b0aeaaed06c64", size = 338163 }, + { url = "https://files.pythonhosted.org/packages/01/b2/5fd461fe8ab3bb788e19ef6c35a3453f44a5c0d6973f847a08060c4d6183/yarl-1.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:27359776bc359ee6eaefe40cb19060238f31228799e43ebd3884e9c589e63b20", size = 343096 }, + { url = "https://files.pythonhosted.org/packages/71/d3/7102efd34ed22e6839361f30a27bdad341c0a01f66fcbf09822a1d90b853/yarl-1.20.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:04d9c7a1dc0a26efb33e1acb56c8849bd57a693b85f44774356c92d610369efa", size = 358520 }, + { url = "https://files.pythonhosted.org/packages/c0/ab/754b60a5c8be8abaa746543555612b2205ba60c194fc3a0547a34e0b6a53/yarl-1.20.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:faa709b66ae0e24c8e5134033187a972d849d87ed0a12a0366bedcc6b5dc14a5", size = 359635 }, + { url = "https://files.pythonhosted.org/packages/e0/d5/369f994369a7233fcd81f642553062d4f6c657a93069b58258b9046bb87d/yarl-1.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:44869ee8538208fe5d9342ed62c11cc6a7a1af1b3d0bb79bb795101b6e77f6e0", size = 353906 }, + { url = "https://files.pythonhosted.org/packages/1b/59/c7f929d7cd7c1f0c918c38aca06d07cac2e4f3577a95fe3a836b3079a3ca/yarl-1.20.0-cp39-cp39-win32.whl", hash = "sha256:b7fa0cb9fd27ffb1211cde944b41f5c67ab1c13a13ebafe470b1e206b8459da8", size = 87243 }, + { url = "https://files.pythonhosted.org/packages/1c/bc/80f16fc58cb3b61b15450eaf6c874d9c984c96453d9024b9d0aa4655dac9/yarl-1.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:d4fad6e5189c847820288286732075f213eabf81be4d08d6cc309912e62be5b7", size = 93457 }, + { url = "https://files.pythonhosted.org/packages/ea/1f/70c57b3d7278e94ed22d85e09685d3f0a38ebdd8c5c73b65ba4c0d0fe002/yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124", size = 46124 }, ] [[package]] name = "zipp" version = "3.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545, upload-time = "2024-11-10T15:05:20.202Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630, upload-time = "2024-11-10T15:05:19.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, ] [[package]] @@ -1645,86 +1656,86 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation == 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/f6/2ac0287b442160a89d726b17a9184a4c615bb5237db763791a7fd16d9df1/zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09", size = 681701, upload-time = "2024-07-15T00:18:06.141Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/f6/2ac0287b442160a89d726b17a9184a4c615bb5237db763791a7fd16d9df1/zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09", size = 681701 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/55/bd0487e86679db1823fc9ee0d8c9c78ae2413d34c0b461193b5f4c31d22f/zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9", size = 788701, upload-time = "2024-07-15T00:13:27.351Z" }, - { url = "https://files.pythonhosted.org/packages/e1/8a/ccb516b684f3ad987dfee27570d635822e3038645b1a950c5e8022df1145/zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880", size = 633678, upload-time = "2024-07-15T00:13:30.24Z" }, - { url = "https://files.pythonhosted.org/packages/12/89/75e633d0611c028e0d9af6df199423bf43f54bea5007e6718ab7132e234c/zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc", size = 4941098, upload-time = "2024-07-15T00:13:32.526Z" }, - { url = "https://files.pythonhosted.org/packages/4a/7a/bd7f6a21802de358b63f1ee636ab823711c25ce043a3e9f043b4fcb5ba32/zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573", size = 5308798, upload-time = "2024-07-15T00:13:34.925Z" }, - { url = "https://files.pythonhosted.org/packages/79/3b/775f851a4a65013e88ca559c8ae42ac1352db6fcd96b028d0df4d7d1d7b4/zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391", size = 5341840, upload-time = "2024-07-15T00:13:37.376Z" }, - { url = "https://files.pythonhosted.org/packages/09/4f/0cc49570141dd72d4d95dd6fcf09328d1b702c47a6ec12fbed3b8aed18a5/zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e", size = 5440337, upload-time = "2024-07-15T00:13:39.772Z" }, - { url = "https://files.pythonhosted.org/packages/e7/7c/aaa7cd27148bae2dc095191529c0570d16058c54c4597a7d118de4b21676/zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd", size = 4861182, upload-time = "2024-07-15T00:13:42.495Z" }, - { url = "https://files.pythonhosted.org/packages/ac/eb/4b58b5c071d177f7dc027129d20bd2a44161faca6592a67f8fcb0b88b3ae/zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4", size = 4932936, upload-time = "2024-07-15T00:13:44.234Z" }, - { url = "https://files.pythonhosted.org/packages/44/f9/21a5fb9bb7c9a274b05ad700a82ad22ce82f7ef0f485980a1e98ed6e8c5f/zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea", size = 5464705, upload-time = "2024-07-15T00:13:46.822Z" }, - { url = "https://files.pythonhosted.org/packages/49/74/b7b3e61db3f88632776b78b1db597af3f44c91ce17d533e14a25ce6a2816/zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2", size = 4857882, upload-time = "2024-07-15T00:13:49.297Z" }, - { url = "https://files.pythonhosted.org/packages/4a/7f/d8eb1cb123d8e4c541d4465167080bec88481ab54cd0b31eb4013ba04b95/zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9", size = 4697672, upload-time = "2024-07-15T00:13:51.447Z" }, - { url = "https://files.pythonhosted.org/packages/5e/05/f7dccdf3d121309b60342da454d3e706453a31073e2c4dac8e1581861e44/zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a", size = 5206043, upload-time = "2024-07-15T00:13:53.587Z" }, - { url = "https://files.pythonhosted.org/packages/86/9d/3677a02e172dccd8dd3a941307621c0cbd7691d77cb435ac3c75ab6a3105/zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0", size = 5667390, upload-time = "2024-07-15T00:13:56.137Z" }, - { url = "https://files.pythonhosted.org/packages/41/7e/0012a02458e74a7ba122cd9cafe491facc602c9a17f590367da369929498/zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c", size = 5198901, upload-time = "2024-07-15T00:13:58.584Z" }, - { url = "https://files.pythonhosted.org/packages/65/3a/8f715b97bd7bcfc7342d8adcd99a026cb2fb550e44866a3b6c348e1b0f02/zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813", size = 430596, upload-time = "2024-07-15T00:14:00.693Z" }, - { url = "https://files.pythonhosted.org/packages/19/b7/b2b9eca5e5a01111e4fe8a8ffb56bdcdf56b12448a24effe6cfe4a252034/zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4", size = 495498, upload-time = "2024-07-15T00:14:02.741Z" }, - { url = "https://files.pythonhosted.org/packages/9e/40/f67e7d2c25a0e2dc1744dd781110b0b60306657f8696cafb7ad7579469bd/zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e", size = 788699, upload-time = "2024-07-15T00:14:04.909Z" }, - { url = "https://files.pythonhosted.org/packages/e8/46/66d5b55f4d737dd6ab75851b224abf0afe5774976fe511a54d2eb9063a41/zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23", size = 633681, upload-time = "2024-07-15T00:14:13.99Z" }, - { url = "https://files.pythonhosted.org/packages/63/b6/677e65c095d8e12b66b8f862b069bcf1f1d781b9c9c6f12eb55000d57583/zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a", size = 4944328, upload-time = "2024-07-15T00:14:16.588Z" }, - { url = "https://files.pythonhosted.org/packages/59/cc/e76acb4c42afa05a9d20827116d1f9287e9c32b7ad58cc3af0721ce2b481/zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db", size = 5311955, upload-time = "2024-07-15T00:14:19.389Z" }, - { url = "https://files.pythonhosted.org/packages/78/e4/644b8075f18fc7f632130c32e8f36f6dc1b93065bf2dd87f03223b187f26/zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2", size = 5344944, upload-time = "2024-07-15T00:14:22.173Z" }, - { url = "https://files.pythonhosted.org/packages/76/3f/dbafccf19cfeca25bbabf6f2dd81796b7218f768ec400f043edc767015a6/zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca", size = 5442927, upload-time = "2024-07-15T00:14:24.825Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c3/d24a01a19b6733b9f218e94d1a87c477d523237e07f94899e1c10f6fd06c/zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c", size = 4864910, upload-time = "2024-07-15T00:14:26.982Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a9/cf8f78ead4597264f7618d0875be01f9bc23c9d1d11afb6d225b867cb423/zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e", size = 4935544, upload-time = "2024-07-15T00:14:29.582Z" }, - { url = "https://files.pythonhosted.org/packages/2c/96/8af1e3731b67965fb995a940c04a2c20997a7b3b14826b9d1301cf160879/zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5", size = 5467094, upload-time = "2024-07-15T00:14:40.126Z" }, - { url = "https://files.pythonhosted.org/packages/ff/57/43ea9df642c636cb79f88a13ab07d92d88d3bfe3e550b55a25a07a26d878/zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48", size = 4860440, upload-time = "2024-07-15T00:14:42.786Z" }, - { url = "https://files.pythonhosted.org/packages/46/37/edb78f33c7f44f806525f27baa300341918fd4c4af9472fbc2c3094be2e8/zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c", size = 4700091, upload-time = "2024-07-15T00:14:45.184Z" }, - { url = "https://files.pythonhosted.org/packages/c1/f1/454ac3962671a754f3cb49242472df5c2cced4eb959ae203a377b45b1a3c/zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003", size = 5208682, upload-time = "2024-07-15T00:14:47.407Z" }, - { url = "https://files.pythonhosted.org/packages/85/b2/1734b0fff1634390b1b887202d557d2dd542de84a4c155c258cf75da4773/zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78", size = 5669707, upload-time = "2024-07-15T00:15:03.529Z" }, - { url = "https://files.pythonhosted.org/packages/52/5a/87d6971f0997c4b9b09c495bf92189fb63de86a83cadc4977dc19735f652/zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473", size = 5201792, upload-time = "2024-07-15T00:15:28.372Z" }, - { url = "https://files.pythonhosted.org/packages/79/02/6f6a42cc84459d399bd1a4e1adfc78d4dfe45e56d05b072008d10040e13b/zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160", size = 430586, upload-time = "2024-07-15T00:15:32.26Z" }, - { url = "https://files.pythonhosted.org/packages/be/a2/4272175d47c623ff78196f3c10e9dc7045c1b9caf3735bf041e65271eca4/zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0", size = 495420, upload-time = "2024-07-15T00:15:34.004Z" }, - { url = "https://files.pythonhosted.org/packages/7b/83/f23338c963bd9de687d47bf32efe9fd30164e722ba27fb59df33e6b1719b/zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094", size = 788713, upload-time = "2024-07-15T00:15:35.815Z" }, - { url = "https://files.pythonhosted.org/packages/5b/b3/1a028f6750fd9227ee0b937a278a434ab7f7fdc3066c3173f64366fe2466/zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8", size = 633459, upload-time = "2024-07-15T00:15:37.995Z" }, - { url = "https://files.pythonhosted.org/packages/26/af/36d89aae0c1f95a0a98e50711bc5d92c144939efc1f81a2fcd3e78d7f4c1/zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1", size = 4945707, upload-time = "2024-07-15T00:15:39.872Z" }, - { url = "https://files.pythonhosted.org/packages/cd/2e/2051f5c772f4dfc0aae3741d5fc72c3dcfe3aaeb461cc231668a4db1ce14/zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072", size = 5306545, upload-time = "2024-07-15T00:15:41.75Z" }, - { url = "https://files.pythonhosted.org/packages/0a/9e/a11c97b087f89cab030fa71206963090d2fecd8eb83e67bb8f3ffb84c024/zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20", size = 5337533, upload-time = "2024-07-15T00:15:44.114Z" }, - { url = "https://files.pythonhosted.org/packages/fc/79/edeb217c57fe1bf16d890aa91a1c2c96b28c07b46afed54a5dcf310c3f6f/zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373", size = 5436510, upload-time = "2024-07-15T00:15:46.509Z" }, - { url = "https://files.pythonhosted.org/packages/81/4f/c21383d97cb7a422ddf1ae824b53ce4b51063d0eeb2afa757eb40804a8ef/zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db", size = 4859973, upload-time = "2024-07-15T00:15:49.939Z" }, - { url = "https://files.pythonhosted.org/packages/ab/15/08d22e87753304405ccac8be2493a495f529edd81d39a0870621462276ef/zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772", size = 4936968, upload-time = "2024-07-15T00:15:52.025Z" }, - { url = "https://files.pythonhosted.org/packages/eb/fa/f3670a597949fe7dcf38119a39f7da49a8a84a6f0b1a2e46b2f71a0ab83f/zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105", size = 5467179, upload-time = "2024-07-15T00:15:54.971Z" }, - { url = "https://files.pythonhosted.org/packages/4e/a9/dad2ab22020211e380adc477a1dbf9f109b1f8d94c614944843e20dc2a99/zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba", size = 4848577, upload-time = "2024-07-15T00:15:57.634Z" }, - { url = "https://files.pythonhosted.org/packages/08/03/dd28b4484b0770f1e23478413e01bee476ae8227bbc81561f9c329e12564/zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd", size = 4693899, upload-time = "2024-07-15T00:16:00.811Z" }, - { url = "https://files.pythonhosted.org/packages/2b/64/3da7497eb635d025841e958bcd66a86117ae320c3b14b0ae86e9e8627518/zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a", size = 5199964, upload-time = "2024-07-15T00:16:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/43/a4/d82decbab158a0e8a6ebb7fc98bc4d903266bce85b6e9aaedea1d288338c/zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90", size = 5655398, upload-time = "2024-07-15T00:16:06.694Z" }, - { url = "https://files.pythonhosted.org/packages/f2/61/ac78a1263bc83a5cf29e7458b77a568eda5a8f81980691bbc6eb6a0d45cc/zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35", size = 5191313, upload-time = "2024-07-15T00:16:09.758Z" }, - { url = "https://files.pythonhosted.org/packages/e7/54/967c478314e16af5baf849b6ee9d6ea724ae5b100eb506011f045d3d4e16/zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d", size = 430877, upload-time = "2024-07-15T00:16:11.758Z" }, - { url = "https://files.pythonhosted.org/packages/75/37/872d74bd7739639c4553bf94c84af7d54d8211b626b352bc57f0fd8d1e3f/zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b", size = 495595, upload-time = "2024-07-15T00:16:13.731Z" }, - { url = "https://files.pythonhosted.org/packages/80/f1/8386f3f7c10261fe85fbc2c012fdb3d4db793b921c9abcc995d8da1b7a80/zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9", size = 788975, upload-time = "2024-07-15T00:16:16.005Z" }, - { url = "https://files.pythonhosted.org/packages/16/e8/cbf01077550b3e5dc86089035ff8f6fbbb312bc0983757c2d1117ebba242/zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a", size = 633448, upload-time = "2024-07-15T00:16:17.897Z" }, - { url = "https://files.pythonhosted.org/packages/06/27/4a1b4c267c29a464a161aeb2589aff212b4db653a1d96bffe3598f3f0d22/zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2", size = 4945269, upload-time = "2024-07-15T00:16:20.136Z" }, - { url = "https://files.pythonhosted.org/packages/7c/64/d99261cc57afd9ae65b707e38045ed8269fbdae73544fd2e4a4d50d0ed83/zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5", size = 5306228, upload-time = "2024-07-15T00:16:23.398Z" }, - { url = "https://files.pythonhosted.org/packages/7a/cf/27b74c6f22541f0263016a0fd6369b1b7818941de639215c84e4e94b2a1c/zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f", size = 5336891, upload-time = "2024-07-15T00:16:26.391Z" }, - { url = "https://files.pythonhosted.org/packages/fa/18/89ac62eac46b69948bf35fcd90d37103f38722968e2981f752d69081ec4d/zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed", size = 5436310, upload-time = "2024-07-15T00:16:29.018Z" }, - { url = "https://files.pythonhosted.org/packages/a8/a8/5ca5328ee568a873f5118d5b5f70d1f36c6387716efe2e369010289a5738/zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea", size = 4859912, upload-time = "2024-07-15T00:16:31.871Z" }, - { url = "https://files.pythonhosted.org/packages/ea/ca/3781059c95fd0868658b1cf0440edd832b942f84ae60685d0cfdb808bca1/zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847", size = 4936946, upload-time = "2024-07-15T00:16:34.593Z" }, - { url = "https://files.pythonhosted.org/packages/ce/11/41a58986f809532742c2b832c53b74ba0e0a5dae7e8ab4642bf5876f35de/zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171", size = 5466994, upload-time = "2024-07-15T00:16:36.887Z" }, - { url = "https://files.pythonhosted.org/packages/83/e3/97d84fe95edd38d7053af05159465d298c8b20cebe9ccb3d26783faa9094/zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840", size = 4848681, upload-time = "2024-07-15T00:16:39.709Z" }, - { url = "https://files.pythonhosted.org/packages/6e/99/cb1e63e931de15c88af26085e3f2d9af9ce53ccafac73b6e48418fd5a6e6/zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690", size = 4694239, upload-time = "2024-07-15T00:16:41.83Z" }, - { url = "https://files.pythonhosted.org/packages/ab/50/b1e703016eebbc6501fc92f34db7b1c68e54e567ef39e6e59cf5fb6f2ec0/zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b", size = 5200149, upload-time = "2024-07-15T00:16:44.287Z" }, - { url = "https://files.pythonhosted.org/packages/aa/e0/932388630aaba70197c78bdb10cce2c91fae01a7e553b76ce85471aec690/zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057", size = 5655392, upload-time = "2024-07-15T00:16:46.423Z" }, - { url = "https://files.pythonhosted.org/packages/02/90/2633473864f67a15526324b007a9f96c96f56d5f32ef2a56cc12f9548723/zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33", size = 5191299, upload-time = "2024-07-15T00:16:49.053Z" }, - { url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862, upload-time = "2024-07-15T00:16:51.003Z" }, - { url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578, upload-time = "2024-07-15T00:16:53.135Z" }, - { url = "https://files.pythonhosted.org/packages/fb/96/4fcafeb7e013a2386d22f974b5b97a0b9a65004ed58c87ae001599bfbd48/zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb", size = 788697, upload-time = "2024-07-15T00:17:31.236Z" }, - { url = "https://files.pythonhosted.org/packages/83/ff/a52ce725be69b86a2967ecba0497a8184540cc284c0991125515449e54e2/zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916", size = 633679, upload-time = "2024-07-15T00:17:32.911Z" }, - { url = "https://files.pythonhosted.org/packages/34/0f/3dc62db122f6a9c481c335fff6fc9f4e88d8f6e2d47321ee3937328addb4/zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a", size = 4940416, upload-time = "2024-07-15T00:17:34.849Z" }, - { url = "https://files.pythonhosted.org/packages/1d/e5/9fe0dd8c85fdc2f635e6660d07872a5dc4b366db566630161e39f9f804e1/zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259", size = 5307693, upload-time = "2024-07-15T00:17:37.355Z" }, - { url = "https://files.pythonhosted.org/packages/73/bf/fe62c0cd865c171ee8ed5bc83174b5382a2cb729c8d6162edfb99a83158b/zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4", size = 5341236, upload-time = "2024-07-15T00:17:40.213Z" }, - { url = "https://files.pythonhosted.org/packages/39/86/4fe79b30c794286110802a6cd44a73b6a314ac8196b9338c0fbd78c2407d/zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58", size = 5439101, upload-time = "2024-07-15T00:17:42.284Z" }, - { url = "https://files.pythonhosted.org/packages/72/ed/cacec235c581ebf8c608c7fb3d4b6b70d1b490d0e5128ea6996f809ecaef/zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15", size = 4860320, upload-time = "2024-07-15T00:17:44.21Z" }, - { url = "https://files.pythonhosted.org/packages/f6/1e/2c589a2930f93946b132fc852c574a19d5edc23fad2b9e566f431050c7ec/zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269", size = 4931933, upload-time = "2024-07-15T00:17:46.455Z" }, - { url = "https://files.pythonhosted.org/packages/8e/f5/30eadde3686d902b5d4692bb5f286977cbc4adc082145eb3f49d834b2eae/zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700", size = 5463878, upload-time = "2024-07-15T00:17:48.866Z" }, - { url = "https://files.pythonhosted.org/packages/e0/c8/8aed1f0ab9854ef48e5ad4431367fcb23ce73f0304f7b72335a8edc66556/zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9", size = 4857192, upload-time = "2024-07-15T00:17:51.558Z" }, - { url = "https://files.pythonhosted.org/packages/a8/c6/55e666cfbcd032b9e271865e8578fec56e5594d4faeac379d371526514f5/zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69", size = 4696513, upload-time = "2024-07-15T00:17:53.924Z" }, - { url = "https://files.pythonhosted.org/packages/dc/bd/720b65bea63ec9de0ac7414c33b9baf271c8de8996e5ff324dc93fc90ff1/zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70", size = 5204823, upload-time = "2024-07-15T00:17:55.948Z" }, - { url = "https://files.pythonhosted.org/packages/d8/40/d678db1556e3941d330cd4e95623a63ef235b18547da98fa184cbc028ecf/zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2", size = 5666490, upload-time = "2024-07-15T00:17:58.327Z" }, - { url = "https://files.pythonhosted.org/packages/ed/cc/c89329723d7515898a1fc7ef5d251264078548c505719d13e9511800a103/zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5", size = 5196622, upload-time = "2024-07-15T00:18:00.404Z" }, - { url = "https://files.pythonhosted.org/packages/78/4c/634289d41e094327a94500dfc919e58841b10ea3a9efdfafbac614797ec2/zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274", size = 430620, upload-time = "2024-07-15T00:18:02.613Z" }, - { url = "https://files.pythonhosted.org/packages/a2/e2/0b0c5a0f4f7699fecd92c1ba6278ef9b01f2b0b0dd46f62bfc6729c05659/zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58", size = 495528, upload-time = "2024-07-15T00:18:04.452Z" }, + { url = "https://files.pythonhosted.org/packages/2a/55/bd0487e86679db1823fc9ee0d8c9c78ae2413d34c0b461193b5f4c31d22f/zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9", size = 788701 }, + { url = "https://files.pythonhosted.org/packages/e1/8a/ccb516b684f3ad987dfee27570d635822e3038645b1a950c5e8022df1145/zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880", size = 633678 }, + { url = "https://files.pythonhosted.org/packages/12/89/75e633d0611c028e0d9af6df199423bf43f54bea5007e6718ab7132e234c/zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc", size = 4941098 }, + { url = "https://files.pythonhosted.org/packages/4a/7a/bd7f6a21802de358b63f1ee636ab823711c25ce043a3e9f043b4fcb5ba32/zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573", size = 5308798 }, + { url = "https://files.pythonhosted.org/packages/79/3b/775f851a4a65013e88ca559c8ae42ac1352db6fcd96b028d0df4d7d1d7b4/zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391", size = 5341840 }, + { url = "https://files.pythonhosted.org/packages/09/4f/0cc49570141dd72d4d95dd6fcf09328d1b702c47a6ec12fbed3b8aed18a5/zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e", size = 5440337 }, + { url = "https://files.pythonhosted.org/packages/e7/7c/aaa7cd27148bae2dc095191529c0570d16058c54c4597a7d118de4b21676/zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd", size = 4861182 }, + { url = "https://files.pythonhosted.org/packages/ac/eb/4b58b5c071d177f7dc027129d20bd2a44161faca6592a67f8fcb0b88b3ae/zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4", size = 4932936 }, + { url = "https://files.pythonhosted.org/packages/44/f9/21a5fb9bb7c9a274b05ad700a82ad22ce82f7ef0f485980a1e98ed6e8c5f/zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea", size = 5464705 }, + { url = "https://files.pythonhosted.org/packages/49/74/b7b3e61db3f88632776b78b1db597af3f44c91ce17d533e14a25ce6a2816/zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2", size = 4857882 }, + { url = "https://files.pythonhosted.org/packages/4a/7f/d8eb1cb123d8e4c541d4465167080bec88481ab54cd0b31eb4013ba04b95/zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9", size = 4697672 }, + { url = "https://files.pythonhosted.org/packages/5e/05/f7dccdf3d121309b60342da454d3e706453a31073e2c4dac8e1581861e44/zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a", size = 5206043 }, + { url = "https://files.pythonhosted.org/packages/86/9d/3677a02e172dccd8dd3a941307621c0cbd7691d77cb435ac3c75ab6a3105/zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0", size = 5667390 }, + { url = "https://files.pythonhosted.org/packages/41/7e/0012a02458e74a7ba122cd9cafe491facc602c9a17f590367da369929498/zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c", size = 5198901 }, + { url = "https://files.pythonhosted.org/packages/65/3a/8f715b97bd7bcfc7342d8adcd99a026cb2fb550e44866a3b6c348e1b0f02/zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813", size = 430596 }, + { url = "https://files.pythonhosted.org/packages/19/b7/b2b9eca5e5a01111e4fe8a8ffb56bdcdf56b12448a24effe6cfe4a252034/zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4", size = 495498 }, + { url = "https://files.pythonhosted.org/packages/9e/40/f67e7d2c25a0e2dc1744dd781110b0b60306657f8696cafb7ad7579469bd/zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e", size = 788699 }, + { url = "https://files.pythonhosted.org/packages/e8/46/66d5b55f4d737dd6ab75851b224abf0afe5774976fe511a54d2eb9063a41/zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23", size = 633681 }, + { url = "https://files.pythonhosted.org/packages/63/b6/677e65c095d8e12b66b8f862b069bcf1f1d781b9c9c6f12eb55000d57583/zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a", size = 4944328 }, + { url = "https://files.pythonhosted.org/packages/59/cc/e76acb4c42afa05a9d20827116d1f9287e9c32b7ad58cc3af0721ce2b481/zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db", size = 5311955 }, + { url = "https://files.pythonhosted.org/packages/78/e4/644b8075f18fc7f632130c32e8f36f6dc1b93065bf2dd87f03223b187f26/zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2", size = 5344944 }, + { url = "https://files.pythonhosted.org/packages/76/3f/dbafccf19cfeca25bbabf6f2dd81796b7218f768ec400f043edc767015a6/zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca", size = 5442927 }, + { url = "https://files.pythonhosted.org/packages/0c/c3/d24a01a19b6733b9f218e94d1a87c477d523237e07f94899e1c10f6fd06c/zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c", size = 4864910 }, + { url = "https://files.pythonhosted.org/packages/1c/a9/cf8f78ead4597264f7618d0875be01f9bc23c9d1d11afb6d225b867cb423/zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e", size = 4935544 }, + { url = "https://files.pythonhosted.org/packages/2c/96/8af1e3731b67965fb995a940c04a2c20997a7b3b14826b9d1301cf160879/zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5", size = 5467094 }, + { url = "https://files.pythonhosted.org/packages/ff/57/43ea9df642c636cb79f88a13ab07d92d88d3bfe3e550b55a25a07a26d878/zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48", size = 4860440 }, + { url = "https://files.pythonhosted.org/packages/46/37/edb78f33c7f44f806525f27baa300341918fd4c4af9472fbc2c3094be2e8/zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c", size = 4700091 }, + { url = "https://files.pythonhosted.org/packages/c1/f1/454ac3962671a754f3cb49242472df5c2cced4eb959ae203a377b45b1a3c/zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003", size = 5208682 }, + { url = "https://files.pythonhosted.org/packages/85/b2/1734b0fff1634390b1b887202d557d2dd542de84a4c155c258cf75da4773/zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78", size = 5669707 }, + { url = "https://files.pythonhosted.org/packages/52/5a/87d6971f0997c4b9b09c495bf92189fb63de86a83cadc4977dc19735f652/zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473", size = 5201792 }, + { url = "https://files.pythonhosted.org/packages/79/02/6f6a42cc84459d399bd1a4e1adfc78d4dfe45e56d05b072008d10040e13b/zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160", size = 430586 }, + { url = "https://files.pythonhosted.org/packages/be/a2/4272175d47c623ff78196f3c10e9dc7045c1b9caf3735bf041e65271eca4/zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0", size = 495420 }, + { url = "https://files.pythonhosted.org/packages/7b/83/f23338c963bd9de687d47bf32efe9fd30164e722ba27fb59df33e6b1719b/zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094", size = 788713 }, + { url = "https://files.pythonhosted.org/packages/5b/b3/1a028f6750fd9227ee0b937a278a434ab7f7fdc3066c3173f64366fe2466/zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8", size = 633459 }, + { url = "https://files.pythonhosted.org/packages/26/af/36d89aae0c1f95a0a98e50711bc5d92c144939efc1f81a2fcd3e78d7f4c1/zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1", size = 4945707 }, + { url = "https://files.pythonhosted.org/packages/cd/2e/2051f5c772f4dfc0aae3741d5fc72c3dcfe3aaeb461cc231668a4db1ce14/zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072", size = 5306545 }, + { url = "https://files.pythonhosted.org/packages/0a/9e/a11c97b087f89cab030fa71206963090d2fecd8eb83e67bb8f3ffb84c024/zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20", size = 5337533 }, + { url = "https://files.pythonhosted.org/packages/fc/79/edeb217c57fe1bf16d890aa91a1c2c96b28c07b46afed54a5dcf310c3f6f/zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373", size = 5436510 }, + { url = "https://files.pythonhosted.org/packages/81/4f/c21383d97cb7a422ddf1ae824b53ce4b51063d0eeb2afa757eb40804a8ef/zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db", size = 4859973 }, + { url = "https://files.pythonhosted.org/packages/ab/15/08d22e87753304405ccac8be2493a495f529edd81d39a0870621462276ef/zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772", size = 4936968 }, + { url = "https://files.pythonhosted.org/packages/eb/fa/f3670a597949fe7dcf38119a39f7da49a8a84a6f0b1a2e46b2f71a0ab83f/zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105", size = 5467179 }, + { url = "https://files.pythonhosted.org/packages/4e/a9/dad2ab22020211e380adc477a1dbf9f109b1f8d94c614944843e20dc2a99/zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba", size = 4848577 }, + { url = "https://files.pythonhosted.org/packages/08/03/dd28b4484b0770f1e23478413e01bee476ae8227bbc81561f9c329e12564/zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd", size = 4693899 }, + { url = "https://files.pythonhosted.org/packages/2b/64/3da7497eb635d025841e958bcd66a86117ae320c3b14b0ae86e9e8627518/zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a", size = 5199964 }, + { url = "https://files.pythonhosted.org/packages/43/a4/d82decbab158a0e8a6ebb7fc98bc4d903266bce85b6e9aaedea1d288338c/zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90", size = 5655398 }, + { url = "https://files.pythonhosted.org/packages/f2/61/ac78a1263bc83a5cf29e7458b77a568eda5a8f81980691bbc6eb6a0d45cc/zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35", size = 5191313 }, + { url = "https://files.pythonhosted.org/packages/e7/54/967c478314e16af5baf849b6ee9d6ea724ae5b100eb506011f045d3d4e16/zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d", size = 430877 }, + { url = "https://files.pythonhosted.org/packages/75/37/872d74bd7739639c4553bf94c84af7d54d8211b626b352bc57f0fd8d1e3f/zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b", size = 495595 }, + { url = "https://files.pythonhosted.org/packages/80/f1/8386f3f7c10261fe85fbc2c012fdb3d4db793b921c9abcc995d8da1b7a80/zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9", size = 788975 }, + { url = "https://files.pythonhosted.org/packages/16/e8/cbf01077550b3e5dc86089035ff8f6fbbb312bc0983757c2d1117ebba242/zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a", size = 633448 }, + { url = "https://files.pythonhosted.org/packages/06/27/4a1b4c267c29a464a161aeb2589aff212b4db653a1d96bffe3598f3f0d22/zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2", size = 4945269 }, + { url = "https://files.pythonhosted.org/packages/7c/64/d99261cc57afd9ae65b707e38045ed8269fbdae73544fd2e4a4d50d0ed83/zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5", size = 5306228 }, + { url = "https://files.pythonhosted.org/packages/7a/cf/27b74c6f22541f0263016a0fd6369b1b7818941de639215c84e4e94b2a1c/zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f", size = 5336891 }, + { url = "https://files.pythonhosted.org/packages/fa/18/89ac62eac46b69948bf35fcd90d37103f38722968e2981f752d69081ec4d/zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed", size = 5436310 }, + { url = "https://files.pythonhosted.org/packages/a8/a8/5ca5328ee568a873f5118d5b5f70d1f36c6387716efe2e369010289a5738/zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea", size = 4859912 }, + { url = "https://files.pythonhosted.org/packages/ea/ca/3781059c95fd0868658b1cf0440edd832b942f84ae60685d0cfdb808bca1/zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847", size = 4936946 }, + { url = "https://files.pythonhosted.org/packages/ce/11/41a58986f809532742c2b832c53b74ba0e0a5dae7e8ab4642bf5876f35de/zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171", size = 5466994 }, + { url = "https://files.pythonhosted.org/packages/83/e3/97d84fe95edd38d7053af05159465d298c8b20cebe9ccb3d26783faa9094/zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840", size = 4848681 }, + { url = "https://files.pythonhosted.org/packages/6e/99/cb1e63e931de15c88af26085e3f2d9af9ce53ccafac73b6e48418fd5a6e6/zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690", size = 4694239 }, + { url = "https://files.pythonhosted.org/packages/ab/50/b1e703016eebbc6501fc92f34db7b1c68e54e567ef39e6e59cf5fb6f2ec0/zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b", size = 5200149 }, + { url = "https://files.pythonhosted.org/packages/aa/e0/932388630aaba70197c78bdb10cce2c91fae01a7e553b76ce85471aec690/zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057", size = 5655392 }, + { url = "https://files.pythonhosted.org/packages/02/90/2633473864f67a15526324b007a9f96c96f56d5f32ef2a56cc12f9548723/zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33", size = 5191299 }, + { url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862 }, + { url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578 }, + { url = "https://files.pythonhosted.org/packages/fb/96/4fcafeb7e013a2386d22f974b5b97a0b9a65004ed58c87ae001599bfbd48/zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb", size = 788697 }, + { url = "https://files.pythonhosted.org/packages/83/ff/a52ce725be69b86a2967ecba0497a8184540cc284c0991125515449e54e2/zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916", size = 633679 }, + { url = "https://files.pythonhosted.org/packages/34/0f/3dc62db122f6a9c481c335fff6fc9f4e88d8f6e2d47321ee3937328addb4/zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a", size = 4940416 }, + { url = "https://files.pythonhosted.org/packages/1d/e5/9fe0dd8c85fdc2f635e6660d07872a5dc4b366db566630161e39f9f804e1/zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259", size = 5307693 }, + { url = "https://files.pythonhosted.org/packages/73/bf/fe62c0cd865c171ee8ed5bc83174b5382a2cb729c8d6162edfb99a83158b/zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4", size = 5341236 }, + { url = "https://files.pythonhosted.org/packages/39/86/4fe79b30c794286110802a6cd44a73b6a314ac8196b9338c0fbd78c2407d/zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58", size = 5439101 }, + { url = "https://files.pythonhosted.org/packages/72/ed/cacec235c581ebf8c608c7fb3d4b6b70d1b490d0e5128ea6996f809ecaef/zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15", size = 4860320 }, + { url = "https://files.pythonhosted.org/packages/f6/1e/2c589a2930f93946b132fc852c574a19d5edc23fad2b9e566f431050c7ec/zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269", size = 4931933 }, + { url = "https://files.pythonhosted.org/packages/8e/f5/30eadde3686d902b5d4692bb5f286977cbc4adc082145eb3f49d834b2eae/zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700", size = 5463878 }, + { url = "https://files.pythonhosted.org/packages/e0/c8/8aed1f0ab9854ef48e5ad4431367fcb23ce73f0304f7b72335a8edc66556/zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9", size = 4857192 }, + { url = "https://files.pythonhosted.org/packages/a8/c6/55e666cfbcd032b9e271865e8578fec56e5594d4faeac379d371526514f5/zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69", size = 4696513 }, + { url = "https://files.pythonhosted.org/packages/dc/bd/720b65bea63ec9de0ac7414c33b9baf271c8de8996e5ff324dc93fc90ff1/zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70", size = 5204823 }, + { url = "https://files.pythonhosted.org/packages/d8/40/d678db1556e3941d330cd4e95623a63ef235b18547da98fa184cbc028ecf/zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2", size = 5666490 }, + { url = "https://files.pythonhosted.org/packages/ed/cc/c89329723d7515898a1fc7ef5d251264078548c505719d13e9511800a103/zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5", size = 5196622 }, + { url = "https://files.pythonhosted.org/packages/78/4c/634289d41e094327a94500dfc919e58841b10ea3a9efdfafbac614797ec2/zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274", size = 430620 }, + { url = "https://files.pythonhosted.org/packages/a2/e2/0b0c5a0f4f7699fecd92c1ba6278ef9b01f2b0b0dd46f62bfc6729c05659/zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58", size = 495528 }, ] From c672590f423bab6af905308350ff61b379f86a3e Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 16:57:47 +0200 Subject: [PATCH 22/30] chore(standard-tests): select ALL rules with exclusions (#31937) Co-authored-by: Mason Daugherty --- libs/standard-tests/langchain_tests/base.py | 6 +-- .../langchain_tests/conftest.py | 18 +++++---- .../integration_tests/chat_models.py | 36 ++++++++--------- .../integration_tests/indexer.py | 4 +- .../langchain_tests/utils/pydantic.py | 2 +- libs/standard-tests/pyproject.toml | 39 +++++++++++++++++-- .../tests/integration_tests/__init__.py | 0 .../tests/unit_tests/custom_chat_model.py | 3 ++ .../tests/unit_tests/test_basic_tool.py | 3 ++ .../unit_tests/test_custom_chat_model.py | 6 +-- .../unit_tests/test_in_memory_base_store.py | 5 +++ .../tests/unit_tests/test_in_memory_cache.py | 3 ++ 12 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 libs/standard-tests/tests/integration_tests/__init__.py diff --git a/libs/standard-tests/langchain_tests/base.py b/libs/standard-tests/langchain_tests/base.py index 0f9156673c1..1afd1e379ae 100644 --- a/libs/standard-tests/langchain_tests/base.py +++ b/libs/standard-tests/langchain_tests/base.py @@ -1,15 +1,13 @@ """Standard tests.""" -from abc import ABC - -class BaseStandardTests(ABC): +class BaseStandardTests: """Base class for standard tests. :private: """ - def test_no_overrides_DO_NOT_OVERRIDE(self) -> None: + def test_no_overrides_DO_NOT_OVERRIDE(self) -> None: # noqa: N802 """Test that no standard tests are overridden. :private: diff --git a/libs/standard-tests/langchain_tests/conftest.py b/libs/standard-tests/langchain_tests/conftest.py index fb441f65f36..8b6b61cda24 100644 --- a/libs/standard-tests/langchain_tests/conftest.py +++ b/libs/standard-tests/langchain_tests/conftest.py @@ -3,7 +3,7 @@ import gzip from os import PathLike from pathlib import Path -from typing import Any, Union +from typing import Any, Union, cast import pytest import yaml @@ -27,7 +27,13 @@ class CustomSerializer: def serialize(cassette_dict: dict) -> bytes: """Convert cassette to YAML and compress it.""" cassette_dict["requests"] = [ - request._to_dict() for request in cassette_dict["requests"] + { + "method": request.method, + "uri": request.uri, + "body": request.body, + "headers": {k: [v] for k, v in request.headers.items()}, + } + for request in cassette_dict["requests"] ] yml = yaml.safe_dump(cassette_dict) return gzip.compress(yml.encode("utf-8")) @@ -35,11 +41,9 @@ class CustomSerializer: @staticmethod def deserialize(data: bytes) -> dict: """Decompress data and convert it from YAML.""" - text = gzip.decompress(data).decode("utf-8") - cassette: dict[str, Any] = yaml.safe_load(text) - cassette["requests"] = [ - Request._from_dict(request) for request in cassette["requests"] - ] + decoded_yaml = gzip.decompress(data).decode("utf-8") + cassette = cast("dict[str, Any]", yaml.safe_load(decoded_yaml)) + cassette["requests"] = [Request(**request) for request in cassette["requests"]] return cassette diff --git a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py index dce989b3a6a..bf7240c2971 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py +++ b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py @@ -30,14 +30,14 @@ from pydantic import BaseModel, Field from pydantic.v1 import BaseModel as BaseModelV1 from pydantic.v1 import Field as FieldV1 from pytest_benchmark.fixture import BenchmarkFixture # type: ignore[import-untyped] -from typing_extensions import TypedDict +from typing_extensions import TypedDict, override from vcr.cassette import Cassette from langchain_tests.unit_tests.chat_models import ChatModelTests from langchain_tests.utils.pydantic import PYDANTIC_MAJOR_VERSION -def _get_joke_class( +def _get_joke_class( # noqa: RET503 schema_type: Literal["pydantic", "typeddict", "json_schema"], ) -> Any: class Joke(BaseModel): @@ -56,7 +56,7 @@ def _get_joke_class( punchline: Annotated[str, ..., "answer to resolve the joke"] def validate_joke_dict(result: Any) -> bool: - return all(key in ["setup", "punchline"] for key in result) + return all(key in {"setup", "punchline"} for key in result) if schema_type == "pydantic": return Joke, validate_joke @@ -75,6 +75,7 @@ class _TestCallbackHandler(BaseCallbackHandler): super().__init__() self.options = [] + @override def on_chat_model_start( self, serialized: Any, @@ -1042,7 +1043,7 @@ class ChatModelIntegrationTests(ChatModelTests): # Needed for langchain_core.callbacks.usage model_name = result.response_metadata.get("model_name") assert isinstance(model_name, str) - assert model_name != "", "model_name is empty" + assert model_name, "model_name is empty" # `input_tokens` is the total, possibly including other unclassified or # system-level tokens. @@ -1056,10 +1057,9 @@ class ChatModelIntegrationTests(ChatModelTests): ) is not None assert isinstance(input_token_details.get("audio"), int) # Asserts that total input tokens are at least the sum of the token counts - total_detailed_tokens = sum( + assert usage_metadata.get("input_tokens", 0) >= sum( v for v in input_token_details.values() if isinstance(v, int) ) - assert usage_metadata.get("input_tokens", 0) >= total_detailed_tokens if "audio_output" in self.supported_usage_metadata_details["invoke"]: msg = self.invoke_with_audio_output() assert (usage_metadata := msg.usage_metadata) is not None @@ -1068,10 +1068,9 @@ class ChatModelIntegrationTests(ChatModelTests): ) is not None assert isinstance(output_token_details.get("audio"), int) # Asserts that total output tokens are at least the sum of the token counts - total_detailed_tokens = sum( + assert usage_metadata.get("output_tokens", 0) >= sum( v for v in output_token_details.values() if isinstance(v, int) ) - assert usage_metadata.get("output_tokens", 0) >= total_detailed_tokens if "reasoning_output" in self.supported_usage_metadata_details["invoke"]: msg = self.invoke_with_reasoning_output() assert (usage_metadata := msg.usage_metadata) is not None @@ -1080,10 +1079,9 @@ class ChatModelIntegrationTests(ChatModelTests): ) is not None assert isinstance(output_token_details.get("reasoning"), int) # Asserts that total output tokens are at least the sum of the token counts - total_detailed_tokens = sum( + assert usage_metadata.get("output_tokens", 0) >= sum( v for v in output_token_details.values() if isinstance(v, int) ) - assert usage_metadata.get("output_tokens", 0) >= total_detailed_tokens if "cache_read_input" in self.supported_usage_metadata_details["invoke"]: msg = self.invoke_with_cache_read_input() assert (usage_metadata := msg.usage_metadata) is not None @@ -1092,10 +1090,9 @@ class ChatModelIntegrationTests(ChatModelTests): ) is not None assert isinstance(input_token_details.get("cache_read"), int) # Asserts that total input tokens are at least the sum of the token counts - total_detailed_tokens = sum( + assert usage_metadata.get("input_tokens", 0) >= sum( v for v in input_token_details.values() if isinstance(v, int) ) - assert usage_metadata.get("input_tokens", 0) >= total_detailed_tokens if "cache_creation_input" in self.supported_usage_metadata_details["invoke"]: msg = self.invoke_with_cache_creation_input() assert (usage_metadata := msg.usage_metadata) is not None @@ -1104,10 +1101,9 @@ class ChatModelIntegrationTests(ChatModelTests): ) is not None assert isinstance(input_token_details.get("cache_creation"), int) # Asserts that total input tokens are at least the sum of the token counts - total_detailed_tokens = sum( + assert usage_metadata.get("input_tokens", 0) >= sum( v for v in input_token_details.values() if isinstance(v, int) ) - assert usage_metadata.get("input_tokens", 0) >= total_detailed_tokens def test_usage_metadata_streaming(self, model: BaseChatModel) -> None: """Test usage metadata in streaming mode. @@ -1235,7 +1231,7 @@ class ChatModelIntegrationTests(ChatModelTests): # Needed for langchain_core.callbacks.usage model_name = full.response_metadata.get("model_name") assert isinstance(model_name, str) - assert model_name != "", "model_name is empty" + assert model_name, "model_name is empty" if "audio_input" in self.supported_usage_metadata_details["stream"]: msg = self.invoke_with_audio_input(stream=True) @@ -1720,7 +1716,7 @@ class ChatModelIntegrationTests(ChatModelTests): pytest.skip("Test requires tool choice.") @tool - def get_weather(location: str) -> str: + def get_weather(location: str) -> str: # noqa: ARG001 """Get weather at a location.""" return "It's sunny." @@ -2130,7 +2126,7 @@ class ChatModelIntegrationTests(ChatModelTests): See `example implementation `__ of ``with_structured_output``. - """ # noqa: E501 + """ if not self.has_structured_output: pytest.skip("Test requires structured output.") @@ -2262,8 +2258,8 @@ class ChatModelIntegrationTests(ChatModelTests): if not self.supports_json_mode: pytest.skip("Test requires json mode support.") - from pydantic import BaseModel as BaseModelProper - from pydantic import Field as FieldProper + from pydantic import BaseModel as BaseModelProper # noqa: PLC0415 + from pydantic import Field as FieldProper # noqa: PLC0415 class Joke(BaseModelProper): """Joke to tell user.""" @@ -2912,7 +2908,7 @@ class ChatModelIntegrationTests(ChatModelTests): pytest.skip("Test requires tool calling.") @tool - def get_weather(location: str) -> str: + def get_weather(location: str) -> str: # noqa: ARG001 """Call to surf the web.""" return "It's sunny." diff --git a/libs/standard-tests/langchain_tests/integration_tests/indexer.py b/libs/standard-tests/langchain_tests/integration_tests/indexer.py index 4a887b5c8ad..94378a45d6c 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/indexer.py +++ b/libs/standard-tests/langchain_tests/integration_tests/indexer.py @@ -175,7 +175,7 @@ class DocumentIndexerTestSuite(ABC): def test_delete_no_args(self, index: DocumentIndex) -> None: """Test delete with no args raises ValueError.""" - with pytest.raises(ValueError): + with pytest.raises(ValueError): # noqa: PT011 index.delete() def test_delete_missing_content(self, index: DocumentIndex) -> None: @@ -367,7 +367,7 @@ class AsyncDocumentIndexTestSuite(ABC): async def test_delete_no_args(self, index: DocumentIndex) -> None: """Test delete with no args raises ValueError.""" - with pytest.raises(ValueError): + with pytest.raises(ValueError): # noqa: PT011 await index.adelete() async def test_delete_missing_content(self, index: DocumentIndex) -> None: diff --git a/libs/standard-tests/langchain_tests/utils/pydantic.py b/libs/standard-tests/langchain_tests/utils/pydantic.py index 34cfce3c2ab..6a6e7ba0ed2 100644 --- a/libs/standard-tests/langchain_tests/utils/pydantic.py +++ b/libs/standard-tests/langchain_tests/utils/pydantic.py @@ -7,7 +7,7 @@ def get_pydantic_major_version() -> int: """Get the major version of Pydantic.""" try: - import pydantic + import pydantic # noqa: PLC0415 return int(pydantic.__version__.split(".")[0]) except ImportError: diff --git a/libs/standard-tests/pyproject.toml b/libs/standard-tests/pyproject.toml index 613ab8c315f..53c33258664 100644 --- a/libs/standard-tests/pyproject.toml +++ b/libs/standard-tests/pyproject.toml @@ -59,14 +59,45 @@ ignore_missing_imports = true target-version = "py39" [tool.ruff.lint] -select = ["D", "E", "F", "I", "PGH", "T201", "UP",] -pyupgrade.keep-runtime-typing = true +select = [ "ALL",] +ignore = [ + "C90", # McCabe complexity + "COM812", # Messes with the formatter + "FA100", # Can't activate since we exclude UP007 for now + "FIX002", # Line contains TODO + "ISC001", # Messes with the formatter + "PERF203", # Rarely useful + "PLR2004", # Magic numbers + "PLR09", # Too many something (arg, statements, etc) + "RUF012", # Doesn't play well with Pydantic + "S101", # Asserts allowed in tests + "S311", # No need for strong crypto in tests + "SLF001", # Tests may call private methods + "TC001", # Doesn't play well with Pydantic + "TC002", # Doesn't play well with Pydantic + "TC003", # Doesn't play well with Pydantic + "TD002", # Missing author in TODO + "TD003", # Missing issue link in TODO -[tool.ruff.lint.pydocstyle] -convention = "google" + # TODO rules + "ANN401", + "BLE", +] +unfixable = [ + "B028", # People should intentionally tune the stacklevel + "PLW1510", # People should intentionally set the check argument +] + +flake8-annotations.allow-star-arg-any = true +flake8-annotations.mypy-init-return = true +flake8-type-checking.runtime-evaluated-base-classes = ["pydantic.BaseModel","langchain_core.load.serializable.Serializable","langchain_core.runnables.base.RunnableSerializable"] +pep8-naming.classmethod-decorators = [ "classmethod", "langchain_core.utils.pydantic.pre_init", "pydantic.field_validator", "pydantic.v1.root_validator",] +pydocstyle.convention = "google" +pyupgrade.keep-runtime-typing = true [tool.ruff.lint.per-file-ignores] "tests/**" = [ "D1",] +"scripts/**" = [ "INP",] [tool.coverage.run] omit = ["tests/*"] diff --git a/libs/standard-tests/tests/integration_tests/__init__.py b/libs/standard-tests/tests/integration_tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libs/standard-tests/tests/unit_tests/custom_chat_model.py b/libs/standard-tests/tests/unit_tests/custom_chat_model.py index d8f9f7c668f..f91786aa62c 100644 --- a/libs/standard-tests/tests/unit_tests/custom_chat_model.py +++ b/libs/standard-tests/tests/unit_tests/custom_chat_model.py @@ -7,6 +7,7 @@ from langchain_core.messages import AIMessage, AIMessageChunk, BaseMessage from langchain_core.messages.ai import UsageMetadata from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult from pydantic import Field +from typing_extensions import override class ChatParrotLink(BaseChatModel): @@ -41,6 +42,7 @@ class ChatParrotLink(BaseChatModel): stop: Optional[list[str]] = None max_retries: int = 2 + @override def _generate( self, messages: list[BaseMessage], @@ -92,6 +94,7 @@ class ChatParrotLink(BaseChatModel): generation = ChatGeneration(message=message) return ChatResult(generations=[generation]) + @override def _stream( self, messages: list[BaseMessage], diff --git a/libs/standard-tests/tests/unit_tests/test_basic_tool.py b/libs/standard-tests/tests/unit_tests/test_basic_tool.py index 1439e414316..d7ab342f043 100644 --- a/libs/standard-tests/tests/unit_tests/test_basic_tool.py +++ b/libs/standard-tests/tests/unit_tests/test_basic_tool.py @@ -1,6 +1,7 @@ from typing import Literal from langchain_core.tools import BaseTool +from typing_extensions import override from langchain_tests.integration_tests import ToolsIntegrationTests from langchain_tests.unit_tests import ToolsUnitTests @@ -12,6 +13,7 @@ class ParrotMultiplyTool(BaseTool): "Multiply two numbers like a parrot. Parrots always add eighty for their matey." ) + @override def _run(self, a: int, b: int) -> int: return a * b + 80 @@ -23,6 +25,7 @@ class ParrotMultiplyArtifactTool(BaseTool): ) response_format: Literal["content_and_artifact"] = "content_and_artifact" + @override def _run(self, a: int, b: int) -> tuple[int, str]: return a * b + 80, "parrot artifact" diff --git a/libs/standard-tests/tests/unit_tests/test_custom_chat_model.py b/libs/standard-tests/tests/unit_tests/test_custom_chat_model.py index ac821bd77dc..36ccb1d256a 100644 --- a/libs/standard-tests/tests/unit_tests/test_custom_chat_model.py +++ b/libs/standard-tests/tests/unit_tests/test_custom_chat_model.py @@ -1,9 +1,8 @@ """Test the standard tests on the custom chat model in the docs.""" -from typing import Optional - import pytest from langchain_core.language_models.chat_models import BaseChatModel +from typing_extensions import Any from langchain_tests.integration_tests import ChatModelIntegrationTests from langchain_tests.unit_tests import ChatModelUnitTests @@ -34,7 +33,6 @@ class TestChatParrotLinkIntegration(ChatModelIntegrationTests): def test_unicode_tool_call_integration( self, model: BaseChatModel, - tool_choice: Optional[str] = None, - force_tool_call: bool = True, + **_: Any, ) -> None: """Expected failure as ChatParrotLink doesn't support tool calling yet.""" diff --git a/libs/standard-tests/tests/unit_tests/test_in_memory_base_store.py b/libs/standard-tests/tests/unit_tests/test_in_memory_base_store.py index 7349d3ffc5e..42fe15cbf90 100644 --- a/libs/standard-tests/tests/unit_tests/test_in_memory_base_store.py +++ b/libs/standard-tests/tests/unit_tests/test_in_memory_base_store.py @@ -2,6 +2,7 @@ import pytest from langchain_core.stores import InMemoryStore +from typing_extensions import override from langchain_tests.integration_tests.base_store import ( BaseStoreAsyncTests, @@ -11,19 +12,23 @@ from langchain_tests.integration_tests.base_store import ( class TestInMemoryStore(BaseStoreSyncTests[str]): @pytest.fixture + @override def three_values(self) -> tuple[str, str, str]: return "foo", "bar", "buzz" @pytest.fixture + @override def kv_store(self) -> InMemoryStore: return InMemoryStore() class TestInMemoryStoreAsync(BaseStoreAsyncTests[str]): @pytest.fixture + @override def three_values(self) -> tuple[str, str, str]: return "foo", "bar", "buzz" @pytest.fixture + @override async def kv_store(self) -> InMemoryStore: return InMemoryStore() diff --git a/libs/standard-tests/tests/unit_tests/test_in_memory_cache.py b/libs/standard-tests/tests/unit_tests/test_in_memory_cache.py index 6c1a1647ade..5d5e67df04d 100644 --- a/libs/standard-tests/tests/unit_tests/test_in_memory_cache.py +++ b/libs/standard-tests/tests/unit_tests/test_in_memory_cache.py @@ -1,5 +1,6 @@ import pytest from langchain_core.caches import InMemoryCache +from typing_extensions import override from langchain_tests.integration_tests.cache import ( AsyncCacheTestSuite, @@ -9,11 +10,13 @@ from langchain_tests.integration_tests.cache import ( class TestInMemoryCache(SyncCacheTestSuite): @pytest.fixture + @override def cache(self) -> InMemoryCache: return InMemoryCache() class TestInMemoryCacheAsync(AsyncCacheTestSuite): @pytest.fixture + @override async def cache(self) -> InMemoryCache: return InMemoryCache() From e3b6c9bb66a985aa5f923ed33722129bd19ac888 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 17:02:08 +0200 Subject: [PATCH 23/30] chore(core): fix some mypy `warn_unreachable` issues (#32560) Found by setting `warn_unreachable: true` in mypy. --------- Co-authored-by: Mason Daugherty --- libs/core/langchain_core/globals.py | 2 +- .../langchain_core/language_models/llms.py | 1 + libs/core/langchain_core/messages/utils.py | 2 +- .../langchain_core/output_parsers/json.py | 4 +--- libs/core/langchain_core/prompts/few_shot.py | 2 +- libs/core/langchain_core/runnables/base.py | 9 ++++++--- libs/core/langchain_core/tools/base.py | 10 +++++----- libs/core/langchain_core/utils/json.py | 4 ++-- libs/core/langchain_core/utils/json_schema.py | 9 ++++++--- .../unit_tests/runnables/test_fallbacks.py | 16 +++++++-------- .../runnables/test_tracing_interops.py | 2 +- libs/core/uv.lock | 20 ++++--------------- 12 files changed, 37 insertions(+), 44 deletions(-) diff --git a/libs/core/langchain_core/globals.py b/libs/core/langchain_core/globals.py index 77375a2d076..faf26578f35 100644 --- a/libs/core/langchain_core/globals.py +++ b/libs/core/langchain_core/globals.py @@ -191,7 +191,7 @@ def set_llm_cache(value: Optional["BaseCache"]) -> None: _llm_cache = value -def get_llm_cache() -> "BaseCache": +def get_llm_cache() -> Optional["BaseCache"]: """Get the value of the `llm_cache` global setting. Returns: diff --git a/libs/core/langchain_core/language_models/llms.py b/libs/core/langchain_core/language_models/llms.py index 5c24d516e7d..10a5f06121f 100644 --- a/libs/core/langchain_core/language_models/llms.py +++ b/libs/core/langchain_core/language_models/llms.py @@ -131,6 +131,7 @@ def create_base_retry_decorator( def _resolve_cache(*, cache: Union[BaseCache, bool, None]) -> Optional[BaseCache]: """Resolve the cache.""" + llm_cache: Optional[BaseCache] if isinstance(cache, BaseCache): llm_cache = cache elif cache is None: diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index e84dc6c0191..2796707aa24 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -182,7 +182,7 @@ def messages_from_dict(messages: Sequence[dict]) -> list[BaseMessage]: return [_message_from_dict(m) for m in messages] -def message_chunk_to_message(chunk: BaseMessageChunk) -> BaseMessage: +def message_chunk_to_message(chunk: BaseMessage) -> BaseMessage: """Convert a message chunk to a message. Args: diff --git a/libs/core/langchain_core/output_parsers/json.py b/libs/core/langchain_core/output_parsers/json.py index 8d8e4d52765..54577037759 100644 --- a/libs/core/langchain_core/output_parsers/json.py +++ b/libs/core/langchain_core/output_parsers/json.py @@ -49,9 +49,7 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]): def _get_schema(self, pydantic_object: type[TBaseModel]) -> dict[str, Any]: if issubclass(pydantic_object, pydantic.BaseModel): return pydantic_object.model_json_schema() - if issubclass(pydantic_object, pydantic.v1.BaseModel): - return pydantic_object.schema() - return None + return pydantic_object.schema() def parse_result(self, result: list[Generation], *, partial: bool = False) -> Any: """Parse the result of an LLM call to a JSON object. diff --git a/libs/core/langchain_core/prompts/few_shot.py b/libs/core/langchain_core/prompts/few_shot.py index 1b42dcdc9c4..a1d237e66cf 100644 --- a/libs/core/langchain_core/prompts/few_shot.py +++ b/libs/core/langchain_core/prompts/few_shot.py @@ -153,7 +153,7 @@ class FewShotPromptTemplate(_FewShotPromptTemplateMixin, StringPromptTemplate): self.template_format, self.input_variables + list(self.partial_variables), ) - elif self.template_format or None: + elif self.template_format: self.input_variables = [ var for var in get_template_variables( diff --git a/libs/core/langchain_core/runnables/base.py b/libs/core/langchain_core/runnables/base.py index 7b872783909..4da0a484415 100644 --- a/libs/core/langchain_core/runnables/base.py +++ b/libs/core/langchain_core/runnables/base.py @@ -5204,10 +5204,13 @@ class RunnableEachBase(RunnableSerializable[list[Input], list[Output]]): config: Optional[RunnableConfig] = None, **kwargs: Optional[Any], ) -> AsyncIterator[StreamEvent]: + def _error_stream_event(message: str) -> StreamEvent: + raise NotImplementedError(message) + for _ in range(1): - msg = "RunnableEach does not support astream_events yet." - raise NotImplementedError(msg) - yield + yield _error_stream_event( + "RunnableEach does not support astream_events yet." + ) class RunnableEach(RunnableEachBase[Input, Output]): diff --git a/libs/core/langchain_core/tools/base.py b/libs/core/langchain_core/tools/base.py index 34ca4b4da30..e93cb74dc6b 100644 --- a/libs/core/langchain_core/tools/base.py +++ b/libs/core/langchain_core/tools/base.py @@ -1285,7 +1285,7 @@ class InjectedToolCallId(InjectedToolArg): def _is_injected_arg_type( - type_: type, injected_type: Optional[type[InjectedToolArg]] = None + type_: Union[type, TypeVar], injected_type: Optional[type[InjectedToolArg]] = None ) -> bool: """Check if a type annotation indicates an injected argument. @@ -1306,7 +1306,7 @@ def _is_injected_arg_type( def get_all_basemodel_annotations( cls: Union[TypeBaseModel, Any], *, default_to_bound: bool = True -) -> dict[str, type]: +) -> dict[str, Union[type, TypeVar]]: """Get all annotations from a Pydantic BaseModel and its parents. Args: @@ -1319,7 +1319,7 @@ def get_all_basemodel_annotations( fields = getattr(cls, "model_fields", {}) or getattr(cls, "__fields__", {}) alias_map = {field.alias: name for name, field in fields.items() if field.alias} - annotations: dict[str, type] = {} + annotations: dict[str, Union[type, TypeVar]] = {} for name, param in inspect.signature(cls).parameters.items(): # Exclude hidden init args added by pydantic Config. For example if # BaseModel(extra="allow") then "extra_data" will part of init sig. @@ -1373,11 +1373,11 @@ def get_all_basemodel_annotations( def _replace_type_vars( - type_: type, + type_: Union[type, TypeVar], generic_map: Optional[dict[TypeVar, type]] = None, *, default_to_bound: bool = True, -) -> type: +) -> Union[type, TypeVar]: """Replace TypeVars in a type annotation with concrete types. Args: diff --git a/libs/core/langchain_core/utils/json.py b/libs/core/langchain_core/utils/json.py index 4b12e85fe99..98450587e1c 100644 --- a/libs/core/langchain_core/utils/json.py +++ b/libs/core/langchain_core/utils/json.py @@ -4,7 +4,7 @@ from __future__ import annotations import json import re -from typing import Any, Callable +from typing import Any, Callable, Union from langchain_core.exceptions import OutputParserException @@ -19,7 +19,7 @@ def _replace_new_line(match: re.Match[str]) -> str: return match.group(1) + value + match.group(3) -def _custom_parser(multiline_string: str) -> str: +def _custom_parser(multiline_string: Union[str, bytes, bytearray]) -> str: r"""Custom parser for multiline strings. The LLM response for `action_input` may be a multiline diff --git a/libs/core/langchain_core/utils/json_schema.py b/libs/core/langchain_core/utils/json_schema.py index 70cea60d094..5463c245b41 100644 --- a/libs/core/langchain_core/utils/json_schema.py +++ b/libs/core/langchain_core/utils/json_schema.py @@ -3,13 +3,13 @@ from __future__ import annotations from copy import deepcopy -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any, Optional, Union if TYPE_CHECKING: from collections.abc import Sequence -def _retrieve_ref(path: str, schema: dict) -> dict: +def _retrieve_ref(path: str, schema: dict) -> Union[list, dict]: components = path.split("/") if components[0] != "#": msg = ( @@ -17,9 +17,12 @@ def _retrieve_ref(path: str, schema: dict) -> dict: "with #." ) raise ValueError(msg) - out = schema + out: Union[list, dict] = schema for component in components[1:]: if component in out: + if isinstance(out, list): + msg = f"Reference '{path}' not found." + raise KeyError(msg) out = out[component] elif component.isdigit(): index = int(component) diff --git a/libs/core/tests/unit_tests/runnables/test_fallbacks.py b/libs/core/tests/unit_tests/runnables/test_fallbacks.py index 3985facc544..c2e1c1af865 100644 --- a/libs/core/tests/unit_tests/runnables/test_fallbacks.py +++ b/libs/core/tests/unit_tests/runnables/test_fallbacks.py @@ -264,16 +264,18 @@ def _generate(_: Iterator) -> Iterator[str]: yield from "foo bar" -def _generate_immediate_error(_: Iterator) -> Iterator[str]: - msg = "immmediate error" +def _error(msg: str) -> None: raise ValueError(msg) + + +def _generate_immediate_error(_: Iterator) -> Iterator[str]: + _error("immmediate error") yield "" def _generate_delayed_error(_: Iterator) -> Iterator[str]: yield "" - msg = "delayed error" - raise ValueError(msg) + _error("delayed error") def test_fallbacks_stream() -> None: @@ -295,15 +297,13 @@ async def _agenerate(_: AsyncIterator) -> AsyncIterator[str]: async def _agenerate_immediate_error(_: AsyncIterator) -> AsyncIterator[str]: - msg = "immmediate error" - raise ValueError(msg) + _error("immediate error") yield "" async def _agenerate_delayed_error(_: AsyncIterator) -> AsyncIterator[str]: yield "" - msg = "delayed error" - raise ValueError(msg) + _error("delayed error") async def test_fallbacks_astream() -> None: diff --git a/libs/core/tests/unit_tests/runnables/test_tracing_interops.py b/libs/core/tests/unit_tests/runnables/test_tracing_interops.py index 08a846827f3..2db895355ed 100644 --- a/libs/core/tests/unit_tests/runnables/test_tracing_interops.py +++ b/libs/core/tests/unit_tests/runnables/test_tracing_interops.py @@ -221,7 +221,7 @@ async def test_config_traceable_async_handoff() -> None: @pytest.mark.parametrize("enabled", [None, True, False]) @pytest.mark.parametrize("env", ["", "true"]) def test_tracing_enable_disable( - mock_get_client: MagicMock, *, enabled: bool, env: str + mock_get_client: MagicMock, *, enabled: Optional[bool], env: str ) -> None: mock_session = MagicMock() mock_client_ = Client( diff --git a/libs/core/uv.lock b/libs/core/uv.lock index 4da17732050..a4bb351a562 100644 --- a/libs/core/uv.lock +++ b/libs/core/uv.lock @@ -1134,7 +1134,7 @@ typing = [ [[package]] name = "langchain-tests" -version = "0.3.20" +version = "0.3.21" source = { directory = "../standard-tests" } dependencies = [ { name = "httpx" }, @@ -1179,18 +1179,14 @@ typing = [ [[package]] name = "langchain-text-splitters" -version = "0.3.9" +version = "0.3.11" source = { directory = "../text-splitters" } dependencies = [ { name = "langchain-core" }, - { name = "pip" }, ] [package.metadata] -requires-dist = [ - { name = "langchain-core", editable = "." }, - { name = "pip", specifier = ">=25.2" }, -] +requires-dist = [{ name = "langchain-core", editable = "." }] [package.metadata.requires-dev] dev = [ @@ -1212,6 +1208,7 @@ test = [ { name = "pytest-xdist", specifier = ">=3.6.1,<4.0.0" }, ] test-integration = [ + { name = "en-core-web-sm", url = "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl" }, { name = "nltk", specifier = ">=3.9.1,<4.0.0" }, { name = "sentence-transformers", specifier = ">=3.0.1" }, { name = "spacy", specifier = ">=3.8.7,<4.0.0" }, @@ -1997,15 +1994,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, ] -[[package]] -name = "pip" -version = "25.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/16/650289cd3f43d5a2fadfd98c68bd1e1e7f2550a1a5326768cddfbcedb2c5/pip-25.2.tar.gz", hash = "sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2", size = 1840021, upload-time = "2025-07-30T21:50:15.401Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/3f/945ef7ab14dc4f9d7f40288d2df998d1837ee0888ec3659c813487572faa/pip-25.2-py3-none-any.whl", hash = "sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717", size = 1752557, upload-time = "2025-07-30T21:50:13.323Z" }, -] - [[package]] name = "platformdirs" version = "4.3.8" From 5840dad40ba0d1c1be7513a59ac381327ff3e7c9 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 17:13:50 +0200 Subject: [PATCH 24/30] chore(core): enable ruff docstring-code-format (#32834) See https://docs.astral.sh/ruff/settings/#format_docstring-code-format --------- Co-authored-by: Mason Daugherty --- libs/core/langchain_core/_api/deprecation.py | 2 +- libs/core/langchain_core/agents.py | 8 +- .../langchain_core/beta/runnables/context.py | 3 +- libs/core/langchain_core/callbacks/base.py | 13 +- libs/core/langchain_core/callbacks/manager.py | 52 +++- libs/core/langchain_core/documents/base.py | 5 +- .../langchain_core/documents/transformers.py | 6 +- libs/core/langchain_core/embeddings/fake.py | 2 + libs/core/langchain_core/indexing/base.py | 2 +- .../language_models/__init__.py | 5 +- .../language_models/chat_models.py | 27 +- libs/core/langchain_core/memory.py | 10 +- libs/core/langchain_core/messages/ai.py | 14 +- libs/core/langchain_core/messages/human.py | 8 +- libs/core/langchain_core/messages/system.py | 8 +- libs/core/langchain_core/messages/tool.py | 19 +- libs/core/langchain_core/messages/utils.py | 182 ++++++++--- .../langchain_core/output_parsers/base.py | 7 +- libs/core/langchain_core/prompts/chat.py | 111 ++++--- libs/core/langchain_core/prompts/few_shot.py | 14 +- .../core/langchain_core/prompts/structured.py | 2 + libs/core/langchain_core/rate_limiters.py | 4 +- libs/core/langchain_core/retrievers.py | 7 +- libs/core/langchain_core/runnables/base.py | 291 +++++++++++------- libs/core/langchain_core/runnables/branch.py | 4 +- .../langchain_core/runnables/configurable.py | 33 +- .../langchain_core/runnables/fallbacks.py | 18 +- libs/core/langchain_core/runnables/history.py | 58 ++-- .../langchain_core/runnables/passthrough.py | 45 +-- libs/core/langchain_core/runnables/retry.py | 14 +- libs/core/langchain_core/runnables/schema.py | 2 + libs/core/langchain_core/stores.py | 18 +- libs/core/langchain_core/sys_info.py | 6 +- libs/core/langchain_core/tools/convert.py | 13 +- .../langchain_core/utils/function_calling.py | 7 +- libs/core/langchain_core/vectorstores/base.py | 12 +- .../langchain_core/vectorstores/in_memory.py | 9 +- libs/core/pyproject.toml | 2 + libs/core/tests/unit_tests/conftest.py | 3 +- .../prompts/__snapshots__/test_chat.ambr | 70 ++--- .../runnables/__snapshots__/test_graph.ambr | 35 +-- .../__snapshots__/test_runnable.ambr | 280 ++++++----------- .../unit_tests/runnables/test_runnable.py | 9 +- libs/core/uv.lock | 6 +- libs/langchain_v1/langchain/__init__.py | 2 +- 45 files changed, 797 insertions(+), 651 deletions(-) diff --git a/libs/core/langchain_core/_api/deprecation.py b/libs/core/langchain_core/_api/deprecation.py index 195812236c6..dc83afa2d17 100644 --- a/libs/core/langchain_core/_api/deprecation.py +++ b/libs/core/langchain_core/_api/deprecation.py @@ -133,7 +133,7 @@ def deprecated( .. code-block:: python - @deprecated('1.4.0') + @deprecated("1.4.0") def the_function_to_deprecate(): pass diff --git a/libs/core/langchain_core/agents.py b/libs/core/langchain_core/agents.py index 74bfcdd4012..8fa3fde3888 100644 --- a/libs/core/langchain_core/agents.py +++ b/libs/core/langchain_core/agents.py @@ -14,13 +14,15 @@ Agents use language models to choose a sequence of actions to take. A basic agent works in the following manner: -1. Given a prompt an agent uses an LLM to request an action to take (e.g., a tool to run). +1. Given a prompt an agent uses an LLM to request an action to take + (e.g., a tool to run). 2. The agent executes the action (e.g., runs the tool), and receives an observation. -3. The agent returns the observation to the LLM, which can then be used to generate the next action. +3. The agent returns the observation to the LLM, which can then be used to generate + the next action. 4. When the agent reaches a stopping condition, it returns a final return value. The schemas for the agents themselves are defined in langchain.agents.agent. -""" # noqa: E501 +""" from __future__ import annotations diff --git a/libs/core/langchain_core/beta/runnables/context.py b/libs/core/langchain_core/beta/runnables/context.py index 993b4665b2b..00d5e936bba 100644 --- a/libs/core/langchain_core/beta/runnables/context.py +++ b/libs/core/langchain_core/beta/runnables/context.py @@ -344,8 +344,7 @@ class Context: chain = ( Context.setter("input") | { - "context": RunnablePassthrough() - | Context.setter("context"), + "context": RunnablePassthrough() | Context.setter("context"), "question": RunnablePassthrough(), } | PromptTemplate.from_template("{context} {question}") diff --git a/libs/core/langchain_core/callbacks/base.py b/libs/core/langchain_core/callbacks/base.py index 5365fcb9ef1..68c4e4a254b 100644 --- a/libs/core/langchain_core/callbacks/base.py +++ b/libs/core/langchain_core/callbacks/base.py @@ -947,11 +947,18 @@ class BaseCallbackManager(CallbackManagerMixin): .. code-block:: python - from langchain_core.callbacks.manager import CallbackManager, trace_as_chain_group + from langchain_core.callbacks.manager import ( + CallbackManager, + trace_as_chain_group, + ) from langchain_core.callbacks.stdout import StdOutCallbackHandler - manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"]) - with trace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager: + manager = CallbackManager( + handlers=[StdOutCallbackHandler()], tags=["tag2"] + ) + with trace_as_chain_group( + "My Group Name", tags=["tag1"] + ) as group_manager: merged_manager = group_manager.merge(manager) print(merged_manager.handlers) # [ diff --git a/libs/core/langchain_core/callbacks/manager.py b/libs/core/langchain_core/callbacks/manager.py index 90009fd5a0f..8498995f86d 100644 --- a/libs/core/langchain_core/callbacks/manager.py +++ b/libs/core/langchain_core/callbacks/manager.py @@ -85,7 +85,8 @@ def trace_as_chain_group( Defaults to None. .. note: - Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in LangSmith. + Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in + LangSmith. Returns: CallbackManagerForChainGroup: The callback manager for the chain group. @@ -94,12 +95,14 @@ def trace_as_chain_group( .. code-block:: python llm_input = "Foo" - with trace_as_chain_group("group_name", inputs={"input": llm_input}) as manager: + with trace_as_chain_group( + "group_name", inputs={"input": llm_input} + ) as manager: # Use the callback manager for the chain group res = llm.invoke(llm_input, {"callbacks": manager}) manager.on_chain_end({"output": res}) - """ # noqa: E501 + """ from langchain_core.tracers.context import _get_trace_callbacks cb = _get_trace_callbacks( @@ -153,8 +156,8 @@ async def atrace_as_chain_group( Args: group_name (str): The name of the chain group. - callback_manager (AsyncCallbackManager, optional): The async callback manager to use, - which manages tracing and other callback behavior. Defaults to None. + callback_manager (AsyncCallbackManager, optional): The async callback manager + to use, which manages tracing and other callback behavior. Defaults to None. inputs (dict[str, Any], optional): The inputs to the chain group. Defaults to None. project_name (str, optional): The name of the project. @@ -171,18 +174,21 @@ async def atrace_as_chain_group( AsyncCallbackManager: The async callback manager for the chain group. .. note: - Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in LangSmith. + Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in + LangSmith. Example: .. code-block:: python llm_input = "Foo" - async with atrace_as_chain_group("group_name", inputs={"input": llm_input}) as manager: + async with atrace_as_chain_group( + "group_name", inputs={"input": llm_input} + ) as manager: # Use the async callback manager for the chain group res = await llm.ainvoke(llm_input, {"callbacks": manager}) await manager.on_chain_end({"output": res}) - """ # noqa: E501 + """ from langchain_core.tracers.context import _get_trace_callbacks cb = _get_trace_callbacks( @@ -1734,11 +1740,18 @@ class CallbackManagerForChainGroup(CallbackManager): .. code-block:: python - from langchain_core.callbacks.manager import CallbackManager, trace_as_chain_group + from langchain_core.callbacks.manager import ( + CallbackManager, + trace_as_chain_group, + ) from langchain_core.callbacks.stdout import StdOutCallbackHandler - manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"]) - with trace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager: + manager = CallbackManager( + handlers=[StdOutCallbackHandler()], tags=["tag2"] + ) + with trace_as_chain_group( + "My Group Name", tags=["tag1"] + ) as group_manager: merged_manager = group_manager.merge(manager) print(type(merged_manager)) # @@ -2258,18 +2271,25 @@ class AsyncCallbackManagerForChainGroup(AsyncCallbackManager): from the current object. Returns: - AsyncCallbackManagerForChainGroup: A copy of the current AsyncCallbackManagerForChainGroup - with the handlers, tags, etc. of the other callback manager merged in. + A copy of the current AsyncCallbackManagerForChainGroup + with the handlers, tags, etc. of the other callback manager merged in. Example: Merging two callback managers. .. code-block:: python - from langchain_core.callbacks.manager import CallbackManager, atrace_as_chain_group + from langchain_core.callbacks.manager import ( + CallbackManager, + atrace_as_chain_group, + ) from langchain_core.callbacks.stdout import StdOutCallbackHandler - manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"]) - async with atrace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager: + manager = CallbackManager( + handlers=[StdOutCallbackHandler()], tags=["tag2"] + ) + async with atrace_as_chain_group( + "My Group Name", tags=["tag1"] + ) as group_manager: merged_manager = group_manager.merge(manager) print(type(merged_manager)) # diff --git a/libs/core/langchain_core/documents/base.py b/libs/core/langchain_core/documents/base.py index 601e831a959..99ae9b62892 100644 --- a/libs/core/langchain_core/documents/base.py +++ b/libs/core/langchain_core/documents/base.py @@ -82,7 +82,7 @@ class Blob(BaseMedia): blob = Blob.from_data( data="Hello, world!", mime_type="text/plain", - metadata={"source": "https://example.com"} + metadata={"source": "https://example.com"}, ) Example: Load the blob from a file @@ -263,8 +263,7 @@ class Document(BaseMedia): from langchain_core.documents import Document document = Document( - page_content="Hello, world!", - metadata={"source": "https://example.com"} + page_content="Hello, world!", metadata={"source": "https://example.com"} ) """ diff --git a/libs/core/langchain_core/documents/transformers.py b/libs/core/langchain_core/documents/transformers.py index 171a98b458e..f70fa0d491e 100644 --- a/libs/core/langchain_core/documents/transformers.py +++ b/libs/core/langchain_core/documents/transformers.py @@ -38,7 +38,9 @@ class BaseDocumentTransformer(ABC): self.embeddings, stateful_documents ) included_idxs = _filter_similar_embeddings( - embedded_documents, self.similarity_fn, self.similarity_threshold + embedded_documents, + self.similarity_fn, + self.similarity_threshold, ) return [stateful_documents[i] for i in sorted(included_idxs)] @@ -47,7 +49,7 @@ class BaseDocumentTransformer(ABC): ) -> Sequence[Document]: raise NotImplementedError - """ # noqa: E501 + """ @abstractmethod def transform_documents( diff --git a/libs/core/langchain_core/embeddings/fake.py b/libs/core/langchain_core/embeddings/fake.py index 99069d08fb3..73b605dfa4b 100644 --- a/libs/core/langchain_core/embeddings/fake.py +++ b/libs/core/langchain_core/embeddings/fake.py @@ -20,6 +20,7 @@ class FakeEmbeddings(Embeddings, BaseModel): .. code-block:: python from langchain_core.embeddings import FakeEmbeddings + embed = FakeEmbeddings(size=100) Embed single text: @@ -78,6 +79,7 @@ class DeterministicFakeEmbedding(Embeddings, BaseModel): .. code-block:: python from langchain_core.embeddings import DeterministicFakeEmbedding + embed = DeterministicFakeEmbedding(size=100) Embed single text: diff --git a/libs/core/langchain_core/indexing/base.py b/libs/core/langchain_core/indexing/base.py index 5110e8c3630..0de0b8cdee2 100644 --- a/libs/core/langchain_core/indexing/base.py +++ b/libs/core/langchain_core/indexing/base.py @@ -254,7 +254,7 @@ class InMemoryRecordManager(RecordManager): """In-memory schema creation is simply ensuring the structure is initialized.""" async def acreate_schema(self) -> None: - """Async in-memory schema creation is simply ensuring the structure is initialized.""" # noqa: E501 + """In-memory schema creation is simply ensuring the structure is initialized.""" def get_time(self) -> float: """Get the current server time as a high resolution timestamp!""" diff --git a/libs/core/langchain_core/language_models/__init__.py b/libs/core/langchain_core/language_models/__init__.py index 4369d597d2e..7dc5791a16b 100644 --- a/libs/core/langchain_core/language_models/__init__.py +++ b/libs/core/langchain_core/language_models/__init__.py @@ -26,7 +26,8 @@ https://python.langchain.com/docs/how_to/custom_chat_model/ **LLMs** Language models that takes a string as input and returns a string. -These are traditionally older models (newer models generally are Chat Models, see below). +These are traditionally older models (newer models generally are Chat Models, +see below). Although the underlying models are string in, string out, the LangChain wrappers also allow these models to take messages as input. This gives them the same interface @@ -39,7 +40,7 @@ Please see the following guide for more information on how to implement a custom https://python.langchain.com/docs/how_to/custom_llm/ -""" # noqa: E501 +""" from typing import TYPE_CHECKING diff --git a/libs/core/langchain_core/language_models/chat_models.py b/libs/core/langchain_core/language_models/chat_models.py index 23872752da5..2ab0d6bb759 100644 --- a/libs/core/langchain_core/language_models/chat_models.py +++ b/libs/core/langchain_core/language_models/chat_models.py @@ -1453,15 +1453,20 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): from pydantic import BaseModel + class AnswerWithJustification(BaseModel): '''An answer to the user question along with justification for the answer.''' + answer: str justification: str + llm = ChatModel(model="model-name", temperature=0) structured_llm = llm.with_structured_output(AnswerWithJustification) - structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") + structured_llm.invoke( + "What weighs more a pound of bricks or a pound of feathers" + ) # -> AnswerWithJustification( # answer='They weigh the same', @@ -1473,15 +1478,22 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): from pydantic import BaseModel + class AnswerWithJustification(BaseModel): '''An answer to the user question along with justification for the answer.''' + answer: str justification: str - llm = ChatModel(model="model-name", temperature=0) - structured_llm = llm.with_structured_output(AnswerWithJustification, include_raw=True) - structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") + llm = ChatModel(model="model-name", temperature=0) + structured_llm = llm.with_structured_output( + AnswerWithJustification, include_raw=True + ) + + structured_llm.invoke( + "What weighs more a pound of bricks or a pound of feathers" + ) # -> { # 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}), # 'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'), @@ -1494,16 +1506,21 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): from pydantic import BaseModel from langchain_core.utils.function_calling import convert_to_openai_tool + class AnswerWithJustification(BaseModel): '''An answer to the user question along with justification for the answer.''' + answer: str justification: str + dict_schema = convert_to_openai_tool(AnswerWithJustification) llm = ChatModel(model="model-name", temperature=0) structured_llm = llm.with_structured_output(dict_schema) - structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") + structured_llm.invoke( + "What weighs more a pound of bricks or a pound of feathers" + ) # -> { # 'answer': 'They weigh the same', # 'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.' diff --git a/libs/core/langchain_core/memory.py b/libs/core/langchain_core/memory.py index b9249567b1c..bd6ac278808 100644 --- a/libs/core/langchain_core/memory.py +++ b/libs/core/langchain_core/memory.py @@ -45,16 +45,20 @@ class BaseMemory(Serializable, ABC): def memory_variables(self) -> list[str]: return list(self.memories.keys()) - def load_memory_variables(self, inputs: dict[str, Any]) -> dict[str, str]: + def load_memory_variables( + self, inputs: dict[str, Any] + ) -> dict[str, str]: return self.memories - def save_context(self, inputs: dict[str, Any], outputs: dict[str, str]) -> None: + def save_context( + self, inputs: dict[str, Any], outputs: dict[str, str] + ) -> None: pass def clear(self) -> None: pass - """ # noqa: E501 + """ model_config = ConfigDict( arbitrary_types_allowed=True, diff --git a/libs/core/langchain_core/messages/ai.py b/libs/core/langchain_core/messages/ai.py index 27ae49dca9f..86d48ec3254 100644 --- a/libs/core/langchain_core/messages/ai.py +++ b/libs/core/langchain_core/messages/ai.py @@ -124,7 +124,7 @@ class UsageMetadata(TypedDict): "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -468,13 +468,13 @@ def add_usage( input_tokens=5, output_tokens=0, total_tokens=5, - input_token_details=InputTokenDetails(cache_read=3) + input_token_details=InputTokenDetails(cache_read=3), ) right = UsageMetadata( input_tokens=0, output_tokens=10, total_tokens=10, - output_token_details=OutputTokenDetails(reasoning=4) + output_token_details=OutputTokenDetails(reasoning=4), ) add_usage(left, right) @@ -488,7 +488,7 @@ def add_usage( output_tokens=10, total_tokens=15, input_token_details=InputTokenDetails(cache_read=3), - output_token_details=OutputTokenDetails(reasoning=4) + output_token_details=OutputTokenDetails(reasoning=4), ) """ @@ -525,13 +525,13 @@ def subtract_usage( input_tokens=5, output_tokens=10, total_tokens=15, - input_token_details=InputTokenDetails(cache_read=4) + input_token_details=InputTokenDetails(cache_read=4), ) right = UsageMetadata( input_tokens=3, output_tokens=8, total_tokens=11, - output_token_details=OutputTokenDetails(reasoning=4) + output_token_details=OutputTokenDetails(reasoning=4), ) subtract_usage(left, right) @@ -545,7 +545,7 @@ def subtract_usage( output_tokens=2, total_tokens=4, input_token_details=InputTokenDetails(cache_read=4), - output_token_details=OutputTokenDetails(reasoning=0) + output_token_details=OutputTokenDetails(reasoning=0), ) """ diff --git a/libs/core/langchain_core/messages/human.py b/libs/core/langchain_core/messages/human.py index 1be4cbfa9d3..d6260cd14bd 100644 --- a/libs/core/langchain_core/messages/human.py +++ b/libs/core/langchain_core/messages/human.py @@ -17,12 +17,8 @@ class HumanMessage(BaseMessage): from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages diff --git a/libs/core/langchain_core/messages/system.py b/libs/core/langchain_core/messages/system.py index d63bd53a0fe..491bea204ea 100644 --- a/libs/core/langchain_core/messages/system.py +++ b/libs/core/langchain_core/messages/system.py @@ -18,12 +18,8 @@ class SystemMessage(BaseMessage): from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages diff --git a/libs/core/langchain_core/messages/tool.py b/libs/core/langchain_core/messages/tool.py index 10e2d18917a..4d847c86d97 100644 --- a/libs/core/langchain_core/messages/tool.py +++ b/libs/core/langchain_core/messages/tool.py @@ -32,7 +32,7 @@ class ToolMessage(BaseMessage, ToolOutputMixin): from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -45,7 +45,8 @@ class ToolMessage(BaseMessage, ToolOutputMixin): from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -53,14 +54,14 @@ class ToolMessage(BaseMessage, ToolOutputMixin): ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the tool call response. This is useful in situations where a chat model is able to request multiple tool calls in parallel. - """ # noqa: E501 + """ tool_call_id: str """Tool call that this message is responding to.""" @@ -184,11 +185,7 @@ class ToolCall(TypedDict): .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -236,12 +233,12 @@ class ToolCallChunk(TypedDict): .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] """ diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index 2796707aa24..16285eaefb2 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -424,11 +424,16 @@ def filter_messages( exclude_ids: Message IDs to exclude. Default is None. exclude_tool_calls: Tool call IDs to exclude. Default is None. Can be one of the following: - - `True`: all AIMessages with tool calls and all ToolMessages will be excluded. + + - ``True``: all AIMessages with tool calls and all ToolMessages will be + excluded. - a sequence of tool call IDs to exclude: + - ToolMessages with the corresponding tool call ID will be excluded. - - The `tool_calls` in the AIMessage will be updated to exclude matching tool calls. - If all tool_calls are filtered from an AIMessage, the whole message is excluded. + - The ``tool_calls`` in the AIMessage will be updated to exclude matching + tool calls. + If all tool_calls are filtered from an AIMessage, + the whole message is excluded. Returns: A list of Messages that meets at least one of the incl_* conditions and none @@ -441,14 +446,25 @@ def filter_messages( Example: .. code-block:: python - from langchain_core.messages import filter_messages, AIMessage, HumanMessage, SystemMessage + from langchain_core.messages import ( + filter_messages, + AIMessage, + HumanMessage, + SystemMessage, + ) messages = [ SystemMessage("you're a good assistant."), HumanMessage("what's your name", id="foo", name="example_user"), AIMessage("steve-o", id="bar", name="example_assistant"), - HumanMessage("what's your favorite color", id="baz",), - AIMessage("silicon blue", id="blah",), + HumanMessage( + "what's your favorite color", + id="baz", + ), + AIMessage( + "silicon blue", + id="blah", + ), ] filter_messages( @@ -465,7 +481,7 @@ def filter_messages( HumanMessage("what's your name", id="foo", name="example_user"), ] - """ # noqa: E501 + """ messages = convert_to_messages(messages) filtered: list[BaseMessage] = [] for msg in messages: @@ -544,12 +560,14 @@ def merge_message_runs( Returns: list of BaseMessages with consecutive runs of message types merged into single messages. By default, if two messages being merged both have string contents, - the merged content is a concatenation of the two strings with a new-line separator. + the merged content is a concatenation of the two strings with a new-line + separator. The separator inserted between message chunks can be controlled by specifying - any string with ``chunk_separator``. If at least one of the messages has a list of - content blocks, the merged content is a list of content blocks. + any string with ``chunk_separator``. If at least one of the messages has a list + of content blocks, the merged content is a list of content blocks. Example: + .. code-block:: python from langchain_core.messages import ( @@ -562,16 +580,33 @@ def merge_message_runs( messages = [ SystemMessage("you're a good assistant."), - HumanMessage("what's your favorite color", id="foo",), - HumanMessage("wait your favorite food", id="bar",), + HumanMessage( + "what's your favorite color", + id="foo", + ), + HumanMessage( + "wait your favorite food", + id="bar", + ), AIMessage( "my favorite colo", - tool_calls=[ToolCall(name="blah_tool", args={"x": 2}, id="123", type="tool_call")], + tool_calls=[ + ToolCall( + name="blah_tool", args={"x": 2}, id="123", type="tool_call" + ) + ], id="baz", ), AIMessage( [{"type": "text", "text": "my favorite dish is lasagna"}], - tool_calls=[ToolCall(name="blah_tool", args={"x": -10}, id="456", type="tool_call")], + tool_calls=[ + ToolCall( + name="blah_tool", + args={"x": -10}, + id="456", + type="tool_call", + ) + ], id="blur", ), ] @@ -582,21 +617,34 @@ def merge_message_runs( [ SystemMessage("you're a good assistant."), - HumanMessage("what's your favorite color\\nwait your favorite food", id="foo",), + HumanMessage( + "what's your favorite color\\n" + "wait your favorite food", id="foo", + ), AIMessage( [ "my favorite colo", {"type": "text", "text": "my favorite dish is lasagna"} ], tool_calls=[ - ToolCall({"name": "blah_tool", "args": {"x": 2}, "id": "123", "type": "tool_call"}), - ToolCall({"name": "blah_tool", "args": {"x": -10}, "id": "456", "type": "tool_call"}) + ToolCall({ + "name": "blah_tool", + "args": {"x": 2}, + "id": "123", + "type": "tool_call" + }), + ToolCall({ + "name": "blah_tool", + "args": {"x": -10}, + "id": "456", + "type": "tool_call" + }) ] id="baz" ), ] - """ # noqa: E501 + """ if not messages: return [] messages = convert_to_messages(messages) @@ -656,8 +704,8 @@ def trim_messages( properties: 1. The resulting chat history should be valid. Most chat models expect that chat - history starts with either (1) a ``HumanMessage`` or (2) a ``SystemMessage`` followed - by a ``HumanMessage``. To achieve this, set ``start_on="human"``. + history starts with either (1) a ``HumanMessage`` or (2) a ``SystemMessage`` + followed by a ``HumanMessage``. To achieve this, set ``start_on="human"``. In addition, generally a ``ToolMessage`` can only appear after an ``AIMessage`` that involved a tool call. Please see the following link for more information about messages: @@ -748,14 +796,18 @@ def trim_messages( ) messages = [ - SystemMessage("you're a good assistant, you always respond with a joke."), + SystemMessage( + "you're a good assistant, you always respond with a joke." + ), HumanMessage("i wonder why it's called langchain"), AIMessage( - 'Well, I guess they thought "WordRope" and "SentenceString" just didn\'t have the same ring to it!' + 'Well, I guess they thought "WordRope" and "SentenceString" just ' + "didn't have the same ring to it!" ), HumanMessage("and who is harrison chasing anyways"), AIMessage( - "Hmmm let me think.\n\nWhy, he's probably chasing after the last cup of coffee in the office!" + "Hmmm let me think.\n\nWhy, he's probably chasing after the last " + "cup of coffee in the office!" ), HumanMessage("what do you call a speechless parrot"), ] @@ -780,8 +832,10 @@ def trim_messages( .. code-block:: python [ - SystemMessage(content="you're a good assistant, you always respond with a joke."), - HumanMessage(content='what do you call a speechless parrot'), + SystemMessage( + content="you're a good assistant, you always respond with a joke." + ), + HumanMessage(content="what do you call a speechless parrot"), ] Trim chat history based on the message count, keeping the SystemMessage if @@ -811,10 +865,15 @@ def trim_messages( .. code-block:: python [ - SystemMessage(content="you're a good assistant, you always respond with a joke."), - HumanMessage(content='and who is harrison chasing anyways'), - AIMessage(content="Hmmm let me think.\n\nWhy, he's probably chasing after the last cup of coffee in the office!"), - HumanMessage(content='what do you call a speechless parrot'), + SystemMessage( + content="you're a good assistant, you always respond with a joke." + ), + HumanMessage(content="and who is harrison chasing anyways"), + AIMessage( + content="Hmmm let me think.\n\nWhy, he's probably chasing after " + "the last cup of coffee in the office!" + ), + HumanMessage(content="what do you call a speechless parrot"), ] @@ -825,7 +884,9 @@ def trim_messages( messages = [ SystemMessage("This is a 4 token text. The full message is 10 tokens."), - HumanMessage("This is a 4 token text. The full message is 10 tokens.", id="first"), + HumanMessage( + "This is a 4 token text. The full message is 10 tokens.", id="first" + ), AIMessage( [ {"type": "text", "text": "This is the FIRST 4 token block."}, @@ -833,10 +894,16 @@ def trim_messages( ], id="second", ), - HumanMessage("This is a 4 token text. The full message is 10 tokens.", id="third"), - AIMessage("This is a 4 token text. The full message is 10 tokens.", id="fourth"), + HumanMessage( + "This is a 4 token text. The full message is 10 tokens.", id="third" + ), + AIMessage( + "This is a 4 token text. The full message is 10 tokens.", + id="fourth", + ), ] + def dummy_token_counter(messages: list[BaseMessage]) -> int: # treat each message like it adds 3 default tokens at the beginning # of the message and at the end of the message. 3 + 4 + 3 = 10 tokens @@ -849,9 +916,17 @@ def trim_messages( count = 0 for msg in messages: if isinstance(msg.content, str): - count += default_msg_prefix_len + default_content_len + default_msg_suffix_len + count += ( + default_msg_prefix_len + + default_content_len + + default_msg_suffix_len + ) if isinstance(msg.content, list): - count += default_msg_prefix_len + len(msg.content) * default_content_len + default_msg_suffix_len + count += ( + default_msg_prefix_len + + len(msg.content) * default_content_len + + default_msg_suffix_len + ) return count First 30 tokens, allowing partial messages: @@ -868,12 +943,20 @@ def trim_messages( .. code-block:: python [ - SystemMessage("This is a 4 token text. The full message is 10 tokens."), - HumanMessage("This is a 4 token text. The full message is 10 tokens.", id="first"), - AIMessage( [{"type": "text", "text": "This is the FIRST 4 token block."}], id="second"), + SystemMessage( + "This is a 4 token text. The full message is 10 tokens." + ), + HumanMessage( + "This is a 4 token text. The full message is 10 tokens.", + id="first", + ), + AIMessage( + [{"type": "text", "text": "This is the FIRST 4 token block."}], + id="second", + ), ] - """ # noqa: E501 + """ # Validate arguments if start_on and strategy == "first": msg = "start_on parameter is only valid with strategy='last'" @@ -985,8 +1068,27 @@ def convert_to_openai_messages( messages = [ SystemMessage([{"type": "text", "text": "foo"}]), - {"role": "user", "content": [{"type": "text", "text": "whats in this"}, {"type": "image_url", "image_url": {"url": "data:image/png;base64,'/9j/4AAQSk'"}}]}, - AIMessage("", tool_calls=[{"name": "analyze", "args": {"baz": "buz"}, "id": "1", "type": "tool_call"}]), + { + "role": "user", + "content": [ + {"type": "text", "text": "whats in this"}, + { + "type": "image_url", + "image_url": {"url": "data:image/png;base64,'/9j/4AAQSk'"}, + }, + ], + }, + AIMessage( + "", + tool_calls=[ + { + "name": "analyze", + "args": {"baz": "buz"}, + "id": "1", + "type": "tool_call", + } + ], + ), ToolMessage("foobar", tool_call_id="1", name="bar"), {"role": "assistant", "content": "thats nice"}, ] diff --git a/libs/core/langchain_core/output_parsers/base.py b/libs/core/langchain_core/output_parsers/base.py index a187efb4b23..6cefd3ef62f 100644 --- a/libs/core/langchain_core/output_parsers/base.py +++ b/libs/core/langchain_core/output_parsers/base.py @@ -144,7 +144,10 @@ class BaseOutputParser( def parse(self, text: str) -> bool: cleaned_text = text.strip().upper() - if cleaned_text not in (self.true_val.upper(), self.false_val.upper()): + if cleaned_text not in ( + self.true_val.upper(), + self.false_val.upper(), + ): raise OutputParserException( f"BooleanOutputParser expected output value to either be " f"{self.true_val} or {self.false_val} (case-insensitive). " @@ -156,7 +159,7 @@ class BaseOutputParser( def _type(self) -> str: return "boolean_output_parser" - """ # noqa: E501 + """ @property @override diff --git a/libs/core/langchain_core/prompts/chat.py b/libs/core/langchain_core/prompts/chat.py index 489cbe7a703..12728ef76e8 100644 --- a/libs/core/langchain_core/prompts/chat.py +++ b/libs/core/langchain_core/prompts/chat.py @@ -67,10 +67,10 @@ class MessagesPlaceholder(BaseMessagePromptTemplate): from langchain_core.prompts import MessagesPlaceholder prompt = MessagesPlaceholder("history") - prompt.format_messages() # raises KeyError + prompt.format_messages() # raises KeyError prompt = MessagesPlaceholder("history", optional=True) - prompt.format_messages() # returns empty list [] + prompt.format_messages() # returns empty list [] prompt.format_messages( history=[ @@ -93,14 +93,14 @@ class MessagesPlaceholder(BaseMessagePromptTemplate): [ ("system", "You are a helpful assistant."), MessagesPlaceholder("history"), - ("human", "{question}") + ("human", "{question}"), ] ) prompt.invoke( - { - "history": [("human", "what's 5 + 2"), ("ai", "5 + 2 is 7")], - "question": "now multiply that by 4" - } + { + "history": [("human", "what's 5 + 2"), ("ai", "5 + 2 is 7")], + "question": "now multiply that by 4", + } ) # -> ChatPromptValue(messages=[ # SystemMessage(content="You are a helpful assistant."), @@ -795,18 +795,17 @@ class ChatPromptTemplate(BaseChatPromptTemplate): from langchain_core.prompts import ChatPromptTemplate - template = ChatPromptTemplate([ - ("system", "You are a helpful AI bot. Your name is {name}."), - ("human", "Hello, how are you doing?"), - ("ai", "I'm doing well, thanks!"), - ("human", "{user_input}"), - ]) + template = ChatPromptTemplate( + [ + ("system", "You are a helpful AI bot. Your name is {name}."), + ("human", "Hello, how are you doing?"), + ("ai", "I'm doing well, thanks!"), + ("human", "{user_input}"), + ] + ) prompt_value = template.invoke( - { - "name": "Bob", - "user_input": "What is your name?" - } + {"name": "Bob", "user_input": "What is your name?"} ) # Output: # ChatPromptValue( @@ -816,7 +815,7 @@ class ChatPromptTemplate(BaseChatPromptTemplate): # AIMessage(content="I'm doing well, thanks!"), # HumanMessage(content='What is your name?') # ] - #) + # ) Messages Placeholder: @@ -826,14 +825,16 @@ class ChatPromptTemplate(BaseChatPromptTemplate): # you can initialize the template with a MessagesPlaceholder # either using the class directly or with the shorthand tuple syntax: - template = ChatPromptTemplate([ - ("system", "You are a helpful AI bot."), - # Means the template will receive an optional list of messages under - # the "conversation" key - ("placeholder", "{conversation}") - # Equivalently: - # MessagesPlaceholder(variable_name="conversation", optional=True) - ]) + template = ChatPromptTemplate( + [ + ("system", "You are a helpful AI bot."), + # Means the template will receive an optional list of messages under + # the "conversation" key + ("placeholder", "{conversation}"), + # Equivalently: + # MessagesPlaceholder(variable_name="conversation", optional=True) + ] + ) prompt_value = template.invoke( { @@ -841,7 +842,7 @@ class ChatPromptTemplate(BaseChatPromptTemplate): ("human", "Hi!"), ("ai", "How can I assist you today?"), ("human", "Can you make me an ice cream sundae?"), - ("ai", "No.") + ("ai", "No."), ] } ) @@ -855,7 +856,7 @@ class ChatPromptTemplate(BaseChatPromptTemplate): # HumanMessage(content='Can you make me an ice cream sundae?'), # AIMessage(content='No.'), # ] - #) + # ) Single-variable template: @@ -868,10 +869,12 @@ class ChatPromptTemplate(BaseChatPromptTemplate): from langchain_core.prompts import ChatPromptTemplate - template = ChatPromptTemplate([ - ("system", "You are a helpful AI bot. Your name is Carl."), - ("human", "{user_input}"), - ]) + template = ChatPromptTemplate( + [ + ("system", "You are a helpful AI bot. Your name is Carl."), + ("human", "{user_input}"), + ] + ) prompt_value = template.invoke("Hello, there!") # Equivalent to @@ -930,20 +933,24 @@ class ChatPromptTemplate(BaseChatPromptTemplate): .. code-block:: python - template = ChatPromptTemplate([ - ("human", "Hello, how are you?"), - ("ai", "I'm doing well, thanks!"), - ("human", "That's good to hear."), - ]) + template = ChatPromptTemplate( + [ + ("human", "Hello, how are you?"), + ("ai", "I'm doing well, thanks!"), + ("human", "That's good to hear."), + ] + ) Instantiation from mixed message formats: .. code-block:: python - template = ChatPromptTemplate([ - SystemMessage(content="hello"), - ("human", "Hello, how are you?"), - ]) + template = ChatPromptTemplate( + [ + SystemMessage(content="hello"), + ("human", "Hello, how are you?"), + ] + ) """ messages_ = [ @@ -1137,20 +1144,24 @@ class ChatPromptTemplate(BaseChatPromptTemplate): .. code-block:: python - template = ChatPromptTemplate.from_messages([ - ("human", "Hello, how are you?"), - ("ai", "I'm doing well, thanks!"), - ("human", "That's good to hear."), - ]) + template = ChatPromptTemplate.from_messages( + [ + ("human", "Hello, how are you?"), + ("ai", "I'm doing well, thanks!"), + ("human", "That's good to hear."), + ] + ) Instantiation from mixed message formats: .. code-block:: python - template = ChatPromptTemplate.from_messages([ - SystemMessage(content="hello"), - ("human", "Hello, how are you?"), - ]) + template = ChatPromptTemplate.from_messages( + [ + SystemMessage(content="hello"), + ("human", "Hello, how are you?"), + ] + ) Args: messages: sequence of message representations. diff --git a/libs/core/langchain_core/prompts/few_shot.py b/libs/core/langchain_core/prompts/few_shot.py index a1d237e66cf..ddb09c2e320 100644 --- a/libs/core/langchain_core/prompts/few_shot.py +++ b/libs/core/langchain_core/prompts/few_shot.py @@ -272,7 +272,7 @@ class FewShotChatMessagePromptTemplate( from langchain_core.prompts import ( FewShotChatMessagePromptTemplate, - ChatPromptTemplate + ChatPromptTemplate, ) examples = [ @@ -281,7 +281,7 @@ class FewShotChatMessagePromptTemplate( ] example_prompt = ChatPromptTemplate.from_messages( - [('human', 'What is {input}?'), ('ai', '{output}')] + [("human", "What is {input}?"), ("ai", "{output}")] ) few_shot_prompt = FewShotChatMessagePromptTemplate( @@ -292,9 +292,9 @@ class FewShotChatMessagePromptTemplate( final_prompt = ChatPromptTemplate.from_messages( [ - ('system', 'You are a helpful AI Assistant'), + ("system", "You are a helpful AI Assistant"), few_shot_prompt, - ('human', '{input}'), + ("human", "{input}"), ] ) final_prompt.format(input="What is 4+4?") @@ -314,10 +314,7 @@ class FewShotChatMessagePromptTemplate( # ... ] - to_vectorize = [ - " ".join(example.values()) - for example in examples - ] + to_vectorize = [" ".join(example.values()) for example in examples] embeddings = OpenAIEmbeddings() vectorstore = Chroma.from_texts( to_vectorize, embeddings, metadatas=examples @@ -355,6 +352,7 @@ class FewShotChatMessagePromptTemplate( # Use within an LLM from langchain_core.chat_models import ChatAnthropic + chain = final_prompt | ChatAnthropic(model="claude-3-haiku-20240307") chain.invoke({"input": "What's 3+3?"}) diff --git a/libs/core/langchain_core/prompts/structured.py b/libs/core/langchain_core/prompts/structured.py index 96dcb79124a..d05ace21ccf 100644 --- a/libs/core/langchain_core/prompts/structured.py +++ b/libs/core/langchain_core/prompts/structured.py @@ -89,10 +89,12 @@ class StructuredPrompt(ChatPromptTemplate): from langchain_core.prompts import StructuredPrompt + class OutputSchema(BaseModel): name: str value: int + template = StructuredPrompt( [ ("human", "Hello, how are you?"), diff --git a/libs/core/langchain_core/rate_limiters.py b/libs/core/langchain_core/rate_limiters.py index dffdb580fa0..9df065a8007 100644 --- a/libs/core/langchain_core/rate_limiters.py +++ b/libs/core/langchain_core/rate_limiters.py @@ -110,9 +110,9 @@ class InMemoryRateLimiter(BaseRateLimiter): ) from langchain_anthropic import ChatAnthropic + model = ChatAnthropic( - model_name="claude-3-opus-20240229", - rate_limiter=rate_limiter + model_name="claude-3-opus-20240229", rate_limiter=rate_limiter ) for _ in range(5): diff --git a/libs/core/langchain_core/retrievers.py b/libs/core/langchain_core/retrievers.py index efc9fc40a7b..2a7cb681ff8 100644 --- a/libs/core/langchain_core/retrievers.py +++ b/libs/core/langchain_core/retrievers.py @@ -109,6 +109,7 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC): from sklearn.metrics.pairwise import cosine_similarity + class TFIDFRetriever(BaseRetriever, BaseModel): vectorizer: Any docs: list[Document] @@ -122,10 +123,12 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC): # Ip -- (n_docs,x), Op -- (n_docs,n_Feats) query_vec = self.vectorizer.transform([query]) # Op -- (n_docs,1) -- Cosine Sim with each doc - results = cosine_similarity(self.tfidf_array, query_vec).reshape((-1,)) + results = cosine_similarity(self.tfidf_array, query_vec).reshape( + (-1,) + ) return [self.docs[i] for i in results.argsort()[-self.k :][::-1]] - """ # noqa: E501 + """ model_config = ConfigDict( arbitrary_types_allowed=True, diff --git a/libs/core/langchain_core/runnables/base.py b/libs/core/langchain_core/runnables/base.py index 4da0a484415..c065cc7afbf 100644 --- a/libs/core/langchain_core/runnables/base.py +++ b/libs/core/langchain_core/runnables/base.py @@ -114,12 +114,13 @@ class Runnable(ABC, Generic[Input, Output]): - **``invoke``/``ainvoke``**: Transforms a single input into an output. - **``batch``/``abatch``**: Efficiently transforms multiple inputs into outputs. - **``stream``/``astream``**: Streams output from a single input as it's produced. - - **``astream_log``**: Streams output and selected intermediate results from an input. + - **``astream_log``**: Streams output and selected intermediate results from an + input. Built-in optimizations: - - **Batch**: By default, batch runs invoke() in parallel using a thread pool executor. - Override to optimize batching. + - **Batch**: By default, batch runs invoke() in parallel using a thread pool + executor. Override to optimize batching. - **Async**: Methods with ``'a'`` suffix are asynchronous. By default, they execute the sync counterpart using asyncio's thread pool. @@ -129,14 +130,16 @@ class Runnable(ABC, Generic[Input, Output]): execution, add tags and metadata for tracing and debugging etc. Runnables expose schematic information about their input, output and config via - the ``input_schema`` property, the ``output_schema`` property and ``config_schema`` method. + the ``input_schema`` property, the ``output_schema`` property and ``config_schema`` + method. LCEL and Composition ==================== - The LangChain Expression Language (LCEL) is a declarative way to compose ``Runnables`` - into chains. Any chain constructed this way will automatically have sync, async, - batch, and streaming support. + The LangChain Expression Language (LCEL) is a declarative way to compose + ``Runnables``into chains. + Any chain constructed this way will automatically have sync, async, batch, and + streaming support. The main composition primitives are ``RunnableSequence`` and ``RunnableParallel``. @@ -157,25 +160,27 @@ class Runnable(ABC, Generic[Input, Output]): # A RunnableSequence constructed using the `|` operator sequence = RunnableLambda(lambda x: x + 1) | RunnableLambda(lambda x: x * 2) - sequence.invoke(1) # 4 - sequence.batch([1, 2, 3]) # [4, 6, 8] + sequence.invoke(1) # 4 + sequence.batch([1, 2, 3]) # [4, 6, 8] # A sequence that contains a RunnableParallel constructed using a dict literal sequence = RunnableLambda(lambda x: x + 1) | { - 'mul_2': RunnableLambda(lambda x: x * 2), - 'mul_5': RunnableLambda(lambda x: x * 5) + "mul_2": RunnableLambda(lambda x: x * 2), + "mul_5": RunnableLambda(lambda x: x * 5), } - sequence.invoke(1) # {'mul_2': 4, 'mul_5': 10} + sequence.invoke(1) # {'mul_2': 4, 'mul_5': 10} Standard Methods ================ - All ``Runnable``s expose additional methods that can be used to modify their behavior - (e.g., add a retry policy, add lifecycle listeners, make them configurable, etc.). + All ``Runnable``s expose additional methods that can be used to modify their + behavior (e.g., add a retry policy, add lifecycle listeners, make them + configurable, etc.). - These methods will work on any ``Runnable``, including ``Runnable`` chains constructed - by composing other ``Runnable``s. See the individual methods for details. + These methods will work on any ``Runnable``, including ``Runnable`` chains + constructed by composing other ``Runnable``s. + See the individual methods for details. For example, @@ -219,6 +224,7 @@ class Runnable(ABC, Generic[Input, Output]): .. code-block:: python from langchain_core.globals import set_debug + set_debug(True) Alternatively, you can pass existing or custom callbacks to any given chain: @@ -227,14 +233,11 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.tracers import ConsoleCallbackHandler - chain.invoke( - ..., - config={'callbacks': [ConsoleCallbackHandler()]} - ) + chain.invoke(..., config={"callbacks": [ConsoleCallbackHandler()]}) For a UI (and much more) checkout `LangSmith `__. - """ # noqa: E501 + """ name: Optional[str] """The name of the ``Runnable``. Used for debugging and tracing.""" @@ -381,9 +384,11 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.runnables import RunnableLambda + def add_one(x: int) -> int: return x + 1 + runnable = RunnableLambda(add_one) print(runnable.get_input_jsonschema()) @@ -395,7 +400,10 @@ class Runnable(ABC, Generic[Input, Output]): @property def output_schema(self) -> type[BaseModel]: - """The type of output this ``Runnable`` produces specified as a pydantic model.""" # noqa: E501 + """Output schema. + + The type of output this ``Runnable`` produces specified as a pydantic model. + """ return self.get_output_schema() def get_output_schema( @@ -455,9 +463,11 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.runnables import RunnableLambda + def add_one(x: int) -> int: return x + 1 + runnable = RunnableLambda(add_one) print(runnable.get_output_jsonschema()) @@ -603,12 +613,15 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.runnables import RunnableLambda + def add_one(x: int) -> int: return x + 1 + def mul_two(x: int) -> int: return x * 2 + runnable_1 = RunnableLambda(add_one) runnable_2 = RunnableLambda(mul_two) sequence = runnable_1.pipe(runnable_2) @@ -658,13 +671,14 @@ class Runnable(ABC, Generic[Input, Output]): as_str = RunnableLambda(str) as_json = RunnableLambda(json.loads) + + def as_bytes(x: Any) -> bytes: return bytes(x, "utf-8") + chain = RunnableMap( - str=as_str, - json=as_json, - bytes=RunnableLambda(as_bytes) + str=as_str, json=as_json, bytes=RunnableLambda(as_bytes) ) chain.invoke("[1, 2, 3]") @@ -1254,6 +1268,7 @@ class Runnable(ABC, Generic[Input, Output]): '''Format the docs.''' return ", ".join([doc.page_content for doc in docs]) + format_docs = RunnableLambda(format_docs) ``some_tool``: @@ -1280,9 +1295,11 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.runnables import RunnableLambda + async def reverse(s: str) -> str: return s[::-1] + chain = RunnableLambda(func=reverse) events = [ @@ -1422,7 +1439,9 @@ class Runnable(ABC, Generic[Input, Output]): config: Optional[RunnableConfig] = None, **kwargs: Optional[Any], ) -> Iterator[Output]: - """Default implementation of transform, which buffers input and calls ``astream``. + """Transform inputs to outputs. + + Default implementation of transform, which buffers input and calls ``astream``. Subclasses should override this method if they can start producing output while input is still being generated. @@ -1435,7 +1454,7 @@ class Runnable(ABC, Generic[Input, Output]): Yields: The output of the ``Runnable``. - """ # noqa: E501 + """ final: Input got_first_val = False @@ -1465,7 +1484,9 @@ class Runnable(ABC, Generic[Input, Output]): config: Optional[RunnableConfig] = None, **kwargs: Optional[Any], ) -> AsyncIterator[Output]: - """Default implementation of atransform, which buffers input and calls ``astream``. + """Transform inputs to outputs. + + Default implementation of atransform, which buffers input and calls ``astream``. Subclasses should override this method if they can start producing output while input is still being generated. @@ -1478,7 +1499,7 @@ class Runnable(ABC, Generic[Input, Output]): Yields: The output of the ``Runnable``. - """ # noqa: E501 + """ final: Input got_first_val = False @@ -1522,22 +1543,16 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_ollama import ChatOllama from langchain_core.output_parsers import StrOutputParser - llm = ChatOllama(model='llama2') + llm = ChatOllama(model="llama2") # Without bind. - chain = ( - llm - | StrOutputParser() - ) + chain = llm | StrOutputParser() chain.invoke("Repeat quoted words exactly: 'One two three four five.'") # Output is 'One two three four five.' # With bind. - chain = ( - llm.bind(stop=["three"]) - | StrOutputParser() - ) + chain = llm.bind(stop=["three"]) | StrOutputParser() chain.invoke("Repeat quoted words exactly: 'One two three four five.'") # Output is 'One two' @@ -1609,18 +1624,21 @@ class Runnable(ABC, Generic[Input, Output]): import time - def test_runnable(time_to_sleep : int): + + def test_runnable(time_to_sleep: int): time.sleep(time_to_sleep) + def fn_start(run_obj: Run): print("start_time:", run_obj.start_time) + def fn_end(run_obj: Run): print("end_time:", run_obj.end_time) + chain = RunnableLambda(test_runnable).with_listeners( - on_start=fn_start, - on_end=fn_end + on_start=fn_start, on_end=fn_end ) chain.invoke(2) @@ -1650,7 +1668,9 @@ class Runnable(ABC, Generic[Input, Output]): on_end: Optional[AsyncListener] = None, on_error: Optional[AsyncListener] = None, ) -> Runnable[Input, Output]: - """Bind async lifecycle listeners to a ``Runnable``, returning a new ``Runnable``. + """Bind async lifecycle listeners to a ``Runnable``. + + Returns a new ``Runnable``. The Run object contains information about the run, including its ``id``, ``type``, ``input``, ``output``, ``error``, ``start_time``, ``end_time``, and @@ -1716,7 +1736,7 @@ class Runnable(ABC, Generic[Input, Output]): on end callback ends at 2025-03-01T07:05:29.883893+00:00 on end callback ends at 2025-03-01T07:05:30.884831+00:00 - """ # noqa: E501 + """ from langchain_core.tracers.root_listeners import AsyncRootListenersTracer return RunnableBinding( @@ -1796,7 +1816,7 @@ class Runnable(ABC, Generic[Input, Output]): if x == 1: raise ValueError("x is 1") else: - pass + pass runnable = RunnableLambda(_lambda) @@ -1808,7 +1828,7 @@ class Runnable(ABC, Generic[Input, Output]): except ValueError: pass - assert (count == 2) + assert count == 2 """ from langchain_core.runnables.retry import RunnableRetry @@ -1837,11 +1857,13 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.runnables import RunnableLambda + def _lambda(x: int) -> int: return x + 1 + runnable = RunnableLambda(_lambda) - print(runnable.map().invoke([1, 2, 3])) # [2, 3, 4] + print(runnable.map().invoke([1, 2, 3])) # [2, 3, 4] """ return RunnableEach(bound=self) @@ -1859,13 +1881,15 @@ class Runnable(ABC, Generic[Input, Output]): in order, upon failures. Args: - fallbacks: A sequence of runnables to try if the original ``Runnable`` fails. + fallbacks: A sequence of runnables to try if the original ``Runnable`` + fails. exceptions_to_handle: A tuple of exception types to handle. Defaults to ``(Exception,)``. exception_key: If string is specified then handled exceptions will be passed - to fallbacks as part of the input under the specified key. If None, - exceptions will not be passed to fallbacks. If used, the base ``Runnable`` - and its fallbacks must accept a dictionary as input. Defaults to None. + to fallbacks as part of the input under the specified key. + If None, exceptions will not be passed to fallbacks. + If used, the base ``Runnable`` and its fallbacks must accept a + dictionary as input. Defaults to None. Returns: A new ``Runnable`` that will try the original ``Runnable``, and then each @@ -1891,22 +1915,24 @@ class Runnable(ABC, Generic[Input, Output]): runnable = RunnableGenerator(_generate_immediate_error).with_fallbacks( [RunnableGenerator(_generate)] - ) - print(''.join(runnable.stream({}))) #foo bar + ) + print("".join(runnable.stream({}))) # foo bar Args: - fallbacks: A sequence of runnables to try if the original ``Runnable`` fails. + fallbacks: A sequence of runnables to try if the original ``Runnable`` + fails. exceptions_to_handle: A tuple of exception types to handle. exception_key: If string is specified then handled exceptions will be passed - to fallbacks as part of the input under the specified key. If None, - exceptions will not be passed to fallbacks. If used, the base ``Runnable`` - and its fallbacks must accept a dictionary as input. + to fallbacks as part of the input under the specified key. + If None, exceptions will not be passed to fallbacks. + If used, the base ``Runnable`` and its fallbacks must accept a + dictionary as input. Returns: A new ``Runnable`` that will try the original ``Runnable``, and then each fallback in order, upon failures. - """ # noqa: E501 + """ from langchain_core.runnables.fallbacks import RunnableWithFallbacks return RunnableWithFallbacks( @@ -1931,11 +1957,14 @@ class Runnable(ABC, Generic[Input, Output]): serialized: Optional[dict[str, Any]] = None, **kwargs: Optional[Any], ) -> Output: - """Helper method to transform an ``Input`` value to an ``Output`` value, with callbacks. + """Call with config. + + Helper method to transform an ``Input`` value to an ``Output`` value, + with callbacks. Use this method to implement ``invoke`` in subclasses. - """ # noqa: E501 + """ config = ensure_config(config) callback_manager = get_callback_manager_for_config(config) run_manager = callback_manager.on_chain_start( @@ -1982,10 +2011,13 @@ class Runnable(ABC, Generic[Input, Output]): serialized: Optional[dict[str, Any]] = None, **kwargs: Optional[Any], ) -> Output: - """Helper method to transform an ``Input`` value to an ``Output`` value, with callbacks. + """Async call with config. + + Helper method to transform an ``Input`` value to an ``Output`` value, + with callbacks. Use this method to implement ``ainvoke`` in subclasses. - """ # noqa: E501 + """ config = ensure_config(config) callback_manager = get_async_callback_manager_for_config(config) run_manager = await callback_manager.on_chain_start( @@ -2411,13 +2443,16 @@ class Runnable(ABC, Generic[Input, Output]): from typing_extensions import TypedDict from langchain_core.runnables import RunnableLambda + class Args(TypedDict): a: int b: list[int] + def f(x: Args) -> str: return str(x["a"] * max(x["b"])) + runnable = RunnableLambda(f) as_tool = runnable.as_tool() as_tool.invoke({"a": 3, "b": [1, 2]}) @@ -2450,9 +2485,11 @@ class Runnable(ABC, Generic[Input, Output]): from typing import Any from langchain_core.runnables import RunnableLambda + def f(x: dict[str, Any]) -> str: return str(x["a"] * max(x["b"])) + runnable = RunnableLambda(f) as_tool = runnable.as_tool(arg_types={"a": int, "b": list[int]}) as_tool.invoke({"a": 3, "b": [1, 2]}) @@ -2463,12 +2500,15 @@ class Runnable(ABC, Generic[Input, Output]): from langchain_core.runnables import RunnableLambda + def f(x: str) -> str: return x + "a" + def g(x: str) -> str: return x + "z" + runnable = RunnableLambda(f) | g as_tool = runnable.as_tool() as_tool.invoke("b") @@ -2538,14 +2578,15 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): # max_tokens = 20 print( - "max_tokens_20: ", - model.invoke("tell me something about chess").content + "max_tokens_20: ", model.invoke("tell me something about chess").content ) # max_tokens = 200 - print("max_tokens_200: ", model.with_config( - configurable={"output_token_number": 200} - ).invoke("tell me something about chess").content + print( + "max_tokens_200: ", + model.with_config(configurable={"output_token_number": 200}) + .invoke("tell me something about chess") + .content, ) """ @@ -2596,7 +2637,7 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): ).configurable_alternatives( ConfigurableField(id="llm"), default_key="anthropic", - openai=ChatOpenAI() + openai=ChatOpenAI(), ) # uses the default model ChatAnthropic @@ -2604,9 +2645,9 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): # uses ChatOpenAI print( - model.with_config( - configurable={"llm": "openai"} - ).invoke("which organization created you?").content + model.with_config(configurable={"llm": "openai"}) + .invoke("which organization created you?") + .content ) """ @@ -2739,12 +2780,15 @@ class RunnableSequence(RunnableSerializable[Input, Output]): from langchain_core.runnables import RunnableLambda + def add_one(x: int) -> int: return x + 1 + def mul_two(x: int) -> int: return x * 2 + runnable_1 = RunnableLambda(add_one) runnable_2 = RunnableLambda(mul_two) sequence = runnable_1 | runnable_2 @@ -2764,17 +2808,17 @@ class RunnableSequence(RunnableSerializable[Input, Output]): from langchain_openai import ChatOpenAI prompt = PromptTemplate.from_template( - 'In JSON format, give me a list of {topic} and their ' - 'corresponding names in French, Spanish and in a ' - 'Cat Language.' + "In JSON format, give me a list of {topic} and their " + "corresponding names in French, Spanish and in a " + "Cat Language." ) model = ChatOpenAI() chain = prompt | model | SimpleJsonOutputParser() - async for chunk in chain.astream({'topic': 'colors'}): - print('-') # noqa: T201 - print(chunk, sep='', flush=True) # noqa: T201 + async for chunk in chain.astream({"topic": "colors"}): + print("-") # noqa: T201 + print(chunk, sep="", flush=True) # noqa: T201 """ @@ -3520,15 +3564,19 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]): from langchain_core.runnables import RunnableLambda + def add_one(x: int) -> int: return x + 1 + def mul_two(x: int) -> int: return x * 2 + def mul_three(x: int) -> int: return x * 3 + runnable_1 = RunnableLambda(add_one) runnable_2 = RunnableLambda(mul_two) runnable_3 = RunnableLambda(mul_three) @@ -3564,8 +3612,7 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]): model = ChatOpenAI() joke_chain = ( - ChatPromptTemplate.from_template("tell me a joke about {topic}") - | model + ChatPromptTemplate.from_template("tell me a joke about {topic}") | model ) poem_chain = ( ChatPromptTemplate.from_template("write a 2-line poem about {topic}") @@ -4068,9 +4115,10 @@ class RunnableGenerator(Runnable[Input, Output]): for token in ["Have", " a", " nice", " day"]: yield token + runnable = RunnableGenerator(agen) await runnable.ainvoke(None) # "Have a nice day" - [p async for p in runnable.astream(None)] # ["Have", " a", " nice", " day"] + [p async for p in runnable.astream(None)] # ["Have", " a", " nice", " day"] ``RunnableGenerator`` makes it easy to implement custom behavior within a streaming context. Below we show an example: @@ -4090,6 +4138,7 @@ class RunnableGenerator(Runnable[Input, Output]): | StrOutputParser() ) + def character_generator(input: Iterator[str]) -> Iterator[str]: for token in input: if "," in token or "." in token: @@ -4100,7 +4149,10 @@ class RunnableGenerator(Runnable[Input, Output]): runnable = chant_chain | character_generator assert type(runnable.last) is RunnableGenerator - "".join(runnable.stream({"topic": "waste"})) # Reduce👏, Reuse👏, Recycle👏. + "".join( + runnable.stream({"topic": "waste"}) + ) # Reduce👏, Reuse👏, Recycle👏. + # Note that RunnableLambda can be used to delay streaming of one step in a # sequence until the previous step is finished: @@ -4109,6 +4161,7 @@ class RunnableGenerator(Runnable[Input, Output]): for character in input[::-1]: yield character + runnable = chant_chain | RunnableLambda(reverse_generator) "".join(runnable.stream({"topic": "waste"})) # ".elcycer ,esuer ,ecudeR" @@ -4353,26 +4406,29 @@ class RunnableLambda(Runnable[Input, Output]): # This is a RunnableLambda from langchain_core.runnables import RunnableLambda + def add_one(x: int) -> int: return x + 1 + runnable = RunnableLambda(add_one) - runnable.invoke(1) # returns 2 - runnable.batch([1, 2, 3]) # returns [2, 3, 4] + runnable.invoke(1) # returns 2 + runnable.batch([1, 2, 3]) # returns [2, 3, 4] # Async is supported by default by delegating to the sync implementation - await runnable.ainvoke(1) # returns 2 - await runnable.abatch([1, 2, 3]) # returns [2, 3, 4] + await runnable.ainvoke(1) # returns 2 + await runnable.abatch([1, 2, 3]) # returns [2, 3, 4] # Alternatively, can provide both synd and sync implementations async def add_one_async(x: int) -> int: return x + 1 + runnable = RunnableLambda(add_one, afunc=add_one_async) - runnable.invoke(1) # Uses add_one - await runnable.ainvoke(1) # Uses add_one_async + runnable.invoke(1) # Uses add_one + await runnable.ainvoke(1) # Uses add_one_async """ @@ -5080,13 +5136,16 @@ class RunnableLambda(Runnable[Input, Output]): class RunnableEachBase(RunnableSerializable[list[Input], list[Output]]): - """``Runnable`` that calls another ``Runnable`` for each element of the input sequence. + """RunnableEachBase class. - Use only if creating a new ``RunnableEach`` subclass with different ``__init__`` args. + ``Runnable`` that calls another ``Runnable`` for each element of the input sequence. + + Use only if creating a new ``RunnableEach`` subclass with different ``__init__`` + args. See documentation for ``RunnableEach`` for more details. - """ # noqa: E501 + """ bound: Runnable[Input, Output] @@ -5214,7 +5273,9 @@ class RunnableEachBase(RunnableSerializable[list[Input], list[Output]]): class RunnableEach(RunnableEachBase[Input, Output]): - """``Runnable`` that calls another ``Runnable`` for each element of the input sequence. + """RunnableEach class. + + ``Runnable`` that calls another ``Runnable`` for each element of the input sequence. It allows you to call multiple inputs with the bounded ``Runnable``. @@ -5239,7 +5300,7 @@ class RunnableEach(RunnableEachBase[Input, Output]): {'topic':'Biology'}]) print(output) # noqa: T201 - """ # noqa: E501 + """ @override def get_name( @@ -5303,7 +5364,9 @@ class RunnableEach(RunnableEachBase[Input, Output]): on_end: Optional[AsyncListener] = None, on_error: Optional[AsyncListener] = None, ) -> RunnableEach[Input, Output]: - """Bind async lifecycle listeners to a ``Runnable``, returning a new ``Runnable``. + """Bind async lifecycle listeners to a ``Runnable``. + + Returns a new ``Runnable``. The ``Run`` object contains information about the run, including its ``id``, ``type``, ``input``, ``output``, ``error``, ``start_time``, ``end_time``, and @@ -5320,7 +5383,7 @@ class RunnableEach(RunnableEachBase[Input, Output]): Returns: A new ``Runnable`` with the listeners bound. - """ # noqa: E501 + """ return RunnableEach( bound=self.bound.with_alisteners( on_start=on_start, on_end=on_end, on_error=on_error @@ -5391,22 +5454,23 @@ class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[ """Create a ``RunnableBinding`` from a ``Runnable`` and kwargs. Args: - bound: The underlying ``Runnable`` that this ``Runnable`` delegates calls to. + bound: The underlying ``Runnable`` that this ``Runnable`` delegates calls + to. kwargs: optional kwargs to pass to the underlying ``Runnable``, when running - the underlying ``Runnable`` (e.g., via ``invoke``, ``batch``, - ``transform``, or ``stream`` or async variants) - Defaults to None. + the underlying ``Runnable`` (e.g., via ``invoke``, ``batch``, + ``transform``, or ``stream`` or async variants) + Defaults to None. config: optional config to bind to the underlying ``Runnable``. - Defaults to None. + Defaults to None. config_factories: optional list of config factories to apply to the - config before binding to the underlying ``Runnable``. - Defaults to None. + config before binding to the underlying ``Runnable``. + Defaults to None. custom_input_type: Specify to override the input type of the underlying - ``Runnable`` with a custom type. Defaults to None. + ``Runnable`` with a custom type. Defaults to None. custom_output_type: Specify to override the output type of the underlying - ``Runnable`` with a custom type. Defaults to None. + ``Runnable`` with a custom type. Defaults to None. **other_kwargs: Unpacked into the base class. - """ # noqa: E501 + """ super().__init__( bound=bound, kwargs=kwargs or {}, @@ -5747,9 +5811,11 @@ class RunnableBinding(RunnableBindingBase[Input, Output]): # type: ignore[no-re These methods include: - ``bind``: Bind kwargs to pass to the underlying ``Runnable`` when running it. - - ``with_config``: Bind config to pass to the underlying ``Runnable`` when running it. + - ``with_config``: Bind config to pass to the underlying ``Runnable`` when running + it. - ``with_listeners``: Bind lifecycle listeners to the underlying ``Runnable``. - - ``with_types``: Override the input and output types of the underlying ``Runnable``. + - ``with_types``: Override the input and output types of the underlying + ``Runnable``. - ``with_retry``: Bind a retry policy to the underlying ``Runnable``. - ``with_fallbacks``: Bind a fallback policy to the underlying ``Runnable``. @@ -5761,12 +5827,13 @@ class RunnableBinding(RunnableBindingBase[Input, Output]): # type: ignore[no-re # Create a Runnable binding that invokes the ChatModel with the # additional kwarg `stop=['-']` when running it. from langchain_community.chat_models import ChatOpenAI + model = ChatOpenAI() - model.invoke('Say "Parrot-MAGIC"', stop=['-']) # Should return `Parrot` + model.invoke('Say "Parrot-MAGIC"', stop=["-"]) # Should return `Parrot` # Using it the easy way via `bind` method which returns a new # RunnableBinding - runnable_binding = model.bind(stop=['-']) - runnable_binding.invoke('Say "Parrot-MAGIC"') # Should return `Parrot` + runnable_binding = model.bind(stop=["-"]) + runnable_binding.invoke('Say "Parrot-MAGIC"') # Should return `Parrot` Can also be done by instantiating a ``RunnableBinding`` directly (not recommended): @@ -5774,13 +5841,14 @@ class RunnableBinding(RunnableBindingBase[Input, Output]): # type: ignore[no-re .. code-block:: python from langchain_core.runnables import RunnableBinding + runnable_binding = RunnableBinding( bound=model, - kwargs={'stop': ['-']} # <-- Note the additional kwargs + kwargs={"stop": ["-"]}, # <-- Note the additional kwargs ) - runnable_binding.invoke('Say "Parrot-MAGIC"') # Should return `Parrot` + runnable_binding.invoke('Say "Parrot-MAGIC"') # Should return `Parrot` - """ # noqa: E501 + """ @override def bind(self, **kwargs: Any) -> Runnable[Input, Output]: @@ -6053,6 +6121,7 @@ def chain( from langchain_core.prompts import PromptTemplate from langchain_openai import OpenAI + @chain def my_func(fields): prompt = PromptTemplate("Hello, {name}!") diff --git a/libs/core/langchain_core/runnables/branch.py b/libs/core/langchain_core/runnables/branch.py index f0975523e15..cecc8f34b5f 100644 --- a/libs/core/langchain_core/runnables/branch.py +++ b/libs/core/langchain_core/runnables/branch.py @@ -61,8 +61,8 @@ class RunnableBranch(RunnableSerializable[Input, Output]): lambda x: "goodbye", ) - branch.invoke("hello") # "HELLO" - branch.invoke(None) # "goodbye" + branch.invoke("hello") # "HELLO" + branch.invoke(None) # "goodbye" """ diff --git a/libs/core/langchain_core/runnables/configurable.py b/libs/core/langchain_core/runnables/configurable.py index eaf1b3d8c9a..a0f9f53a06d 100644 --- a/libs/core/langchain_core/runnables/configurable.py +++ b/libs/core/langchain_core/runnables/configurable.py @@ -501,7 +501,7 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): ).configurable_alternatives( ConfigurableField(id="prompt"), default_key="joke", - poem=PromptTemplate.from_template("Write a short poem about {topic}") + poem=PromptTemplate.from_template("Write a short poem about {topic}"), ) # When invoking the created RunnableSequence, you can pass in the @@ -511,7 +511,9 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): # The `with_config` method brings in the desired Prompt Runnable in your # Runnable Sequence. - chain.with_config(configurable={"prompt": "poem"}).invoke({"topic": "bears"}) + chain.with_config(configurable={"prompt": "poem"}).invoke( + {"topic": "bears"} + ) Equivalently, you can initialize RunnableConfigurableAlternatives directly @@ -520,20 +522,28 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): .. code-block:: python from langchain_core.runnables import ConfigurableField - from langchain_core.runnables.configurable import RunnableConfigurableAlternatives + from langchain_core.runnables.configurable import ( + RunnableConfigurableAlternatives, + ) from langchain_openai import ChatOpenAI prompt = RunnableConfigurableAlternatives( - which=ConfigurableField(id='prompt'), + which=ConfigurableField(id="prompt"), default=PromptTemplate.from_template("Tell me a joke about {topic}"), - default_key='joke', + default_key="joke", prefix_keys=False, - alternatives={"poem":PromptTemplate.from_template("Write a short poem about {topic}")} + alternatives={ + "poem": PromptTemplate.from_template( + "Write a short poem about {topic}" + ) + }, ) chain = prompt | ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0) - chain.with_config(configurable={"prompt": "poem"}).invoke({"topic": "bears"}) + chain.with_config(configurable={"prompt": "poem"}).invoke( + {"topic": "bears"} + ) - """ # noqa: E501 + """ which: ConfigurableField """The ConfigurableField to use to choose between alternatives.""" @@ -680,7 +690,10 @@ def make_options_spec( spec: Union[ConfigurableFieldSingleOption, ConfigurableFieldMultiOption], description: Optional[str], ) -> ConfigurableFieldSpec: - """Make a ConfigurableFieldSpec for a ConfigurableFieldSingleOption or ConfigurableFieldMultiOption. + """Make options spec. + + Make a ConfigurableFieldSpec for a ConfigurableFieldSingleOption or + ConfigurableFieldMultiOption. Args: spec: The ConfigurableFieldSingleOption or ConfigurableFieldMultiOption. @@ -688,7 +701,7 @@ def make_options_spec( Returns: The ConfigurableFieldSpec. - """ # noqa: E501 + """ with _enums_for_spec_lock: if enum := _enums_for_spec.get(spec): pass diff --git a/libs/core/langchain_core/runnables/fallbacks.py b/libs/core/langchain_core/runnables/fallbacks.py index ab280790c8e..7b0b845c206 100644 --- a/libs/core/langchain_core/runnables/fallbacks.py +++ b/libs/core/langchain_core/runnables/fallbacks.py @@ -56,12 +56,12 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): from langchain_core.chat_models.openai import ChatOpenAI from langchain_core.chat_models.anthropic import ChatAnthropic - model = ChatAnthropic( - model="claude-3-haiku-20240307" - ).with_fallbacks([ChatOpenAI(model="gpt-3.5-turbo-0125")]) + model = ChatAnthropic(model="claude-3-haiku-20240307").with_fallbacks( + [ChatOpenAI(model="gpt-3.5-turbo-0125")] + ) # Will usually use ChatAnthropic, but fallback to ChatOpenAI # if ChatAnthropic fails. - model.invoke('hello') + model.invoke("hello") # And you can also use fallbacks at the level of a chain. # Here if both LLM providers fail, we'll fallback to a good hardcoded @@ -71,12 +71,16 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): from langchain_core.output_parser import StrOutputParser from langchain_core.runnables import RunnableLambda + def when_all_is_lost(inputs): - return ("Looks like our LLM providers are down. " - "Here's a nice 🦜️ emoji for you instead.") + return ( + "Looks like our LLM providers are down. " + "Here's a nice 🦜️ emoji for you instead." + ) + chain_with_fallback = ( - PromptTemplate.from_template('Tell me a joke about {topic}') + PromptTemplate.from_template("Tell me a joke about {topic}") | model | StrOutputParser() ).with_fallbacks([RunnableLambda(when_all_is_lost)]) diff --git a/libs/core/langchain_core/runnables/history.py b/libs/core/langchain_core/runnables/history.py index 42a206b9ae7..e838ee1e16f 100644 --- a/libs/core/langchain_core/runnables/history.py +++ b/libs/core/langchain_core/runnables/history.py @@ -145,11 +145,13 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] from langchain_core.runnables.history import RunnableWithMessageHistory - prompt = ChatPromptTemplate.from_messages([ - ("system", "You're an assistant who's good at {ability}"), - MessagesPlaceholder(variable_name="history"), - ("human", "{question}"), - ]) + prompt = ChatPromptTemplate.from_messages( + [ + ("system", "You're an assistant who's good at {ability}"), + MessagesPlaceholder(variable_name="history"), + ("human", "{question}"), + ] + ) chain = prompt | ChatAnthropic(model="claude-2") @@ -162,18 +164,22 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] history_messages_key="history", ) - print(chain_with_history.invoke( # noqa: T201 - {"ability": "math", "question": "What does cosine mean?"}, - config={"configurable": {"session_id": "foo"}} - )) + print( + chain_with_history.invoke( # noqa: T201 + {"ability": "math", "question": "What does cosine mean?"}, + config={"configurable": {"session_id": "foo"}}, + ) + ) # Uses the store defined in the example above. print(store) # noqa: T201 - print(chain_with_history.invoke( # noqa: T201 - {"ability": "math", "question": "What's its inverse"}, - config={"configurable": {"session_id": "foo"}} - )) + print( + chain_with_history.invoke( # noqa: T201 + {"ability": "math", "question": "What's its inverse"}, + config={"configurable": {"session_id": "foo"}}, + ) + ) print(store) # noqa: T201 @@ -184,6 +190,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] store = {} + def get_session_history( user_id: str, conversation_id: str ) -> BaseChatMessageHistory: @@ -191,11 +198,14 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] store[(user_id, conversation_id)] = InMemoryHistory() return store[(user_id, conversation_id)] - prompt = ChatPromptTemplate.from_messages([ - ("system", "You're an assistant who's good at {ability}"), - MessagesPlaceholder(variable_name="history"), - ("human", "{question}"), - ]) + + prompt = ChatPromptTemplate.from_messages( + [ + ("system", "You're an assistant who's good at {ability}"), + MessagesPlaceholder(variable_name="history"), + ("human", "{question}"), + ] + ) chain = prompt | ChatAnthropic(model="claude-2") @@ -226,7 +236,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] with_message_history.invoke( {"ability": "math", "question": "What does cosine mean?"}, - config={"configurable": {"user_id": "123", "conversation_id": "1"}} + config={"configurable": {"user_id": "123", "conversation_id": "1"}}, ) """ @@ -280,11 +290,8 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] .. code-block:: python def get_session_history( - session_id: str, - *, - user_id: Optional[str]=None - ) -> BaseChatMessageHistory: - ... + session_id: str, *, user_id: Optional[str] = None + ) -> BaseChatMessageHistory: ... Or it should take keyword arguments that match the keys of `session_history_config_specs` and return a corresponding @@ -296,8 +303,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] *, user_id: str, thread_id: str, - ) -> BaseChatMessageHistory: - ... + ) -> BaseChatMessageHistory: ... input_messages_key: Must be specified if the base runnable accepts a dict as input. Default is None. diff --git a/libs/core/langchain_core/runnables/passthrough.py b/libs/core/langchain_core/runnables/passthrough.py index 7ca0634dfe9..afc28e54d42 100644 --- a/libs/core/langchain_core/runnables/passthrough.py +++ b/libs/core/langchain_core/runnables/passthrough.py @@ -96,22 +96,22 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]): ) runnable = RunnableParallel( - origin=RunnablePassthrough(), - modified=lambda x: x+1 + origin=RunnablePassthrough(), modified=lambda x: x + 1 ) - runnable.invoke(1) # {'origin': 1, 'modified': 2} + runnable.invoke(1) # {'origin': 1, 'modified': 2} - def fake_llm(prompt: str) -> str: # Fake LLM for the example + def fake_llm(prompt: str) -> str: # Fake LLM for the example return "completion" + chain = RunnableLambda(fake_llm) | { - 'original': RunnablePassthrough(), # Original LLM output - 'parsed': lambda text: text[::-1] # Parsing logic + "original": RunnablePassthrough(), # Original LLM output + "parsed": lambda text: text[::-1], # Parsing logic } - chain.invoke('hello') # {'original': 'completion', 'parsed': 'noitelpmoc'} + chain.invoke("hello") # {'original': 'completion', 'parsed': 'noitelpmoc'} In some cases, it may be useful to pass the input through while adding some keys to the output. In this case, you can use the `assign` method: @@ -120,17 +120,19 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]): from langchain_core.runnables import RunnablePassthrough - def fake_llm(prompt: str) -> str: # Fake LLM for the example + + def fake_llm(prompt: str) -> str: # Fake LLM for the example return "completion" + runnable = { - 'llm1': fake_llm, - 'llm2': fake_llm, + "llm1": fake_llm, + "llm2": fake_llm, } | RunnablePassthrough.assign( - total_chars=lambda inputs: len(inputs['llm1'] + inputs['llm2']) + total_chars=lambda inputs: len(inputs["llm1"] + inputs["llm2"]) ) - runnable.invoke('hello') + runnable.invoke("hello") # {'llm1': 'completion', 'llm2': 'completion', 'total_chars': 20} """ @@ -378,11 +380,15 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]): ) from langchain_core.runnables.base import RunnableLambda + def add_ten(x: dict[str, int]) -> dict[str, int]: return {"added": x["input"] + 10} + mapper = RunnableParallel( - {"add_step": RunnableLambda(add_ten),} + { + "add_step": RunnableLambda(add_ten), + } ) runnable_assign = RunnableAssign(mapper) @@ -688,13 +694,13 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]): from langchain_core.runnables.passthrough import RunnablePick input_data = { - 'name': 'John', - 'age': 30, - 'city': 'New York', - 'country': 'USA' + "name": "John", + "age": 30, + "city": "New York", + "country": "USA", } - runnable = RunnablePick(keys=['name', 'age']) + runnable = RunnablePick(keys=["name", "age"]) output_data = runnable.invoke(input_data) @@ -730,7 +736,8 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]): name = ( name or self.name - or f"RunnablePick<{','.join([self.keys] if isinstance(self.keys, str) else self.keys)}>" # noqa: E501 + or "RunnablePick" + f"<{','.join([self.keys] if isinstance(self.keys, str) else self.keys)}>" ) return super().get_name(suffix, name=name) diff --git a/libs/core/langchain_core/runnables/retry.py b/libs/core/langchain_core/runnables/retry.py index e909b9b175b..d3bb74547b0 100644 --- a/libs/core/langchain_core/runnables/retry.py +++ b/libs/core/langchain_core/runnables/retry.py @@ -66,17 +66,21 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede import time + def foo(input) -> None: '''Fake function that raises an exception.''' raise ValueError(f"Invoking foo failed. At time {time.time()}") + runnable = RunnableLambda(foo) runnable_with_retries = runnable.with_retry( - retry_if_exception_type=(ValueError,), # Retry only on ValueError - wait_exponential_jitter=True, # Add jitter to the exponential backoff - stop_after_attempt=2, # Try twice - exponential_jitter_params={"initial": 2}, # if desired, customize backoff + retry_if_exception_type=(ValueError,), # Retry only on ValueError + wait_exponential_jitter=True, # Add jitter to the exponential backoff + stop_after_attempt=2, # Try twice + exponential_jitter_params={ + "initial": 2 + }, # if desired, customize backoff ) # The method invocation above is equivalent to the longer form below: @@ -111,7 +115,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede chain = template | model retryable_chain = chain.with_retry() - """ # noqa: E501 + """ retry_exception_types: tuple[type[BaseException], ...] = (Exception,) """The exception types to retry on. By default all exceptions are retried. diff --git a/libs/core/langchain_core/runnables/schema.py b/libs/core/langchain_core/runnables/schema.py index 1ec2c58a48f..3d6471022b8 100644 --- a/libs/core/langchain_core/runnables/schema.py +++ b/libs/core/langchain_core/runnables/schema.py @@ -51,9 +51,11 @@ class BaseStreamEvent(TypedDict): from langchain_core.runnables import RunnableLambda + async def reverse(s: str) -> str: return s[::-1] + chain = RunnableLambda(func=reverse) events = [event async for event in chain.astream_events("hello")] diff --git a/libs/core/langchain_core/stores.py b/libs/core/langchain_core/stores.py index 24ab0ea74d6..e6df8fd93eb 100644 --- a/libs/core/langchain_core/stores.py +++ b/libs/core/langchain_core/stores.py @@ -52,8 +52,8 @@ class BaseStore(ABC, Generic[K, V]): from langchain.storage import BaseStore - class MyInMemoryStore(BaseStore[str, int]): + class MyInMemoryStore(BaseStore[str, int]): def __init__(self): self.store = {} @@ -295,13 +295,13 @@ class InMemoryStore(InMemoryBaseStore[Any]): from langchain.storage import InMemoryStore store = InMemoryStore() - store.mset([('key1', 'value1'), ('key2', 'value2')]) - store.mget(['key1', 'key2']) + store.mset([("key1", "value1"), ("key2", "value2")]) + store.mget(["key1", "key2"]) # ['value1', 'value2'] - store.mdelete(['key1']) + store.mdelete(["key1"]) list(store.yield_keys()) # ['key2'] - list(store.yield_keys(prefix='k')) + list(store.yield_keys(prefix="k")) # ['key2'] """ @@ -321,13 +321,13 @@ class InMemoryByteStore(InMemoryBaseStore[bytes]): from langchain.storage import InMemoryByteStore store = InMemoryByteStore() - store.mset([('key1', b'value1'), ('key2', b'value2')]) - store.mget(['key1', 'key2']) + store.mset([("key1", b"value1"), ("key2", b"value2")]) + store.mget(["key1", "key2"]) # [b'value1', b'value2'] - store.mdelete(['key1']) + store.mdelete(["key1"]) list(store.yield_keys()) # ['key2'] - list(store.yield_keys(prefix='k')) + list(store.yield_keys(prefix="k")) # ['key2'] """ diff --git a/libs/core/langchain_core/sys_info.py b/libs/core/langchain_core/sys_info.py index 96deed97dd1..b7073ffb9cd 100644 --- a/libs/core/langchain_core/sys_info.py +++ b/libs/core/langchain_core/sys_info.py @@ -1,4 +1,8 @@ -"""**sys_info** prints information about the system and langchain packages for debugging purposes.""" # noqa: E501 +"""**sys_info** implementation. + +sys_info prints information about the system and langchain packages for +debugging purposes. +""" from collections.abc import Sequence diff --git a/libs/core/langchain_core/tools/convert.py b/libs/core/langchain_core/tools/convert.py index 8b103fd54d6..2693ce80150 100644 --- a/libs/core/langchain_core/tools/convert.py +++ b/libs/core/langchain_core/tools/convert.py @@ -134,11 +134,13 @@ def tool( # Searches the API for the query. return + @tool("search", return_direct=True) def search_api(query: str) -> str: # Searches the API for the query. return + @tool(response_format="content_and_artifact") def search_api(query: str) -> tuple[str, dict]: return "partial json of results", {"full": "object of results"} @@ -171,18 +173,15 @@ def tool( "bar": { "title": "Bar", "description": "The bar.", - "type": "string" + "type": "string", }, "baz": { "title": "Baz", "description": "The baz.", - "type": "integer" - } + "type": "integer", + }, }, - "required": [ - "bar", - "baz" - ] + "required": ["bar", "baz"], } Note that parsing by default will raise ``ValueError`` if the docstring diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index acc50e7acdd..61849113d1b 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -672,8 +672,10 @@ def tool_example_to_messages( from pydantic import BaseModel, Field from langchain_openai import ChatOpenAI + class Person(BaseModel): '''Information about a person.''' + name: Optional[str] = Field(..., description="The name of the person") hair_color: Optional[str] = Field( ..., description="The color of the person's hair if known" @@ -682,6 +684,7 @@ def tool_example_to_messages( ..., description="Height in METERS" ) + examples = [ ( "The ocean is vast and blue. It's more than 20,000 feet deep.", @@ -697,9 +700,7 @@ def tool_example_to_messages( messages = [] for txt, tool_call in examples: - messages.extend( - tool_example_to_messages(txt, [tool_call]) - ) + messages.extend(tool_example_to_messages(txt, [tool_call])) """ messages: list[BaseMessage] = [HumanMessage(content=input)] diff --git a/libs/core/langchain_core/vectorstores/base.py b/libs/core/langchain_core/vectorstores/base.py index c6bfc467260..17fa6592c72 100644 --- a/libs/core/langchain_core/vectorstores/base.py +++ b/libs/core/langchain_core/vectorstores/base.py @@ -969,30 +969,28 @@ class VectorStore(ABC): # Retrieve more documents with higher diversity # Useful if your dataset has many similar documents docsearch.as_retriever( - search_type="mmr", - search_kwargs={'k': 6, 'lambda_mult': 0.25} + search_type="mmr", search_kwargs={"k": 6, "lambda_mult": 0.25} ) # Fetch more documents for the MMR algorithm to consider # But only return the top 5 docsearch.as_retriever( - search_type="mmr", - search_kwargs={'k': 5, 'fetch_k': 50} + search_type="mmr", search_kwargs={"k": 5, "fetch_k": 50} ) # Only retrieve documents that have a relevance score # Above a certain threshold docsearch.as_retriever( search_type="similarity_score_threshold", - search_kwargs={'score_threshold': 0.8} + search_kwargs={"score_threshold": 0.8}, ) # Only get the single most similar document from the dataset - docsearch.as_retriever(search_kwargs={'k': 1}) + docsearch.as_retriever(search_kwargs={"k": 1}) # Use a filter to only retrieve documents from a specific paper docsearch.as_retriever( - search_kwargs={'filter': {'paper_title':'GPT-4 Technical Report'}} + search_kwargs={"filter": {"paper_title": "GPT-4 Technical Report"}} ) """ diff --git a/libs/core/langchain_core/vectorstores/in_memory.py b/libs/core/langchain_core/vectorstores/in_memory.py index 23eb4127084..e7787f8a882 100644 --- a/libs/core/langchain_core/vectorstores/in_memory.py +++ b/libs/core/langchain_core/vectorstores/in_memory.py @@ -83,7 +83,7 @@ class InMemoryVectorStore(VectorStore): Search: .. code-block:: python - results = vector_store.similarity_search(query="thud",k=1) + results = vector_store.similarity_search(query="thud", k=1) for doc in results: print(f"* {doc.page_content} [{doc.metadata}]") @@ -97,6 +97,7 @@ class InMemoryVectorStore(VectorStore): def _filter_function(doc: Document) -> bool: return doc.metadata.get("bar") == "baz" + results = vector_store.similarity_search( query="thud", k=1, filter=_filter_function ) @@ -111,9 +112,7 @@ class InMemoryVectorStore(VectorStore): Search with score: .. code-block:: python - results = vector_store.similarity_search_with_score( - query="qux", k=1 - ) + results = vector_store.similarity_search_with_score(query="qux", k=1) for doc, score in results: print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]") @@ -135,7 +134,7 @@ class InMemoryVectorStore(VectorStore): # search with score results = await vector_store.asimilarity_search_with_score(query="qux", k=1) - for doc,score in results: + for doc, score in results: print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]") .. code-block:: none diff --git a/libs/core/pyproject.toml b/libs/core/pyproject.toml index 14b8bfbaa2e..1ea42cee123 100644 --- a/libs/core/pyproject.toml +++ b/libs/core/pyproject.toml @@ -77,6 +77,8 @@ warn_return_any = "False" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true [tool.ruff.lint] select = [ "ALL",] diff --git a/libs/core/tests/unit_tests/conftest.py b/libs/core/tests/unit_tests/conftest.py index aceca3156b8..83f39adc1c1 100644 --- a/libs/core/tests/unit_tests/conftest.py +++ b/libs/core/tests/unit_tests/conftest.py @@ -64,8 +64,7 @@ def pytest_collection_modifyitems( .. code-block:: python @pytest.mark.requires("package1", "package2") - def test_something(): - ... + def test_something(): ... """ # Mapping from the name of a package to whether it is installed or not. diff --git a/libs/core/tests/unit_tests/prompts/__snapshots__/test_chat.ambr b/libs/core/tests/unit_tests/prompts/__snapshots__/test_chat.ambr index 7c07416fe5d..c851464cd5b 100644 --- a/libs/core/tests/unit_tests/prompts/__snapshots__/test_chat.ambr +++ b/libs/core/tests/unit_tests/prompts/__snapshots__/test_chat.ambr @@ -526,12 +526,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -834,12 +830,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -990,11 +982,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -1046,12 +1034,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -1127,7 +1115,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -1140,7 +1128,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -1148,7 +1137,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -1338,7 +1327,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -1958,12 +1947,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -2266,12 +2251,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -2422,11 +2403,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -2478,12 +2455,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -2559,7 +2536,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -2572,7 +2549,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -2580,7 +2558,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -2770,7 +2748,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 diff --git a/libs/core/tests/unit_tests/runnables/__snapshots__/test_graph.ambr b/libs/core/tests/unit_tests/runnables/__snapshots__/test_graph.ambr index a788c425fce..a7dcec5b72b 100644 --- a/libs/core/tests/unit_tests/runnables/__snapshots__/test_graph.ambr +++ b/libs/core/tests/unit_tests/runnables/__snapshots__/test_graph.ambr @@ -929,12 +929,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -1237,12 +1233,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -1393,11 +1385,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -1449,12 +1437,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -1530,7 +1518,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -1543,7 +1531,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -1551,7 +1540,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -1741,7 +1730,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 diff --git a/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr b/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr index 079e4909061..4cd36110b0e 100644 --- a/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr +++ b/libs/core/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr @@ -2476,12 +2476,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -2781,12 +2777,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -2935,11 +2927,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -2990,12 +2978,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -3070,7 +3058,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -3083,7 +3071,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -3091,7 +3080,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -3279,7 +3268,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -3952,12 +3941,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -4276,12 +4261,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -4430,11 +4411,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -4485,12 +4462,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -4565,7 +4542,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -4578,7 +4555,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -4586,7 +4564,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -4774,7 +4752,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -5459,12 +5437,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -5783,12 +5757,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -5937,11 +5907,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -5992,12 +5958,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -6072,7 +6038,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -6085,7 +6051,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -6093,7 +6060,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -6281,7 +6248,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -6841,12 +6808,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -7146,12 +7109,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -7300,11 +7259,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -7355,12 +7310,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -7435,7 +7390,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -7448,7 +7403,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -7456,7 +7412,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -7644,7 +7600,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -8359,12 +8315,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -8683,12 +8635,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -8837,11 +8785,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -8892,12 +8836,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -8972,7 +8916,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -8985,7 +8929,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -8993,7 +8938,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -9181,7 +9126,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -9786,12 +9731,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -10091,12 +10032,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -10245,11 +10182,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -10300,12 +10233,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -10380,7 +10313,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -10393,7 +10326,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -10401,7 +10335,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -10589,7 +10523,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -11212,12 +11146,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -11547,12 +11477,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -11701,11 +11627,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -11756,12 +11678,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -11836,7 +11758,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -11849,7 +11771,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -11857,7 +11780,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -12045,7 +11968,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 @@ -12680,12 +12603,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Instantiate a chat model and invoke it with the messages @@ -13004,12 +12923,8 @@ from langchain_core.messages import HumanMessage, SystemMessage messages = [ - SystemMessage( - content="You are a helpful assistant! Your name is Bob." - ), - HumanMessage( - content="What is your name?" - ) + SystemMessage(content="You are a helpful assistant! Your name is Bob."), + HumanMessage(content="What is your name?"), ] # Define a chat model and invoke it with the messages @@ -13158,11 +13073,7 @@ .. code-block:: python - { - "name": "foo", - "args": {"a": 1}, - "id": "123" - } + {"name": "foo", "args": {"a": 1}, "id": "123"} This represents a request to call the tool named "foo" with arguments {"a": 1} and an identifier of "123". @@ -13213,12 +13124,12 @@ .. code-block:: python left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)] - right_chunks = [ToolCallChunk(name=None, args='1}', index=0)] + right_chunks = [ToolCallChunk(name=None, args="1}", index=0)] ( AIMessageChunk(content="", tool_call_chunks=left_chunks) + AIMessageChunk(content="", tool_call_chunks=right_chunks) - ).tool_call_chunks == [ToolCallChunk(name='foo', args='{"a":1}', index=0)] + ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)] ''', 'properties': dict({ 'args': dict({ @@ -13293,7 +13204,7 @@ from langchain_core.messages import ToolMessage - ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL') + ToolMessage(content="42", tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL") Example: A ToolMessage where only part of the tool output is sent to the model @@ -13306,7 +13217,8 @@ from langchain_core.messages import ToolMessage tool_output = { - "stdout": "From the graph we can see that the correlation between x and y is ...", + "stdout": "From the graph we can see that the correlation between " + "x and y is ...", "stderr": None, "artifacts": {"type": "image", "base64_data": "/9j/4gIcSU..."}, } @@ -13314,7 +13226,7 @@ ToolMessage( content=tool_output["stdout"], artifact=tool_output, - tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL', + tool_call_id="call_Jja7J89XsjrOLA5r!MEOW!SL", ) The tool_call_id field is used to associate the tool call request with the @@ -13502,7 +13414,7 @@ "output_token_details": { "audio": 10, "reasoning": 200, - } + }, } .. versionchanged:: 0.3.9 diff --git a/libs/core/tests/unit_tests/runnables/test_runnable.py b/libs/core/tests/unit_tests/runnables/test_runnable.py index d9a9db349e8..5c33c5a99c4 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable.py @@ -314,14 +314,11 @@ def test_schemas(snapshot: SnapshotAssertion) -> None: "\n" " .. code-block:: python\n" "\n" - " from langchain_core.documents " - "import Document\n" + " from langchain_core.documents import Document\n" "\n" " document = Document(\n" - ' page_content="Hello, ' - 'world!",\n' - ' metadata={"source": ' - '"https://example.com"}\n' + ' page_content="Hello, world!", ' + 'metadata={"source": "https://example.com"}\n' " )", "properties": { "id": { diff --git a/libs/core/uv.lock b/libs/core/uv.lock index a4bb351a562..0b0c16552d2 100644 --- a/libs/core/uv.lock +++ b/libs/core/uv.lock @@ -1174,7 +1174,8 @@ test = [{ name = "langchain-core", editable = "." }] test-integration = [] typing = [ { name = "langchain-core", editable = "." }, - { name = "mypy", specifier = ">=1.17.1,<2" }, + { name = "mypy", specifier = ">=1.17.1,<1.18" }, + { name = "types-pyyaml", specifier = ">=6.0.12.2,<7.0.0.0" }, ] [[package]] @@ -1217,9 +1218,10 @@ test-integration = [ { name = "transformers", specifier = ">=4.51.3,<5.0.0" }, ] typing = [ + { name = "beautifulsoup4", specifier = ">=4.13.5,<5.0.0" }, { name = "lxml-stubs", specifier = ">=0.5.1,<1.0.0" }, { name = "mypy", specifier = ">=1.17.1,<1.18" }, - { name = "tiktoken", specifier = ">=0.8.0,<1.0.0" }, + { name = "tiktoken", specifier = ">=0.11.0,<1.0.0" }, { name = "types-requests", specifier = ">=2.31.0.20240218,<3.0.0.0" }, ] diff --git a/libs/langchain_v1/langchain/__init__.py b/libs/langchain_v1/langchain/__init__.py index d3d37dc36db..2455640fc22 100644 --- a/libs/langchain_v1/langchain/__init__.py +++ b/libs/langchain_v1/langchain/__init__.py @@ -2,7 +2,7 @@ from typing import Any -__version__ = "1.0.0a3" +__version__ = "1.0.0a4" def __getattr__(name: str) -> Any: # noqa: ANN401 From f589168411d51695dd6b99231f667ca096dda8f0 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 17:16:13 +0200 Subject: [PATCH 25/30] refactor(core): use pytest style in `TestGetBufferString` (#32786) Co-authored-by: Mason Daugherty --- libs/core/tests/unit_tests/test_messages.py | 60 +++++++++------------ 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/libs/core/tests/unit_tests/test_messages.py b/libs/core/tests/unit_tests/test_messages.py index 807f52ae10d..b1df4955232 100644 --- a/libs/core/tests/unit_tests/test_messages.py +++ b/libs/core/tests/unit_tests/test_messages.py @@ -1,4 +1,3 @@ -import unittest import uuid from typing import Optional, Union @@ -335,54 +334,45 @@ def test_ai_message_chunks() -> None: ) -class TestGetBufferString(unittest.TestCase): - def setUp(self) -> None: - self.human_msg = HumanMessage(content="human") - self.ai_msg = AIMessage(content="ai") - self.sys_msg = SystemMessage(content="system") - self.func_msg = FunctionMessage(name="func", content="function") - self.tool_msg = ToolMessage(tool_call_id="tool_id", content="tool") - self.chat_msg = ChatMessage(role="Chat", content="chat") - self.tool_calls_msg = AIMessage(content="tool") +class TestGetBufferString: + _HUMAN_MSG = HumanMessage(content="human") + _AI_MSG = AIMessage(content="ai") def test_empty_input(self) -> None: assert get_buffer_string([]) == "" def test_valid_single_message(self) -> None: - expected_output = f"Human: {self.human_msg.content}" - assert get_buffer_string([self.human_msg]) == expected_output + expected_output = "Human: human" + assert get_buffer_string([self._HUMAN_MSG]) == expected_output def test_custom_human_prefix(self) -> None: - prefix = "H" - expected_output = f"{prefix}: {self.human_msg.content}" - assert get_buffer_string([self.human_msg], human_prefix="H") == expected_output + expected_output = "H: human" + assert get_buffer_string([self._HUMAN_MSG], human_prefix="H") == expected_output def test_custom_ai_prefix(self) -> None: - prefix = "A" - expected_output = f"{prefix}: {self.ai_msg.content}" - assert get_buffer_string([self.ai_msg], ai_prefix="A") == expected_output + expected_output = "A: ai" + assert get_buffer_string([self._AI_MSG], ai_prefix="A") == expected_output def test_multiple_msg(self) -> None: msgs = [ - self.human_msg, - self.ai_msg, - self.sys_msg, - self.func_msg, - self.tool_msg, - self.chat_msg, - self.tool_calls_msg, + self._HUMAN_MSG, + self._AI_MSG, + SystemMessage(content="system"), + FunctionMessage(name="func", content="function"), + ToolMessage(tool_call_id="tool_id", content="tool"), + ChatMessage(role="Chat", content="chat"), + AIMessage(content="tool"), ] - expected_output = "\n".join( # noqa: FLY002 - [ - "Human: human", - "AI: ai", - "System: system", - "Function: function", - "Tool: tool", - "Chat: chat", - "AI: tool", - ] + expected_output = ( + "Human: human\n" + "AI: ai\n" + "System: system\n" + "Function: function\n" + "Tool: tool\n" + "Chat: chat\n" + "AI: tool" ) + assert get_buffer_string(msgs) == expected_output From 4024d47412e6fdb184f2c27959c8e95f897e4e83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 11:27:54 -0400 Subject: [PATCH 26/30] chore(infra): bump `actions/setup-python` from 5 to 6 (#32842) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
Release notes

Sourced from actions/setup-python's releases.

v6.0.0

What's Changed

Breaking Changes

Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. See Release Notes

Enhancements:

Bug fixes:

Dependency updates:

New Contributors

Full Changelog: https://github.com/actions/setup-python/compare/v5...v6.0.0

v5.6.0

What's Changed

Full Changelog: https://github.com/actions/setup-python/compare/v5...v5.6.0

v5.5.0

What's Changed

Enhancements:

Bug fixes:

... (truncated)

Commits
  • e797f83 Upgrade to node 24 (#1164)
  • 3d1e2d2 Revert "Enhance cache-dependency-path handling to support files outside the w...
  • 65b0712 Clarify pythonLocation behavior for PyPy and GraalPy in environment variables...
  • 5b668cf Bump actions/checkout from 4 to 5 (#1181)
  • f62a0e2 Change missing cache directory error to warning (#1182)
  • 9322b3c Upgrade setuptools to 78.1.1 to fix path traversal vulnerability in PackageIn...
  • fbeb884 Bump form-data to fix critical vulnerabilities #182 & #183 (#1163)
  • 03bb615 Bump idna from 2.9 to 3.7 in /tests/data (#843)
  • 36da51d Add version parsing from Pipfile (#1067)
  • 3c6f142 update documentation (#1156)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-python&package-manager=github_actions&previous-version=5&new-version=6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/api_doc_build.yml | 2 +- .github/workflows/check_diffs.yml | 2 +- .github/workflows/check_new_docs.yml | 2 +- .github/workflows/codspeed.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/api_doc_build.yml b/.github/workflows/api_doc_build.yml index 3cd664a4beb..0702dc57c6e 100644 --- a/.github/workflows/api_doc_build.yml +++ b/.github/workflows/api_doc_build.yml @@ -72,7 +72,7 @@ jobs: done - name: '🐍 Setup Python ${{ env.PYTHON_VERSION }}' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 id: setup-python with: python-version: ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/check_diffs.yml b/.github/workflows/check_diffs.yml index ced20078937..33a17c9780a 100644 --- a/.github/workflows/check_diffs.yml +++ b/.github/workflows/check_diffs.yml @@ -35,7 +35,7 @@ jobs: - name: '📋 Checkout Code' uses: actions/checkout@v5 - name: '🐍 Setup Python 3.11' - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.11' - name: '📂 Get Changed Files' diff --git a/.github/workflows/check_new_docs.yml b/.github/workflows/check_new_docs.yml index 1df3ac9f504..cf988ba1153 100644 --- a/.github/workflows/check_new_docs.yml +++ b/.github/workflows/check_new_docs.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.10' - id: files diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 089f019074d..ae942ea9c98 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -44,7 +44,7 @@ jobs: with: python-version: "3.12" - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.12" From f4e83e0ad8d12bec889fb3b96ffedec183bf5267 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 17:44:15 +0200 Subject: [PATCH 27/30] chore(core): fix some docstrings (from DOC preview rule) (#32833) * Add `Raises` sections * Add `Returns` sections * Add `Yields` sections --------- Co-authored-by: Mason Daugherty --- .../langchain_core/_api/beta_decorator.py | 3 + libs/core/langchain_core/_api/deprecation.py | 12 ++ libs/core/langchain_core/_api/path.py | 21 ++- libs/core/langchain_core/_import_utils.py | 7 + libs/core/langchain_core/agents.py | 8 +- libs/core/langchain_core/callbacks/base.py | 2 +- libs/core/langchain_core/callbacks/manager.py | 66 ++++---- libs/core/langchain_core/callbacks/usage.py | 3 + libs/core/langchain_core/chat_history.py | 3 + .../langchain_core/document_loaders/base.py | 30 +++- .../document_loaders/langsmith.py | 3 + libs/core/langchain_core/documents/base.py | 40 ++++- .../langchain_core/example_selectors/base.py | 12 ++ libs/core/langchain_core/exceptions.py | 7 + libs/core/langchain_core/indexing/api.py | 9 + libs/core/langchain_core/indexing/base.py | 11 +- .../core/langchain_core/indexing/in_memory.py | 26 ++- .../langchain_core/language_models/base.py | 6 + .../language_models/chat_models.py | 65 ++++++- .../language_models/fake_chat_models.py | 12 +- .../langchain_core/language_models/llms.py | 47 ++++- libs/core/langchain_core/load/load.py | 16 +- libs/core/langchain_core/load/serializable.py | 17 +- libs/core/langchain_core/messages/ai.py | 36 +++- libs/core/langchain_core/messages/base.py | 12 +- .../langchain_core/messages/content_blocks.py | 25 ++- libs/core/langchain_core/messages/tool.py | 27 ++- libs/core/langchain_core/messages/utils.py | 4 + .../langchain_core/output_parsers/list.py | 26 +-- .../output_parsers/openai_functions.py | 3 + .../output_parsers/openai_tools.py | 7 +- .../langchain_core/output_parsers/pydantic.py | 4 + .../langchain_core/output_parsers/string.py | 3 +- .../core/langchain_core/output_parsers/xml.py | 3 - .../langchain_core/outputs/chat_generation.py | 25 ++- .../core/langchain_core/outputs/generation.py | 17 +- .../core/langchain_core/outputs/llm_result.py | 9 +- libs/core/langchain_core/prompt_values.py | 14 +- libs/core/langchain_core/prompts/base.py | 11 +- libs/core/langchain_core/prompts/chat.py | 34 +++- libs/core/langchain_core/prompts/dict.py | 24 ++- libs/core/langchain_core/prompts/few_shot.py | 4 +- .../prompts/few_shot_with_templates.py | 6 +- libs/core/langchain_core/prompts/image.py | 17 +- libs/core/langchain_core/prompts/message.py | 8 +- libs/core/langchain_core/prompts/pipeline.py | 6 +- libs/core/langchain_core/prompts/prompt.py | 16 +- libs/core/langchain_core/prompts/string.py | 6 +- .../core/langchain_core/prompts/structured.py | 7 +- libs/core/langchain_core/retrievers.py | 1 + libs/core/langchain_core/runnables/base.py | 160 +++++++++++++++--- libs/core/langchain_core/runnables/branch.py | 14 +- libs/core/langchain_core/runnables/config.py | 9 +- .../langchain_core/runnables/configurable.py | 6 + .../langchain_core/runnables/fallbacks.py | 10 +- libs/core/langchain_core/runnables/graph.py | 14 +- .../langchain_core/runnables/graph_ascii.py | 33 +++- .../langchain_core/runnables/graph_png.py | 18 +- .../langchain_core/runnables/passthrough.py | 20 ++- libs/core/langchain_core/runnables/router.py | 8 +- libs/core/langchain_core/runnables/utils.py | 68 +++----- libs/core/langchain_core/stores.py | 20 +-- libs/core/langchain_core/tools/base.py | 23 ++- libs/core/langchain_core/tools/convert.py | 11 ++ libs/core/langchain_core/tools/simple.py | 38 ++++- libs/core/langchain_core/tools/structured.py | 27 ++- libs/core/langchain_core/tracers/base.py | 4 +- libs/core/langchain_core/tracers/context.py | 6 +- libs/core/langchain_core/tracers/core.py | 110 +++++++++--- .../langchain_core/tracers/event_stream.py | 31 +++- libs/core/langchain_core/tracers/langchain.py | 7 +- .../langchain_core/tracers/langchain_v1.py | 12 +- .../core/langchain_core/tracers/log_stream.py | 56 +++++- libs/core/langchain_core/tracers/schemas.py | 6 +- libs/core/langchain_core/utils/aiter.py | 18 +- libs/core/langchain_core/utils/env.py | 3 + .../langchain_core/utils/function_calling.py | 21 ++- .../langchain_core/utils/interactive_env.py | 6 +- libs/core/langchain_core/utils/iter.py | 14 +- libs/core/langchain_core/utils/json.py | 3 + libs/core/langchain_core/utils/json_schema.py | 7 + libs/core/langchain_core/utils/loading.py | 6 +- libs/core/langchain_core/utils/mustache.py | 37 ++-- libs/core/langchain_core/utils/pydantic.py | 36 +++- libs/core/langchain_core/utils/utils.py | 30 +++- libs/core/langchain_core/vectorstores/base.py | 6 - .../langchain_core/vectorstores/in_memory.py | 2 - 87 files changed, 1281 insertions(+), 400 deletions(-) diff --git a/libs/core/langchain_core/_api/beta_decorator.py b/libs/core/langchain_core/_api/beta_decorator.py index 76955b435f4..786f371ad21 100644 --- a/libs/core/langchain_core/_api/beta_decorator.py +++ b/libs/core/langchain_core/_api/beta_decorator.py @@ -63,6 +63,9 @@ def beta( addendum : str, optional Additional text appended directly to the final message. + Returns: + A decorator which can be used to mark functions or classes as beta. + Examples: .. code-block:: python diff --git a/libs/core/langchain_core/_api/deprecation.py b/libs/core/langchain_core/_api/deprecation.py index dc83afa2d17..7999d8a3216 100644 --- a/libs/core/langchain_core/_api/deprecation.py +++ b/libs/core/langchain_core/_api/deprecation.py @@ -129,6 +129,9 @@ def deprecated( package: str, optional The package of the deprecated object. + Returns: + A decorator to mark a function or class as deprecated. + Examples: .. code-block:: python @@ -544,6 +547,15 @@ def rename_parameter( is passed to *func*, a DeprecationWarning is emitted, and its value is used, even if *new* is also passed by keyword. + Args: + since: The version in which the parameter was renamed. + removal: The version in which the old parameter will be removed. + old: The old parameter name. + new: The new parameter name. + + Returns: + A decorator indicating that a parameter was renamed. + Example: .. code-block:: python diff --git a/libs/core/langchain_core/_api/path.py b/libs/core/langchain_core/_api/path.py index 0589ae44956..0d70b5a23a3 100644 --- a/libs/core/langchain_core/_api/path.py +++ b/libs/core/langchain_core/_api/path.py @@ -12,7 +12,15 @@ SEPARATOR = os.sep def get_relative_path( file: Union[Path, str], *, relative_to: Path = PACKAGE_DIR ) -> str: - """Get the path of the file as a relative path to the package directory.""" + """Get the path of the file as a relative path to the package directory. + + Args: + file: The file path to convert. + relative_to: The base path to make the file path relative to. + + Returns: + The relative path as a string. + """ if isinstance(file, str): file = Path(file) return str(file.relative_to(relative_to)) @@ -24,7 +32,16 @@ def as_import_path( suffix: Optional[str] = None, relative_to: Path = PACKAGE_DIR, ) -> str: - """Path of the file as a LangChain import exclude langchain top namespace.""" + """Path of the file as a LangChain import exclude langchain top namespace. + + Args: + file: The file path to convert. + suffix: An optional suffix to append to the import path. + relative_to: The base path to make the file path relative to. + + Returns: + The import path as a string. + """ if isinstance(file, str): file = Path(file) path = get_relative_path(file, relative_to=relative_to) diff --git a/libs/core/langchain_core/_import_utils.py b/libs/core/langchain_core/_import_utils.py index 6f4d0a5df2b..6e0ce0bbee9 100644 --- a/libs/core/langchain_core/_import_utils.py +++ b/libs/core/langchain_core/_import_utils.py @@ -17,6 +17,13 @@ def import_attr( module_name: The name of the module to import from. If None, the attribute is imported from the package itself. package: The name of the package where the module is located. + + Raises: + ImportError: If the module cannot be found. + AttributeError: If the attribute does not exist in the module or package. + + Returns: + The imported attribute. """ if module_name == "__module__" or module_name is None: try: diff --git a/libs/core/langchain_core/agents.py b/libs/core/langchain_core/agents.py index 8fa3fde3888..dae02a86f13 100644 --- a/libs/core/langchain_core/agents.py +++ b/libs/core/langchain_core/agents.py @@ -86,7 +86,8 @@ class AgentAction(Serializable): def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default is ["langchain", "schema", "agent"]. + Returns: + ``["langchain", "schema", "agent"]`` """ return ["langchain", "schema", "agent"] @@ -155,14 +156,15 @@ class AgentFinish(Serializable): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether or not the class is serializable.""" + """Return True as this class is serializable.""" return True @classmethod def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default namespace is ["langchain", "schema", "agent"]. + Returns: + ``["langchain", "schema", "agent"]`` """ return ["langchain", "schema", "agent"] diff --git a/libs/core/langchain_core/callbacks/base.py b/libs/core/langchain_core/callbacks/base.py index 68c4e4a254b..3f3fd178cfd 100644 --- a/libs/core/langchain_core/callbacks/base.py +++ b/libs/core/langchain_core/callbacks/base.py @@ -922,7 +922,7 @@ class BaseCallbackManager(CallbackManagerMixin): self.inheritable_metadata = inheritable_metadata or {} def copy(self) -> Self: - """Copy the callback manager.""" + """Return a copy of the callback manager.""" return self.__class__( handlers=self.handlers.copy(), inheritable_handlers=self.inheritable_handlers.copy(), diff --git a/libs/core/langchain_core/callbacks/manager.py b/libs/core/langchain_core/callbacks/manager.py index 8498995f86d..4851a1c1c1d 100644 --- a/libs/core/langchain_core/callbacks/manager.py +++ b/libs/core/langchain_core/callbacks/manager.py @@ -88,8 +88,8 @@ def trace_as_chain_group( Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in LangSmith. - Returns: - CallbackManagerForChainGroup: The callback manager for the chain group. + Yields: + The callback manager for the chain group. Example: .. code-block:: python @@ -170,8 +170,8 @@ async def atrace_as_chain_group( metadata (dict[str, Any], optional): The metadata to apply to all runs. Defaults to None. - Returns: - AsyncCallbackManager: The async callback manager for the chain group. + Yields: + The async callback manager for the chain group. .. note: Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in @@ -519,15 +519,12 @@ class RunManager(BaseRunManager): self, text: str, **kwargs: Any, - ) -> Any: + ) -> None: """Run when a text is received. Args: text (str): The received text. **kwargs (Any): Additional keyword arguments. - - Returns: - Any: The result of the callback. """ if not self.handlers: return @@ -607,16 +604,12 @@ class AsyncRunManager(BaseRunManager, ABC): self, text: str, **kwargs: Any, - ) -> Any: + ) -> None: """Run when a text is received. Args: text (str): The received text. **kwargs (Any): Additional keyword arguments. - - Returns: - Any: The result of the callback. - """ if not self.handlers: return @@ -914,16 +907,12 @@ class CallbackManagerForChainRun(ParentRunManager, ChainManagerMixin): **kwargs, ) - def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: + def on_agent_action(self, action: AgentAction, **kwargs: Any) -> None: """Run when agent action is received. Args: action (AgentAction): The agent action. **kwargs (Any): Additional keyword arguments. - - Returns: - Any: The result of the callback. - """ if not self.handlers: return @@ -938,16 +927,12 @@ class CallbackManagerForChainRun(ParentRunManager, ChainManagerMixin): **kwargs, ) - def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any: + def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None: """Run when agent finish is received. Args: finish (AgentFinish): The agent finish. **kwargs (Any): Additional keyword arguments. - - Returns: - Any: The result of the callback. - """ if not self.handlers: return @@ -1033,16 +1018,12 @@ class AsyncCallbackManagerForChainRun(AsyncParentRunManager, ChainManagerMixin): **kwargs, ) - async def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: + async def on_agent_action(self, action: AgentAction, **kwargs: Any) -> None: """Run when agent action is received. Args: action (AgentAction): The agent action. **kwargs (Any): Additional keyword arguments. - - Returns: - Any: The result of the callback. - """ if not self.handlers: return @@ -1057,16 +1038,12 @@ class AsyncCallbackManagerForChainRun(AsyncParentRunManager, ChainManagerMixin): **kwargs, ) - async def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any: + async def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None: """Run when agent finish is received. Args: finish (AgentFinish): The agent finish. **kwargs (Any): Additional keyword arguments. - - Returns: - Any: The result of the callback. - """ if not self.handlers: return @@ -1562,6 +1539,8 @@ class CallbackManager(BaseCallbackManager): parent_run_id (UUID, optional): The ID of the parent run. Defaults to None. **kwargs (Any): Additional keyword arguments. + Returns: + The callback manager for the retriever run. """ if run_id is None: run_id = uuid.uuid4() @@ -1608,6 +1587,9 @@ class CallbackManager(BaseCallbackManager): data: The data for the adhoc event. run_id: The ID of the run. Defaults to None. + Raises: + ValueError: If additional keyword arguments are passed. + .. versionadded:: 0.2.14 """ @@ -1710,8 +1692,8 @@ class CallbackManagerForChainGroup(CallbackManager): self.parent_run_manager = parent_run_manager self.ended = False + @override def copy(self) -> CallbackManagerForChainGroup: - """Copy the callback manager.""" return self.__class__( handlers=self.handlers.copy(), inheritable_handlers=self.inheritable_handlers.copy(), @@ -2099,6 +2081,9 @@ class AsyncCallbackManager(BaseCallbackManager): data: The data for the adhoc event. run_id: The ID of the run. Defaults to None. + Raises: + ValueError: If additional keyword arguments are passed. + .. versionadded:: 0.2.14 """ if not self.handlers: @@ -2249,7 +2234,7 @@ class AsyncCallbackManagerForChainGroup(AsyncCallbackManager): self.ended = False def copy(self) -> AsyncCallbackManagerForChainGroup: - """Copy the async callback manager.""" + """Return a copy the async callback manager.""" return self.__class__( handlers=self.handlers.copy(), inheritable_handlers=self.inheritable_handlers.copy(), @@ -2385,6 +2370,9 @@ def _configure( local_metadata (Optional[dict[str, Any]], optional): The local metadata. Defaults to None. + Raises: + RuntimeError: If `LANGCHAIN_TRACING` is set but `LANGCHAIN_TRACING_V2` is not. + Returns: T: The configured callback manager. """ @@ -2557,6 +2545,10 @@ async def adispatch_custom_event( this is not enforced. config: Optional config object. Mirrors the async API but not strictly needed. + Raises: + RuntimeError: If there is no parent run ID available to associate + the event with. + Example: .. code-block:: python @@ -2678,6 +2670,10 @@ def dispatch_custom_event( this is not enforced. config: Optional config object. Mirrors the async API but not strictly needed. + Raises: + RuntimeError: If there is no parent run ID available to associate + the event with. + Example: .. code-block:: python diff --git a/libs/core/langchain_core/callbacks/usage.py b/libs/core/langchain_core/callbacks/usage.py index 0249cadec1f..497b6ff4912 100644 --- a/libs/core/langchain_core/callbacks/usage.py +++ b/libs/core/langchain_core/callbacks/usage.py @@ -101,6 +101,9 @@ def get_usage_metadata_callback( name (str): The name of the context variable. Defaults to ``'usage_metadata_callback'``. + Yields: + The usage metadata callback. + Example: .. code-block:: python diff --git a/libs/core/langchain_core/chat_history.py b/libs/core/langchain_core/chat_history.py index 19138005162..0091b240b69 100644 --- a/libs/core/langchain_core/chat_history.py +++ b/libs/core/langchain_core/chat_history.py @@ -109,6 +109,9 @@ class BaseChatMessageHistory(ABC): In general, fetching messages may involve IO to the underlying persistence layer. + + Returns: + The messages. """ from langchain_core.runnables.config import run_in_executor diff --git a/libs/core/langchain_core/document_loaders/base.py b/libs/core/langchain_core/document_loaders/base.py index 0d4054c2b99..7208529da17 100644 --- a/libs/core/langchain_core/document_loaders/base.py +++ b/libs/core/langchain_core/document_loaders/base.py @@ -28,11 +28,19 @@ class BaseLoader(ABC): # noqa: B024 # Sub-classes should not implement this method directly. Instead, they # should implement the lazy load method. def load(self) -> list[Document]: - """Load data into Document objects.""" + """Load data into Document objects. + + Returns: + the documents. + """ return list(self.lazy_load()) async def aload(self) -> list[Document]: - """Load data into Document objects.""" + """Load data into Document objects. + + Returns: + the documents. + """ return [document async for document in self.alazy_load()] def load_and_split( @@ -44,7 +52,11 @@ class BaseLoader(ABC): # noqa: B024 Args: text_splitter: TextSplitter instance to use for splitting documents. - Defaults to RecursiveCharacterTextSplitter. + Defaults to RecursiveCharacterTextSplitter. + + Raises: + ImportError: If langchain-text-splitters is not installed + and no text_splitter is provided. Returns: List of Documents. @@ -69,14 +81,22 @@ class BaseLoader(ABC): # noqa: B024 # Attention: This method will be upgraded into an abstractmethod once it's # implemented in all the existing subclasses. def lazy_load(self) -> Iterator[Document]: - """A lazy loader for Documents.""" + """A lazy loader for Documents. + + Yields: + the documents. + """ if type(self).load != BaseLoader.load: return iter(self.load()) msg = f"{self.__class__.__name__} does not implement lazy_load()" raise NotImplementedError(msg) async def alazy_load(self) -> AsyncIterator[Document]: - """A lazy loader for Documents.""" + """A lazy loader for Documents. + + Yields: + the documents. + """ iterator = await run_in_executor(None, self.lazy_load) done = object() while True: diff --git a/libs/core/langchain_core/document_loaders/langsmith.py b/libs/core/langchain_core/document_loaders/langsmith.py index 67089f520a3..81d9f26c3db 100644 --- a/libs/core/langchain_core/document_loaders/langsmith.py +++ b/libs/core/langchain_core/document_loaders/langsmith.py @@ -84,6 +84,9 @@ class LangSmithLoader(BaseLoader): client: LangSmith Client. If not provided will be initialized from below args. client_kwargs: Keyword args to pass to LangSmith client init. Should only be specified if ``client`` isn't. + + Raises: + ValueError: If both ``client`` and ``client_kwargs`` are provided. """ # noqa: E501 if client and client_kwargs: raise ValueError diff --git a/libs/core/langchain_core/documents/base.py b/libs/core/langchain_core/documents/base.py index 99ae9b62892..adc42ac0182 100644 --- a/libs/core/langchain_core/documents/base.py +++ b/libs/core/langchain_core/documents/base.py @@ -145,7 +145,14 @@ class Blob(BaseMedia): return values def as_string(self) -> str: - """Read data as a string.""" + """Read data as a string. + + Raises: + ValueError: If the blob cannot be represented as a string. + + Returns: + The data as a string. + """ if self.data is None and self.path: return Path(self.path).read_text(encoding=self.encoding) if isinstance(self.data, bytes): @@ -156,7 +163,14 @@ class Blob(BaseMedia): raise ValueError(msg) def as_bytes(self) -> bytes: - """Read data as bytes.""" + """Read data as bytes. + + Raises: + ValueError: If the blob cannot be represented as bytes. + + Returns: + The data as bytes. + """ if isinstance(self.data, bytes): return self.data if isinstance(self.data, str): @@ -168,7 +182,14 @@ class Blob(BaseMedia): @contextlib.contextmanager def as_bytes_io(self) -> Generator[Union[BytesIO, BufferedReader], None, None]: - """Read data as a byte stream.""" + """Read data as a byte stream. + + Raises: + NotImplementedError: If the blob cannot be represented as a byte stream. + + Yields: + The data as a byte stream. + """ if isinstance(self.data, bytes): yield BytesIO(self.data) elif self.data is None and self.path: @@ -246,7 +267,7 @@ class Blob(BaseMedia): ) def __repr__(self) -> str: - """Define the blob representation.""" + """Return the blob representation.""" str_repr = f"Blob {id(self)}" if self.source: str_repr += f" {self.source}" @@ -280,19 +301,24 @@ class Document(BaseMedia): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether this class is serializable.""" + """Return True as this class is serializable.""" return True @classmethod def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default namespace is ["langchain", "schema", "document"]. + Returns: + ["langchain", "schema", "document"] """ return ["langchain", "schema", "document"] def __str__(self) -> str: - """Override __str__ to restrict it to page_content and metadata.""" + """Override __str__ to restrict it to page_content and metadata. + + Returns: + A string representation of the Document. + """ # The format matches pydantic format for __str__. # # The purpose of this change is to make sure that user code that diff --git a/libs/core/langchain_core/example_selectors/base.py b/libs/core/langchain_core/example_selectors/base.py index e344e80551f..ec845cfc2e9 100644 --- a/libs/core/langchain_core/example_selectors/base.py +++ b/libs/core/langchain_core/example_selectors/base.py @@ -16,6 +16,9 @@ class BaseExampleSelector(ABC): Args: example: A dictionary with keys as input variables and values as their values. + + Returns: + Any return value. """ async def aadd_example(self, example: dict[str, str]) -> Any: @@ -24,6 +27,9 @@ class BaseExampleSelector(ABC): Args: example: A dictionary with keys as input variables and values as their values. + + Returns: + Any return value. """ return await run_in_executor(None, self.add_example, example) @@ -34,6 +40,9 @@ class BaseExampleSelector(ABC): Args: input_variables: A dictionary with keys as input variables and values as their values. + + Returns: + A list of examples. """ async def aselect_examples(self, input_variables: dict[str, str]) -> list[dict]: @@ -42,5 +51,8 @@ class BaseExampleSelector(ABC): Args: input_variables: A dictionary with keys as input variables and values as their values. + + Returns: + A list of examples. """ return await run_in_executor(None, self.select_examples, input_variables) diff --git a/libs/core/langchain_core/exceptions.py b/libs/core/langchain_core/exceptions.py index cde6d6ff8ce..6aa8d89bc1f 100644 --- a/libs/core/langchain_core/exceptions.py +++ b/libs/core/langchain_core/exceptions.py @@ -42,6 +42,10 @@ class OutputParserException(ValueError, LangChainException): # noqa: N818 previous output was improperly structured, in the hopes that it will update the output to the correct format. Defaults to False. + + Raises: + ValueError: If ``send_to_llm`` is True but either observation or + ``llm_output`` are not provided. """ if isinstance(error, str): error = create_message( @@ -77,6 +81,9 @@ def create_message(*, message: str, error_code: ErrorCode) -> str: Args: message: The message to display. error_code: The error code to display. + + Returns: + The full message with the troubleshooting link. """ return ( f"{message}\n" diff --git a/libs/core/langchain_core/indexing/api.py b/libs/core/langchain_core/indexing/api.py index bb232b298fe..7e938355fb1 100644 --- a/libs/core/langchain_core/indexing/api.py +++ b/libs/core/langchain_core/indexing/api.py @@ -185,6 +185,9 @@ def _get_document_with_hash( When changing the key encoder, you must change the index as well to avoid duplicated documents in the cache. + Raises: + ValueError: If the metadata cannot be serialized using json. + Returns: Document with a unique identifier based on the hash of the content and metadata. """ @@ -374,6 +377,9 @@ def index( ValueError: If vectorstore does not have "delete" and "add_documents" required methods. ValueError: If source_id_key is not None, but is not a string or callable. + TypeError: If ``vectorstore`` is not a VectorStore or a DocumentIndex. + AssertionError: If ``source_id`` is None when cleanup mode is incremental. + (should be unreachable code). .. version_modified:: 0.3.25 @@ -708,6 +714,9 @@ async def aindex( ValueError: If vectorstore does not have "adelete" and "aadd_documents" required methods. ValueError: If source_id_key is not None, but is not a string or callable. + TypeError: If ``vector_store`` is not a VectorStore or DocumentIndex. + AssertionError: If ``source_id_key`` is None when cleanup mode is + incremental or ``scoped_full`` (should be unreachable). .. version_modified:: 0.3.25 diff --git a/libs/core/langchain_core/indexing/base.py b/libs/core/langchain_core/indexing/base.py index 0de0b8cdee2..6e638ebd722 100644 --- a/libs/core/langchain_core/indexing/base.py +++ b/libs/core/langchain_core/indexing/base.py @@ -7,6 +7,8 @@ import time from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Any, Optional, TypedDict +from typing_extensions import override + from langchain_core._api import beta from langchain_core.retrievers import BaseRetriever from langchain_core.runnables import run_in_executor @@ -256,12 +258,12 @@ class InMemoryRecordManager(RecordManager): async def acreate_schema(self) -> None: """In-memory schema creation is simply ensuring the structure is initialized.""" + @override def get_time(self) -> float: - """Get the current server time as a high resolution timestamp!""" return time.time() + @override async def aget_time(self) -> float: - """Async get the current server time as a high resolution timestamp!""" return self.get_time() def update( @@ -322,11 +324,6 @@ class InMemoryRecordManager(RecordManager): raise an error. This is meant to help prevent time-drift issues since time may not be monotonically increasing! - - Raises: - ValueError: If the length of keys doesn't match the length of group - ids. - ValueError: If time_at_least is in the future. """ self.update(keys, group_ids=group_ids, time_at_least=time_at_least) diff --git a/libs/core/langchain_core/indexing/in_memory.py b/libs/core/langchain_core/indexing/in_memory.py index 34609a0370d..02c11ffd198 100644 --- a/libs/core/langchain_core/indexing/in_memory.py +++ b/libs/core/langchain_core/indexing/in_memory.py @@ -32,7 +32,17 @@ class InMemoryDocumentIndex(DocumentIndex): @override def upsert(self, items: Sequence[Document], /, **kwargs: Any) -> UpsertResponse: - """Upsert items into the index.""" + """Upsert documents into the index. + + Args: + items: Sequence of documents to add to the index. + **kwargs: Additional keyword arguments. + + Returns: + A response object that contains the list of IDs that were + successfully added or updated in the index and the list of IDs that + failed to be added or updated. + """ ok_ids = [] for item in items: @@ -51,7 +61,18 @@ class InMemoryDocumentIndex(DocumentIndex): @override def delete(self, ids: Optional[list[str]] = None, **kwargs: Any) -> DeleteResponse: - """Delete by ID.""" + """Delete by IDs. + + Args: + ids: List of ids to delete. + + Raises: + ValueError: If ids is None. + + Returns: + A response object that contains the list of IDs that were successfully + deleted and the list of IDs that failed to be deleted. + """ if ids is None: msg = "IDs must be provided for deletion" raise ValueError(msg) @@ -69,7 +90,6 @@ class InMemoryDocumentIndex(DocumentIndex): @override def get(self, ids: Sequence[str], /, **kwargs: Any) -> list[Document]: - """Get by ids.""" return [self.store[id_] for id_ in ids if id_ in self.store] @override diff --git a/libs/core/langchain_core/language_models/base.py b/libs/core/langchain_core/language_models/base.py index 9f9856d7c6c..80be6ff7305 100644 --- a/libs/core/langchain_core/language_models/base.py +++ b/libs/core/langchain_core/language_models/base.py @@ -59,6 +59,12 @@ def get_tokenizer() -> Any: This function is cached to avoid re-loading the tokenizer every time it is called. + Raises: + ImportError: If the transformers package is not installed. + + Returns: + The GPT-2 tokenizer instance. + """ try: from transformers import GPT2TokenizerFast # type: ignore[import-not-found] diff --git a/libs/core/langchain_core/language_models/chat_models.py b/libs/core/langchain_core/language_models/chat_models.py index 2ab0d6bb759..f4ec3d48af9 100644 --- a/libs/core/langchain_core/language_models/chat_models.py +++ b/libs/core/langchain_core/language_models/chat_models.py @@ -161,6 +161,9 @@ def generate_from_stream(stream: Iterator[ChatGenerationChunk]) -> ChatResult: Args: stream: Iterator of ``ChatGenerationChunk``. + Raises: + ValueError: If no generations are found in the stream. + Returns: ChatResult: Chat result. @@ -328,7 +331,7 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): @model_validator(mode="before") @classmethod def raise_deprecation(cls, values: dict) -> Any: - """Raise deprecation warning if ``callback_manager`` is used. + """Emit deprecation warning if ``callback_manager`` is used. Args: values (Dict): Values to validate. @@ -336,9 +339,6 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): Returns: Dict: Validated values. - Raises: - DeprecationWarning: If ``callback_manager`` is used. - """ if values.get("callback_manager") is not None: warnings.warn( @@ -1185,7 +1185,17 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> ChatResult: - """Top Level call.""" + """Generate the result. + + Args: + messages: The messages to generate from. + stop: Optional list of stop words to use when generating. + run_manager: Optional callback manager to use for this call. + **kwargs: Additional keyword arguments to pass to the model. + + Returns: + The chat result. + """ async def _agenerate( self, @@ -1194,7 +1204,17 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, **kwargs: Any, ) -> ChatResult: - """Top Level call.""" + """Generate the result. + + Args: + messages: The messages to generate from. + stop: Optional list of stop words to use when generating. + run_manager: Optional callback manager to use for this call. + **kwargs: Additional keyword arguments to pass to the model. + + Returns: + The chat result. + """ return await run_in_executor( None, self._generate, @@ -1211,6 +1231,17 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> Iterator[ChatGenerationChunk]: + """Stream the output of the model. + + Args: + messages: The messages to generate from. + stop: Optional list of stop words to use when generating. + run_manager: Optional callback manager to use for this call. + **kwargs: Additional keyword arguments to pass to the model. + + Yields: + The chat generation chunks. + """ raise NotImplementedError async def _astream( @@ -1220,6 +1251,17 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, **kwargs: Any, ) -> AsyncIterator[ChatGenerationChunk]: + """Stream the output of the model. + + Args: + messages: The messages to generate from. + stop: Optional list of stop words to use when generating. + run_manager: Optional callback manager to use for this call. + **kwargs: Additional keyword arguments to pass to the model. + + Yields: + The chat generation chunks. + """ iterator = await run_in_executor( None, self._stream, @@ -1259,6 +1301,9 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): **kwargs: Arbitrary additional keyword arguments. These are usually passed to the model provider API call. + Raises: + ValueError: If the generation is not a chat generation. + Returns: The model output message. @@ -1320,6 +1365,9 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): **kwargs: Arbitrary additional keyword arguments. These are usually passed to the model provider API call. + Raises: + ValueError: If the output is not a string. + Returns: The predicted output string. @@ -1434,6 +1482,11 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): will be caught and returned as well. The final output is always a dict with keys ``'raw'``, ``'parsed'``, and ``'parsing_error'``. + Raises: + ValueError: If there are any unsupported ``kwargs``. + NotImplementedError: If the model does not implement + ``with_structured_output()``. + Returns: A Runnable that takes same inputs as a :class:`langchain_core.language_models.chat.BaseChatModel`. diff --git a/libs/core/langchain_core/language_models/fake_chat_models.py b/libs/core/langchain_core/language_models/fake_chat_models.py index c6e78b5389a..3b90259e525 100644 --- a/libs/core/langchain_core/language_models/fake_chat_models.py +++ b/libs/core/langchain_core/language_models/fake_chat_models.py @@ -75,12 +75,13 @@ class FakeListChatModel(SimpleChatModel): @override def _call( self, - messages: list[BaseMessage], - stop: Optional[list[str]] = None, - run_manager: Optional[CallbackManagerForLLMRun] = None, + *args: Any, **kwargs: Any, ) -> str: - """First try to lookup in queries, else return 'foo' or 'bar'.""" + """Return the next response in the list. + + Cycle back to the start if at the end. + """ if self.sleep is not None: time.sleep(self.sleep) response = self.responses[self.i] @@ -239,7 +240,6 @@ class GenericFakeChatModel(BaseChatModel): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> ChatResult: - """Top Level call.""" message = next(self.messages) message_ = AIMessage(content=message) if isinstance(message, str) else message generation = ChatGeneration(message=message_) @@ -252,7 +252,6 @@ class GenericFakeChatModel(BaseChatModel): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> Iterator[ChatGenerationChunk]: - """Stream the output of the model.""" chat_result = self._generate( messages, stop=stop, run_manager=run_manager, **kwargs ) @@ -362,7 +361,6 @@ class ParrotFakeChatModel(BaseChatModel): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> ChatResult: - """Top Level call.""" return ChatResult(generations=[ChatGeneration(message=messages[-1])]) @property diff --git a/libs/core/langchain_core/language_models/llms.py b/libs/core/langchain_core/language_models/llms.py index 10a5f06121f..c274e02310d 100644 --- a/libs/core/langchain_core/language_models/llms.py +++ b/libs/core/langchain_core/language_models/llms.py @@ -664,7 +664,18 @@ class BaseLLM(BaseLanguageModel[str], ABC): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> LLMResult: - """Run the LLM on the given prompts.""" + """Run the LLM on the given prompts. + + Args: + prompts: The prompts to generate from. + stop: Stop words to use when generating. Model output is cut off at the + first occurrence of any of the stop substrings. + If stop tokens are not supported consider raising NotImplementedError. + run_manager: Callback manager for the run. + + Returns: + The LLM result. + """ async def _agenerate( self, @@ -673,7 +684,18 @@ class BaseLLM(BaseLanguageModel[str], ABC): run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, **kwargs: Any, ) -> LLMResult: - """Run the LLM on the given prompts.""" + """Run the LLM on the given prompts. + + Args: + prompts: The prompts to generate from. + stop: Stop words to use when generating. Model output is cut off at the + first occurrence of any of the stop substrings. + If stop tokens are not supported consider raising NotImplementedError. + run_manager: Callback manager for the run. + + Returns: + The LLM result. + """ return await run_in_executor( None, self._generate, @@ -706,8 +728,8 @@ class BaseLLM(BaseLanguageModel[str], ABC): **kwargs: Arbitrary additional keyword arguments. These are usually passed to the model provider API call. - Returns: - An iterator of GenerationChunks. + Yields: + Generation chunks. """ raise NotImplementedError @@ -732,8 +754,8 @@ class BaseLLM(BaseLanguageModel[str], ABC): **kwargs: Arbitrary additional keyword arguments. These are usually passed to the model provider API call. - Returns: - An async iterator of GenerationChunks. + Yields: + Generation chunks. """ iterator = await run_in_executor( None, @@ -854,6 +876,11 @@ class BaseLLM(BaseLanguageModel[str], ABC): **kwargs: Arbitrary additional keyword arguments. These are usually passed to the model provider API call. + Raises: + ValueError: If prompts is not a list. + ValueError: If the length of ``callbacks``, ``tags``, ``metadata``, or + ``run_name`` (if provided) does not match the length of prompts. + Returns: An LLMResult, which contains a list of candidate Generations for each input prompt and additional model provider-specific output. @@ -1114,6 +1141,10 @@ class BaseLLM(BaseLanguageModel[str], ABC): **kwargs: Arbitrary additional keyword arguments. These are usually passed to the model provider API call. + Raises: + ValueError: If the length of ``callbacks``, ``tags``, ``metadata``, or + ``run_name`` (if provided) does not match the length of prompts. + Returns: An LLMResult, which contains a list of candidate Generations for each input prompt and additional model provider-specific output. @@ -1389,7 +1420,7 @@ class BaseLLM(BaseLanguageModel[str], ABC): return AIMessage(content=content) def __str__(self) -> str: - """Get a string representation of the object for printing.""" + """Return a string representation of the object for printing.""" cls_name = f"\033[1m{self.__class__.__name__}\033[0m" return f"{cls_name}\nParams: {self._identifying_params}" @@ -1537,7 +1568,6 @@ class LLM(BaseLLM): run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> LLMResult: - """Run the LLM on the given prompt and input.""" # TODO: add caching here. generations = [] new_arg_supported = inspect.signature(self._call).parameters.get("run_manager") @@ -1557,7 +1587,6 @@ class LLM(BaseLLM): run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, **kwargs: Any, ) -> LLMResult: - """Async run the LLM on the given prompt and input.""" generations = [] new_arg_supported = inspect.signature(self._acall).parameters.get("run_manager") for prompt in prompts: diff --git a/libs/core/langchain_core/load/load.py b/libs/core/langchain_core/load/load.py index 0c2cbf1f65e..52f4e2080b8 100644 --- a/libs/core/langchain_core/load/load.py +++ b/libs/core/langchain_core/load/load.py @@ -95,7 +95,21 @@ class Reviver: self.ignore_unserializable_fields = ignore_unserializable_fields def __call__(self, value: dict[str, Any]) -> Any: - """Revive the value.""" + """Revive the value. + + Args: + value: The value to revive. + + Returns: + The revived value. + + Raises: + ValueError: If the namespace is invalid. + ValueError: If trying to deserialize something that cannot + be deserialized in the current version of langchain-core. + NotImplementedError: If the object is not implemented and + ``ignore_unserializable_fields`` is False. + """ if ( value.get("lc") == 1 and value.get("type") == "secret" diff --git a/libs/core/langchain_core/load/serializable.py b/libs/core/langchain_core/load/serializable.py index fde77e69932..b9d612be45c 100644 --- a/libs/core/langchain_core/load/serializable.py +++ b/libs/core/langchain_core/load/serializable.py @@ -79,9 +79,6 @@ def try_neq_default(value: Any, key: str, model: BaseModel) -> bool: Returns: Whether the value is different from the default. - - Raises: - Exception: If the key is not in the model. """ field = type(model).model_fields[key] return _try_neq_default(value, field) @@ -148,6 +145,9 @@ class Serializable(BaseModel, ABC): For example, if the class is `langchain.llms.openai.OpenAI`, then the namespace is ["langchain", "llms", "openai"] + + Returns: + The namespace as a list of strings. """ return cls.__module__.split(".") @@ -171,7 +171,7 @@ class Serializable(BaseModel, ABC): @classmethod def lc_id(cls) -> list[str]: - """A unique identifier for this class for serialization purposes. + """Return a unique identifier for this class for serialization purposes. The unique identifier is a list of strings that describes the path to the object. @@ -203,6 +203,9 @@ class Serializable(BaseModel, ABC): def to_json(self) -> Union[SerializedConstructor, SerializedNotImplemented]: """Serialize the object to JSON. + Raises: + ValueError: If the class has deprecated attributes. + Returns: A json serializable object or a SerializedNotImplemented object. """ @@ -276,7 +279,11 @@ class Serializable(BaseModel, ABC): } def to_json_not_implemented(self) -> SerializedNotImplemented: - """Serialize a "not implemented" object.""" + """Serialize a "not implemented" object. + + Returns: + SerializedNotImplemented. + """ return to_json_not_implemented(self) diff --git a/libs/core/langchain_core/messages/ai.py b/libs/core/langchain_core/messages/ai.py index 86d48ec3254..e8640545649 100644 --- a/libs/core/langchain_core/messages/ai.py +++ b/libs/core/langchain_core/messages/ai.py @@ -310,14 +310,8 @@ class AIMessageChunk(AIMessage, BaseMessageChunk): def init_tool_calls(self) -> Self: """Initialize tool calls from tool call chunks. - Args: - values: The values to validate. - Returns: - The values with tool calls initialized. - - Raises: - ValueError: If the tool call chunks are malformed. + This ``AIMessageChunk``. """ if not self.tool_call_chunks: if self.tool_calls: @@ -392,7 +386,19 @@ class AIMessageChunk(AIMessage, BaseMessageChunk): def add_ai_message_chunks( left: AIMessageChunk, *others: AIMessageChunk ) -> AIMessageChunk: - """Add multiple AIMessageChunks together.""" + """Add multiple ``AIMessageChunk``s together. + + Args: + left: The first ``AIMessageChunk``. + *others: Other ``AIMessageChunk``s to add. + + Raises: + ValueError: If the example values of the chunks are not the same. + + Returns: + The resulting ``AIMessageChunk``. + + """ if any(left.example != o.example for o in others): msg = "Cannot concatenate AIMessageChunks with different example values." raise ValueError(msg) @@ -491,6 +497,13 @@ def add_usage( output_token_details=OutputTokenDetails(reasoning=4), ) + Args: + left: The first ``UsageMetadata`` object. + right: The second ``UsageMetadata`` object. + + Returns: + The sum of the two ``UsageMetadata`` objects. + """ if not (left or right): return UsageMetadata(input_tokens=0, output_tokens=0, total_tokens=0) @@ -548,6 +561,13 @@ def subtract_usage( output_token_details=OutputTokenDetails(reasoning=0), ) + Args: + left: The first ``UsageMetadata`` object. + right: The second ``UsageMetadata`` object. + + Returns: + The resulting ``UsageMetadata`` after subtraction. + """ if not (left or right): return UsageMetadata(input_tokens=0, output_tokens=0, total_tokens=0) diff --git a/libs/core/langchain_core/messages/base.py b/libs/core/langchain_core/messages/base.py index ba976286b75..2f831d79d02 100644 --- a/libs/core/langchain_core/messages/base.py +++ b/libs/core/langchain_core/messages/base.py @@ -84,7 +84,8 @@ class BaseMessage(Serializable): def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default is ["langchain", "schema", "messages"]. + Returns: + ``["langchain", "schema", "messages"]`` """ return ["langchain", "schema", "messages"] @@ -109,7 +110,14 @@ class BaseMessage(Serializable): ) def __add__(self, other: Any) -> ChatPromptTemplate: - """Concatenate this message with another message.""" + """Concatenate this message with another message. + + Args: + other: Another message to concatenate with this one. + + Returns: + A ChatPromptTemplate containing both messages. + """ from langchain_core.prompts.chat import ChatPromptTemplate prompt = ChatPromptTemplate(messages=[self]) diff --git a/libs/core/langchain_core/messages/content_blocks.py b/libs/core/langchain_core/messages/content_blocks.py index 83a66fb123a..e90426ebb13 100644 --- a/libs/core/langchain_core/messages/content_blocks.py +++ b/libs/core/langchain_core/messages/content_blocks.py @@ -88,7 +88,18 @@ def is_data_content_block( def convert_to_openai_image_block(content_block: dict[str, Any]) -> dict: - """Convert image content block to format expected by OpenAI Chat Completions API.""" + """Convert image content block to format expected by OpenAI Chat Completions API. + + Args: + content_block: The content block to convert. + + Raises: + ValueError: If the source type is not supported or if ``mime_type`` is missing + for base64 data. + + Returns: + A dictionary formatted for OpenAI's API. + """ if content_block["source_type"] == "url": return { "type": "image_url", @@ -112,7 +123,17 @@ def convert_to_openai_image_block(content_block: dict[str, Any]) -> dict: def convert_to_openai_data_block(block: dict) -> dict: - """Format standard data content block to format expected by OpenAI.""" + """Format standard data content block to format expected by OpenAI. + + Args: + block: A data content block. + + Raises: + ValueError: If the block type or source type is not supported. + + Returns: + A dictionary formatted for OpenAI's API. + """ if block["type"] == "image": formatted_block = convert_to_openai_image_block(block) diff --git a/libs/core/langchain_core/messages/tool.py b/libs/core/langchain_core/messages/tool.py index 4d847c86d97..b2f858d8138 100644 --- a/libs/core/langchain_core/messages/tool.py +++ b/libs/core/langchain_core/messages/tool.py @@ -217,6 +217,9 @@ def tool_call( name: The name of the tool to be called. args: The arguments to the tool call. id: An identifier associated with the tool call. + + Returns: + The created tool call. """ return ToolCall(name=name, args=args, id=id, type="tool_call") @@ -267,6 +270,9 @@ def tool_call_chunk( args: The arguments to the tool call. id: An identifier associated with the tool call. index: The index of the tool call in a sequence. + + Returns: + The created tool call chunk. """ return ToolCallChunk( name=name, args=args, id=id, index=index, type="tool_call_chunk" @@ -305,6 +311,9 @@ def invalid_tool_call( args: The arguments to the tool call. id: An identifier associated with the tool call. error: An error message associated with the tool call. + + Returns: + The created invalid tool call. """ return InvalidToolCall( name=name, args=args, id=id, error=error, type="invalid_tool_call" @@ -314,7 +323,14 @@ def invalid_tool_call( def default_tool_parser( raw_tool_calls: list[dict], ) -> tuple[list[ToolCall], list[InvalidToolCall]]: - """Best-effort parsing of tools.""" + """Best-effort parsing of tools. + + Args: + raw_tool_calls: List of raw tool call dicts to parse. + + Returns: + A list of tool calls and invalid tool calls. + """ tool_calls = [] invalid_tool_calls = [] for raw_tool_call in raw_tool_calls: @@ -342,7 +358,14 @@ def default_tool_parser( def default_tool_chunk_parser(raw_tool_calls: list[dict]) -> list[ToolCallChunk]: - """Best-effort parsing of tool chunks.""" + """Best-effort parsing of tool chunks. + + Args: + raw_tool_calls: List of raw tool call dicts to parse. + + Returns: + List of parsed ToolCallChunk objects. + """ tool_call_chunks = [] for tool_call in raw_tool_calls: if "function" not in tool_call: diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index 16285eaefb2..c63f5b1c421 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -1046,6 +1046,10 @@ def convert_to_openai_messages( with a single content block of type 'text'. If a message has content blocks these are left as is. + Raises: + ValueError: if an unrecognized ``text_format`` is specified, or if a message + content block is missing expected keys. + Returns: The return type depends on the input type: - dict: diff --git a/libs/core/langchain_core/output_parsers/list.py b/libs/core/langchain_core/output_parsers/list.py index d60afe3554d..cc8ca4238cb 100644 --- a/libs/core/langchain_core/output_parsers/list.py +++ b/libs/core/langchain_core/output_parsers/list.py @@ -143,10 +143,7 @@ class CommaSeparatedListOutputParser(ListOutputParser): @classmethod def is_lc_serializable(cls) -> bool: - """Check if the langchain object is serializable. - - Returns True. - """ + """Return True as this class is serializable.""" return True @classmethod @@ -154,8 +151,7 @@ class CommaSeparatedListOutputParser(ListOutputParser): """Get the namespace of the langchain object. Returns: - A list of strings. - Default is ["langchain", "output_parsers", "list"]. + ``["langchain", "output_parsers", "list"]`` """ return ["langchain", "output_parsers", "list"] @@ -213,15 +209,8 @@ class NumberedListOutputParser(ListOutputParser): """ return re.findall(self.pattern, text) + @override def parse_iter(self, text: str) -> Iterator[re.Match]: - """Parse the output of an LLM call. - - Args: - text: The output of an LLM call. - - Yields: - A match object for each part of the output. - """ return re.finditer(self.pattern, text) @property @@ -250,15 +239,8 @@ class MarkdownListOutputParser(ListOutputParser): """ return re.findall(self.pattern, text, re.MULTILINE) + @override def parse_iter(self, text: str) -> Iterator[re.Match]: - """Parse the output of an LLM call. - - Args: - text: The output of an LLM call. - - Yields: - A match object for each part of the output. - """ return re.finditer(self.pattern, text, re.MULTILINE) @property diff --git a/libs/core/langchain_core/output_parsers/openai_functions.py b/libs/core/langchain_core/output_parsers/openai_functions.py index 129c9855061..5518f36a78e 100644 --- a/libs/core/langchain_core/output_parsers/openai_functions.py +++ b/libs/core/langchain_core/output_parsers/openai_functions.py @@ -261,6 +261,9 @@ class PydanticOutputFunctionsParser(OutputFunctionsParser): result: The result of the LLM call. partial: Whether to parse partial JSON objects. Default is False. + Raises: + ValueError: If the pydantic schema is not valid. + Returns: The parsed JSON object. """ diff --git a/libs/core/langchain_core/output_parsers/openai_tools.py b/libs/core/langchain_core/output_parsers/openai_tools.py index 5c2e0cd6644..44563e9a3c2 100644 --- a/libs/core/langchain_core/output_parsers/openai_tools.py +++ b/libs/core/langchain_core/output_parsers/openai_tools.py @@ -231,6 +231,9 @@ class JsonOutputKeyToolsParser(JsonOutputToolsParser): If False, the output will be the full JSON object. Default is False. + Raises: + OutputParserException: If the generation is not a chat generation. + Returns: The parsed tool calls. """ @@ -316,7 +319,9 @@ class PydanticToolsParser(JsonOutputToolsParser): The parsed Pydantic objects. Raises: - OutputParserException: If the output is not valid JSON. + ValueError: If the tool call arguments are not a dict. + ValidationError: If the tool call arguments do not conform + to the Pydantic model. """ json_results = super().parse_result(result, partial=partial) if not json_results: diff --git a/libs/core/langchain_core/output_parsers/pydantic.py b/libs/core/langchain_core/output_parsers/pydantic.py index b543df55768..1785cbc60fa 100644 --- a/libs/core/langchain_core/output_parsers/pydantic.py +++ b/libs/core/langchain_core/output_parsers/pydantic.py @@ -54,6 +54,10 @@ class PydanticOutputParser(JsonOutputParser, Generic[TBaseModel]): all the keys that have been returned so far. Defaults to False. + Raises: + OutputParserException: If the result is not valid JSON + or does not conform to the pydantic model. + Returns: The parsed pydantic object. """ diff --git a/libs/core/langchain_core/output_parsers/string.py b/libs/core/langchain_core/output_parsers/string.py index 4f952c68892..c2194e8bddf 100644 --- a/libs/core/langchain_core/output_parsers/string.py +++ b/libs/core/langchain_core/output_parsers/string.py @@ -19,7 +19,8 @@ class StrOutputParser(BaseTransformOutputParser[str]): def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default is ["langchain", "schema", "output_parser"]. + Returns: + ``["langchain", "schema", "output_parser"]`` """ return ["langchain", "schema", "output_parser"] diff --git a/libs/core/langchain_core/output_parsers/xml.py b/libs/core/langchain_core/output_parsers/xml.py index 483d9871c1a..fcbd68a89d0 100644 --- a/libs/core/langchain_core/output_parsers/xml.py +++ b/libs/core/langchain_core/output_parsers/xml.py @@ -136,9 +136,6 @@ class _StreamingParser: """Close the parser. This should be called after all chunks have been parsed. - - Raises: - xml.etree.ElementTree.ParseError: If the XML is not well-formed. """ # Ignore ParseError. This will ignore any incomplete XML at the end of the input with contextlib.suppress(xml.etree.ElementTree.ParseError): diff --git a/libs/core/langchain_core/outputs/chat_generation.py b/libs/core/langchain_core/outputs/chat_generation.py index d42f2038d34..594066f2fb7 100644 --- a/libs/core/langchain_core/outputs/chat_generation.py +++ b/libs/core/langchain_core/outputs/chat_generation.py @@ -47,9 +47,6 @@ class ChatGeneration(Generation): Returns: The values of the object with the text attribute set. - - Raises: - ValueError: If the message is not a string or a list. """ text = "" if isinstance(self.message.content, str): @@ -83,11 +80,18 @@ class ChatGenerationChunk(ChatGeneration): def __add__( self, other: Union[ChatGenerationChunk, list[ChatGenerationChunk]] ) -> ChatGenerationChunk: - """Concatenate two ChatGenerationChunks. + """Concatenate two ``ChatGenerationChunk``s. Args: - other: The other ChatGenerationChunk or list of ChatGenerationChunks to - concatenate. + other: The other ``ChatGenerationChunk`` or list of ``ChatGenerationChunk`` + to concatenate. + + Raises: + TypeError: If other is not a ``ChatGenerationChunk`` or list of + ``ChatGenerationChunk``. + + Returns: + A new ``ChatGenerationChunk`` concatenated from self and other. """ if isinstance(other, ChatGenerationChunk): generation_info = merge_dicts( @@ -116,7 +120,14 @@ class ChatGenerationChunk(ChatGeneration): def merge_chat_generation_chunks( chunks: list[ChatGenerationChunk], ) -> Union[ChatGenerationChunk, None]: - """Merge a list of ChatGenerationChunks into a single ChatGenerationChunk.""" + """Merge a list of ``ChatGenerationChunk``s into a single ``ChatGenerationChunk``. + + Args: + chunks: A list of ``ChatGenerationChunk`` to merge. + + Returns: + A merged ``ChatGenerationChunk``, or None if the input list is empty. + """ if not chunks: return None diff --git a/libs/core/langchain_core/outputs/generation.py b/libs/core/langchain_core/outputs/generation.py index 1167616d6bc..cd06c20e673 100644 --- a/libs/core/langchain_core/outputs/generation.py +++ b/libs/core/langchain_core/outputs/generation.py @@ -39,14 +39,15 @@ class Generation(Serializable): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether this class is serializable.""" + """Return True as this class is serializable.""" return True @classmethod def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default namespace is ["langchain", "schema", "output"]. + Returns: + ``["langchain", "schema", "output"]`` """ return ["langchain", "schema", "output"] @@ -55,7 +56,17 @@ class GenerationChunk(Generation): """Generation chunk, which can be concatenated with other Generation chunks.""" def __add__(self, other: GenerationChunk) -> GenerationChunk: - """Concatenate two GenerationChunks.""" + """Concatenate two ``GenerationChunk``s. + + Args: + other: Another ``GenerationChunk`` to concatenate with. + + Raises: + TypeError: If other is not a ``GenerationChunk``. + + Returns: + A new ``GenerationChunk`` concatenated from self and other. + """ if isinstance(other, GenerationChunk): generation_info = merge_dicts( self.generation_info or {}, diff --git a/libs/core/langchain_core/outputs/llm_result.py b/libs/core/langchain_core/outputs/llm_result.py index 08e5e78f2a7..088b909755c 100644 --- a/libs/core/langchain_core/outputs/llm_result.py +++ b/libs/core/langchain_core/outputs/llm_result.py @@ -91,7 +91,14 @@ class LLMResult(BaseModel): return llm_results def __eq__(self, other: object) -> bool: - """Check for LLMResult equality by ignoring any metadata related to runs.""" + """Check for ``LLMResult`` equality by ignoring any metadata related to runs. + + Args: + other: Another ``LLMResult`` object to compare against. + + Returns: + True if the generations and ``llm_output`` are equal, False otherwise. + """ if not isinstance(other, LLMResult): return NotImplemented return ( diff --git a/libs/core/langchain_core/prompt_values.py b/libs/core/langchain_core/prompt_values.py index 7652bd76e3c..5b7c2e414bb 100644 --- a/libs/core/langchain_core/prompt_values.py +++ b/libs/core/langchain_core/prompt_values.py @@ -30,7 +30,7 @@ class PromptValue(Serializable, ABC): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether this class is serializable. Defaults to True.""" + """Return True as this class is serializable.""" return True @classmethod @@ -38,7 +38,9 @@ class PromptValue(Serializable, ABC): """Get the namespace of the langchain object. This is used to determine the namespace of the object when serializing. - Defaults to ["langchain", "schema", "prompt"]. + + Returns: + ``["langchain", "schema", "prompt"]`` """ return ["langchain", "schema", "prompt"] @@ -63,7 +65,9 @@ class StringPromptValue(PromptValue): """Get the namespace of the langchain object. This is used to determine the namespace of the object when serializing. - Defaults to ["langchain", "prompts", "base"]. + + Returns: + ``["langchain", "prompts", "base"]`` """ return ["langchain", "prompts", "base"] @@ -98,7 +102,9 @@ class ChatPromptValue(PromptValue): """Get the namespace of the langchain object. This is used to determine the namespace of the object when serializing. - Defaults to ["langchain", "prompts", "chat"]. + + Returns: + ``["langchain", "prompts", "chat"]`` """ return ["langchain", "prompts", "chat"] diff --git a/libs/core/langchain_core/prompts/base.py b/libs/core/langchain_core/prompts/base.py index f36c69be8e6..6581c56902c 100644 --- a/libs/core/langchain_core/prompts/base.py +++ b/libs/core/langchain_core/prompts/base.py @@ -101,16 +101,14 @@ class BasePromptTemplate( def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Returns ["langchain", "schema", "prompt_template"]. + Returns: + ``["langchain", "schema", "prompt_template"]`` """ return ["langchain", "schema", "prompt_template"] @classmethod def is_lc_serializable(cls) -> bool: - """Return whether this class is serializable. - - Returns True. - """ + """Return True as this class is serializable.""" return True model_config = ConfigDict( @@ -341,9 +339,6 @@ class BasePromptTemplate( Returns: Dict: Dictionary representation of the prompt. - - Raises: - NotImplementedError: If the prompt type is not implemented. """ prompt_dict = super().model_dump(**kwargs) with contextlib.suppress(NotImplementedError): diff --git a/libs/core/langchain_core/prompts/chat.py b/libs/core/langchain_core/prompts/chat.py index 12728ef76e8..93bcb29730a 100644 --- a/libs/core/langchain_core/prompts/chat.py +++ b/libs/core/langchain_core/prompts/chat.py @@ -740,10 +740,18 @@ class BaseChatPromptTemplate(BasePromptTemplate, ABC): @abstractmethod def format_messages(self, **kwargs: Any) -> list[BaseMessage]: - """Format kwargs into a list of messages.""" + """Format kwargs into a list of messages. + + Returns: + List of messages. + """ async def aformat_messages(self, **kwargs: Any) -> list[BaseMessage]: - """Async format kwargs into a list of messages.""" + """Async format kwargs into a list of messages. + + Returns: + List of messages. + """ return self.format_messages(**kwargs) def pretty_repr( @@ -925,9 +933,6 @@ class ChatPromptTemplate(BaseChatPromptTemplate): input_types: A dictionary of the types of the variables the prompt template expects. If not provided, all variables are assumed to be strings. - Returns: - A chat prompt template. - Examples: Instantiation from a list of message templates: @@ -981,7 +986,11 @@ class ChatPromptTemplate(BaseChatPromptTemplate): @classmethod def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "prompts", "chat"]`` + """ return ["langchain", "prompts", "chat"] def __add__(self, other: Any) -> ChatPromptTemplate: @@ -1185,6 +1194,9 @@ class ChatPromptTemplate(BaseChatPromptTemplate): **kwargs: keyword arguments to use for filling in template variables in all the template messages in this chat template. + Raises: + ValueError: if messages are of unexpected types. + Returns: list of formatted messages. """ @@ -1295,7 +1307,13 @@ class ChatPromptTemplate(BaseChatPromptTemplate): def __getitem__( self, index: Union[int, slice] ) -> Union[MessageLike, ChatPromptTemplate]: - """Use to index into the chat template.""" + """Use to index into the chat template. + + Returns: + If index is an int, returns the message at that index. + If index is a slice, returns a new ``ChatPromptTemplate`` + containing the messages in that slice. + """ if isinstance(index, slice): start, stop, step = index.indices(len(self.messages)) messages = self.messages[start:stop:step] @@ -1303,7 +1321,7 @@ class ChatPromptTemplate(BaseChatPromptTemplate): return self.messages[index] def __len__(self) -> int: - """Get the length of the chat template.""" + """Return the length of the chat template.""" return len(self.messages) @property diff --git a/libs/core/langchain_core/prompts/dict.py b/libs/core/langchain_core/prompts/dict.py index 0b5ee5072a2..135f8021b9d 100644 --- a/libs/core/langchain_core/prompts/dict.py +++ b/libs/core/langchain_core/prompts/dict.py @@ -31,18 +31,25 @@ class DictPromptTemplate(RunnableSerializable[dict, dict]): return _get_input_variables(self.template, self.template_format) def format(self, **kwargs: Any) -> dict[str, Any]: - """Format the prompt with the inputs.""" + """Format the prompt with the inputs. + + Returns: + A formatted dict. + """ return _insert_input_variables(self.template, kwargs, self.template_format) async def aformat(self, **kwargs: Any) -> dict[str, Any]: - """Format the prompt with the inputs.""" + """Format the prompt with the inputs. + + Returns: + A formatted dict. + """ return self.format(**kwargs) @override def invoke( self, input: dict, config: Optional[RunnableConfig] = None, **kwargs: Any ) -> dict: - """Invoke the prompt.""" return self._call_with_config( lambda x: self.format(**x), input, @@ -62,15 +69,16 @@ class DictPromptTemplate(RunnableSerializable[dict, dict]): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether or not the class is serializable. - - Returns: True. - """ + """Return True as this class is serializable.""" return True @classmethod def get_lc_namespace(cls) -> list[str]: - """Serialization namespace.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain_core", "prompts", "dict"]`` + """ return ["langchain_core", "prompts", "dict"] def pretty_repr(self, *, html: bool = False) -> str: diff --git a/libs/core/langchain_core/prompts/few_shot.py b/libs/core/langchain_core/prompts/few_shot.py index ddb09c2e320..70c95038208 100644 --- a/libs/core/langchain_core/prompts/few_shot.py +++ b/libs/core/langchain_core/prompts/few_shot.py @@ -117,7 +117,7 @@ class FewShotPromptTemplate(_FewShotPromptTemplateMixin, StringPromptTemplate): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether or not the class is serializable.""" + """Return False as this class is not serializable.""" return False validate_template: bool = False @@ -367,7 +367,7 @@ class FewShotChatMessagePromptTemplate( @classmethod def is_lc_serializable(cls) -> bool: - """Return whether or not the class is serializable.""" + """Return False as this class is not serializable.""" return False model_config = ConfigDict( diff --git a/libs/core/langchain_core/prompts/few_shot_with_templates.py b/libs/core/langchain_core/prompts/few_shot_with_templates.py index eaf8ab0fd15..5f3ad91fe48 100644 --- a/libs/core/langchain_core/prompts/few_shot_with_templates.py +++ b/libs/core/langchain_core/prompts/few_shot_with_templates.py @@ -46,7 +46,11 @@ class FewShotPromptWithTemplates(StringPromptTemplate): @classmethod def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "prompts", "few_shot_with_templates"]`` + """ return ["langchain", "prompts", "few_shot_with_templates"] @model_validator(mode="before") diff --git a/libs/core/langchain_core/prompts/image.py b/libs/core/langchain_core/prompts/image.py index 4240b6bdec0..95776dbba00 100644 --- a/libs/core/langchain_core/prompts/image.py +++ b/libs/core/langchain_core/prompts/image.py @@ -23,7 +23,12 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]): Options are: 'f-string', 'mustache', 'jinja2'.""" def __init__(self, **kwargs: Any) -> None: - """Create an image prompt template.""" + """Create an image prompt template. + + Raises: + ValueError: If the input variables contain ``'url'``, ``'path'``, or + ``'detail'``. + """ if "input_variables" not in kwargs: kwargs["input_variables"] = [] @@ -44,7 +49,11 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]): @classmethod def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "prompts", "image"]`` + """ return ["langchain", "prompts", "image"] def format_prompt(self, **kwargs: Any) -> PromptValue: @@ -84,6 +93,7 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]): Raises: ValueError: If the url is not provided. ValueError: If the url is not a string. + ValueError: If ``'path'`` is provided in the template or kwargs. Example: @@ -128,9 +138,6 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]): Returns: A formatted string. - - Raises: - ValueError: If the path or url is not a string. """ return await run_in_executor(None, self.format, **kwargs) diff --git a/libs/core/langchain_core/prompts/message.py b/libs/core/langchain_core/prompts/message.py index 668374a19f0..409f54320b1 100644 --- a/libs/core/langchain_core/prompts/message.py +++ b/libs/core/langchain_core/prompts/message.py @@ -18,17 +18,15 @@ class BaseMessagePromptTemplate(Serializable, ABC): @classmethod def is_lc_serializable(cls) -> bool: - """Return whether or not the class is serializable. - - Returns: True. - """ + """Return True as this class is serializable.""" return True @classmethod def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Default namespace is ["langchain", "prompts", "chat"]. + Returns: + ``["langchain", "prompts", "chat"]`` """ return ["langchain", "prompts", "chat"] diff --git a/libs/core/langchain_core/prompts/pipeline.py b/libs/core/langchain_core/prompts/pipeline.py index bb11fda48fd..ee4ea4b0dca 100644 --- a/libs/core/langchain_core/prompts/pipeline.py +++ b/libs/core/langchain_core/prompts/pipeline.py @@ -55,7 +55,11 @@ class PipelinePromptTemplate(BasePromptTemplate): @classmethod def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "prompts", "pipeline"]`` + """ return ["langchain", "prompts", "pipeline"] @model_validator(mode="before") diff --git a/libs/core/langchain_core/prompts/prompt.py b/libs/core/langchain_core/prompts/prompt.py index 0066445a050..11a9922f92b 100644 --- a/libs/core/langchain_core/prompts/prompt.py +++ b/libs/core/langchain_core/prompts/prompt.py @@ -69,6 +69,11 @@ class PromptTemplate(StringPromptTemplate): @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "prompts", "prompt"]`` + """ return ["langchain", "prompts", "prompt"] template: str @@ -135,7 +140,16 @@ class PromptTemplate(StringPromptTemplate): return mustache_schema(self.template) def __add__(self, other: Any) -> PromptTemplate: - """Override the + operator to allow for combining prompt templates.""" + """Override the + operator to allow for combining prompt templates. + + Raises: + ValueError: If the template formats are not f-string or if there are + conflicting partial variables. + NotImplementedError: If the other object is not a ``PromptTemplate`` or str. + + Returns: + A new ``PromptTemplate`` that is the combination of the two. + """ # Allow for easy combining if isinstance(other, PromptTemplate): if self.template_format != "f-string": diff --git a/libs/core/langchain_core/prompts/string.py b/libs/core/langchain_core/prompts/string.py index 69b3fd64c82..12357bf3a27 100644 --- a/libs/core/langchain_core/prompts/string.py +++ b/libs/core/langchain_core/prompts/string.py @@ -268,7 +268,11 @@ class StringPromptTemplate(BasePromptTemplate, ABC): @classmethod def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "prompts", "base"]`` + """ return ["langchain", "prompts", "base"] def format_prompt(self, **kwargs: Any) -> PromptValue: diff --git a/libs/core/langchain_core/prompts/structured.py b/libs/core/langchain_core/prompts/structured.py index d05ace21ccf..0d2c5d90b0f 100644 --- a/libs/core/langchain_core/prompts/structured.py +++ b/libs/core/langchain_core/prompts/structured.py @@ -68,8 +68,11 @@ class StructuredPrompt(ChatPromptTemplate): def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - For example, if the class is `langchain.llms.openai.OpenAI`, then the - namespace is ["langchain", "llms", "openai"] + For example, if the class is ``langchain.llms.openai.OpenAI``, then the + namespace is ``["langchain", "llms", "openai"]`` + + Returns: + The namespace of the langchain object. """ return cls.__module__.split(".") diff --git a/libs/core/langchain_core/retrievers.py b/libs/core/langchain_core/retrievers.py index 2a7cb681ff8..8e1acf56c16 100644 --- a/libs/core/langchain_core/retrievers.py +++ b/libs/core/langchain_core/retrievers.py @@ -362,6 +362,7 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC): Args: query: String to find relevant documents for run_manager: The callback handler to use + Returns: List of relevant documents """ diff --git a/libs/core/langchain_core/runnables/base.py b/libs/core/langchain_core/runnables/base.py index c065cc7afbf..1f90b2f608c 100644 --- a/libs/core/langchain_core/runnables/base.py +++ b/libs/core/langchain_core/runnables/base.py @@ -245,7 +245,15 @@ class Runnable(ABC, Generic[Input, Output]): def get_name( self, suffix: Optional[str] = None, *, name: Optional[str] = None ) -> str: - """Get the name of the ``Runnable``.""" + """Get the name of the ``Runnable``. + + Args: + suffix: An optional suffix to append to the name. + name: An optional name to use instead of the ``Runnable``'s name. + + Returns: + The name of the ``Runnable``. + """ if name: name_ = name elif hasattr(self, "name") and self.name: @@ -276,7 +284,13 @@ class Runnable(ABC, Generic[Input, Output]): @property def InputType(self) -> type[Input]: # noqa: N802 - """The type of input this ``Runnable`` accepts specified as a type annotation.""" # noqa: E501 + """Input type. + + The type of input this ``Runnable`` accepts specified as a type annotation. + + Raises: + TypeError: If the input type cannot be inferred. + """ # First loop through all parent classes and if any of them is # a pydantic model, we will pick up the generic parameterization # from that model via the __pydantic_generic_metadata__ attribute. @@ -302,7 +316,13 @@ class Runnable(ABC, Generic[Input, Output]): @property def OutputType(self) -> type[Output]: # noqa: N802 - """The type of output this ``Runnable`` produces specified as a type annotation.""" # noqa: E501 + """Output Type. + + The type of output this ``Runnable`` produces specified as a type annotation. + + Raises: + TypeError: If the output type cannot be inferred. + """ # First loop through bases -- this will help generic # any pydantic models. for base in self.__class__.mro(): @@ -583,7 +603,17 @@ class Runnable(ABC, Generic[Input, Output]): Mapping[str, Union[Runnable[Any, Other], Callable[[Any], Other], Any]], ], ) -> RunnableSerializable[Input, Other]: - """Compose this ``Runnable`` with another object to create a ``RunnableSequence``.""" # noqa: E501 + """Runnable "or" operator. + + Compose this ``Runnable`` with another object to create a + ``RunnableSequence``. + + Args: + other: Another ``Runnable`` or a ``Runnable``-like object. + + Returns: + A new ``Runnable``. + """ return RunnableSequence(self, coerce_to_runnable(other)) def __ror__( @@ -596,7 +626,17 @@ class Runnable(ABC, Generic[Input, Output]): Mapping[str, Union[Runnable[Other, Any], Callable[[Other], Any], Any]], ], ) -> RunnableSerializable[Other, Output]: - """Compose this ``Runnable`` with another object to create a ``RunnableSequence``.""" # noqa: E501 + """Runnable "reverse-or" operator. + + Compose this ``Runnable`` with another object to create a + ``RunnableSequence``. + + Args: + other: Another ``Runnable`` or a ``Runnable``-like object. + + Returns: + A new ``Runnable``. + """ return RunnableSequence(coerce_to_runnable(other), self) def pipe( @@ -604,11 +644,15 @@ class Runnable(ABC, Generic[Input, Output]): *others: Union[Runnable[Any, Other], Callable[[Any], Other]], name: Optional[str] = None, ) -> RunnableSerializable[Input, Other]: - """Compose this ``Runnable`` with ``Runnable``-like objects to make a ``RunnableSequence``. + """Pipe runnables. + + Compose this ``Runnable`` with ``Runnable``-like objects to make a + ``RunnableSequence``. Equivalent to ``RunnableSequence(self, *others)`` or ``self | others[0] | ...`` Example: + .. code-block:: python from langchain_core.runnables import RunnableLambda @@ -636,13 +680,20 @@ class Runnable(ABC, Generic[Input, Output]): await sequence.abatch([1, 2, 3]) # -> [4, 6, 8] - """ # noqa: E501 + Args: + *others: Other ``Runnable`` or ``Runnable``-like objects to compose + name: An optional name for the resulting ``RunnableSequence``. + + Returns: + A new ``Runnable``. + """ return RunnableSequence(self, *others, name=name) def pick(self, keys: Union[str, list[str]]) -> RunnableSerializable[Any, Any]: """Pick keys from the output dict of this ``Runnable``. Pick single key: + .. code-block:: python import json @@ -661,6 +712,7 @@ class Runnable(ABC, Generic[Input, Output]): # -> [1, 2, 3] Pick list of keys: + .. code-block:: python from typing import Any @@ -688,6 +740,12 @@ class Runnable(ABC, Generic[Input, Output]): json_and_bytes_chain.invoke("[1, 2, 3]") # -> {"json": [1, 2, 3], "bytes": b"[1, 2, 3]"} + Args: + keys: A key or list of keys to pick from the output dict. + + Returns: + a new ``Runnable``. + """ from langchain_core.runnables.passthrough import RunnablePick @@ -706,8 +764,6 @@ class Runnable(ABC, Generic[Input, Output]): ) -> RunnableSerializable[Any, Any]: """Assigns new fields to the dict output of this ``Runnable``. - Returns a new ``Runnable``. - .. code-block:: python from langchain_community.llms.fake import FakeStreamingListLLM @@ -734,6 +790,13 @@ class Runnable(ABC, Generic[Input, Output]): {'str': {'title': 'Str', 'type': 'string'}, 'hello': {'title': 'Hello', 'type': 'string'}}} + Args: + **kwargs: A mapping of keys to ``Runnable`` or ``Runnable``-like objects + that will be invoked with the entire output dict of this ``Runnable``. + + Returns: + A new ``Runnable``. + """ from langchain_core.runnables.passthrough import RunnableAssign @@ -769,12 +832,18 @@ class Runnable(ABC, Generic[Input, Output]): config: Optional[RunnableConfig] = None, **kwargs: Any, ) -> Output: - """Default implementation of ``ainvoke``, calls ``invoke`` from a thread. + """Transform a single input into an output. - The default implementation allows usage of async code even if - the ``Runnable`` did not implement a native async version of ``invoke``. + Args: + input: The input to the ``Runnable``. + config: A config to use when invoking the ``Runnable``. + The config supports standard keys like ``'tags'``, ``'metadata'`` for + tracing purposes, ``'max_concurrency'`` for controlling how much work to + do in parallel, and other keys. Please refer to the ``RunnableConfig`` + for more details. Defaults to None. - Subclasses should override this method if they can run asynchronously. + Returns: + The output of the ``Runnable``. """ return await run_in_executor(config, self.invoke, input, config, **kwargs) @@ -794,6 +863,20 @@ class Runnable(ABC, Generic[Input, Output]): Subclasses should override this method if they can batch more efficiently; e.g., if the underlying ``Runnable`` uses an API which supports a batch mode. + Args: + inputs: A list of inputs to the ``Runnable``. + config: A config to use when invoking the ``Runnable``. + The config supports standard keys like ``'tags'``, ``'metadata'`` for + tracing purposes, ``'max_concurrency'`` for controlling how much work + to do in parallel, and other keys. Please refer to the + ``RunnableConfig`` for more details. Defaults to None. + return_exceptions: Whether to return exceptions instead of raising them. + Defaults to False. + **kwargs: Additional keyword arguments to pass to the ``Runnable``. + + Returns: + A list of outputs from the ``Runnable``. + """ if not inputs: return [] @@ -848,6 +931,20 @@ class Runnable(ABC, Generic[Input, Output]): Yields results as they complete. + Args: + inputs: A list of inputs to the ``Runnable``. + config: A config to use when invoking the ``Runnable``. + The config supports standard keys like ``'tags'``, ``'metadata'`` for + tracing purposes, ``'max_concurrency'`` for controlling how much work to + do in parallel, and other keys. Please refer to the ``RunnableConfig`` + for more details. Defaults to None. + return_exceptions: Whether to return exceptions instead of raising them. + Defaults to False. + **kwargs: Additional keyword arguments to pass to the ``Runnable``. + + Yields: + Tuples of the index of the input and the output from the ``Runnable``. + """ if not inputs: return @@ -912,7 +1009,7 @@ class Runnable(ABC, Generic[Input, Output]): for more details. Defaults to None. return_exceptions: Whether to return exceptions instead of raising them. Defaults to False. - kwargs: Additional keyword arguments to pass to the ``Runnable``. + **kwargs: Additional keyword arguments to pass to the ``Runnable``. Returns: A list of outputs from the ``Runnable``. @@ -2560,6 +2657,9 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): Args: **kwargs: A dictionary of ``ConfigurableField`` instances to configure. + Raises: + ValueError: If a configuration key is not found in the ``Runnable``. + Returns: A new ``Runnable`` with the fields configured. @@ -2873,6 +2973,11 @@ class RunnableSequence(RunnableSerializable[Input, Output]): @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @property @@ -2887,14 +2992,7 @@ class RunnableSequence(RunnableSerializable[Input, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Check if the object is serializable. - - Returns: - True if the object is serializable, False otherwise. - - Defaults to True. - - """ + """Return True as this class is serializable.""" return True model_config = ConfigDict( @@ -3666,11 +3764,17 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] model_config = ConfigDict( @@ -4700,7 +4804,7 @@ class RunnableLambda(Runnable[Input, Output]): __hash__ = None # type: ignore[assignment] def __repr__(self) -> str: - """A string representation of this ``Runnable``.""" + """Return a string representation of this ``Runnable``.""" if self._repr is None: if hasattr(self, "func") and isinstance(self.func, itemgetter): self._repr = f"RunnableLambda({str(self.func)[len('operator.') :]})" @@ -5213,11 +5317,17 @@ class RunnableEachBase(RunnableSerializable[list[Input], list[Output]]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] def _invoke( @@ -5537,6 +5647,7 @@ class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[ @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @@ -5544,7 +5655,8 @@ class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[ def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Defaults to ``["langchain", "schema", "runnable"]``. + Returns: + ``["langchain", "schema", "runnable"]`` """ return ["langchain", "schema", "runnable"] diff --git a/libs/core/langchain_core/runnables/branch.py b/libs/core/langchain_core/runnables/branch.py index cecc8f34b5f..bd8e8c64a76 100644 --- a/libs/core/langchain_core/runnables/branch.py +++ b/libs/core/langchain_core/runnables/branch.py @@ -144,12 +144,17 @@ class RunnableBranch(RunnableSerializable[Input, Output]): @classmethod def is_lc_serializable(cls) -> bool: - """RunnableBranch is serializable if all its branches are serializable.""" + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @override @@ -260,7 +265,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]): async def ainvoke( self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any ) -> Output: - """Async version of invoke.""" config = ensure_config(config) callback_manager = get_async_callback_manager_for_config(config) run_manager = await callback_manager.on_chain_start( @@ -321,9 +325,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]): Yields: The output of the branch that was run. - - Raises: - BaseException: If an error occurs during the execution of the Runnable. """ config = ensure_config(config) callback_manager = get_callback_manager_for_config(config) @@ -408,9 +409,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]): Yields: The output of the branch that was run. - - Raises: - BaseException: If an error occurs during the execution of the Runnable. """ config = ensure_config(config) callback_manager = get_async_callback_manager_for_config(config) diff --git a/libs/core/langchain_core/runnables/config.py b/libs/core/langchain_core/runnables/config.py index cc36622b914..98090872a34 100644 --- a/libs/core/langchain_core/runnables/config.py +++ b/libs/core/langchain_core/runnables/config.py @@ -125,6 +125,9 @@ def _set_config_context( Args: config (RunnableConfig): The config to set. + + Returns: + The token to reset the config and the previous tracing context. """ from langchain_core.tracers.langchain import LangChainTracer @@ -160,6 +163,9 @@ def set_config_context(config: RunnableConfig) -> Generator[Context, None, None] Args: config (RunnableConfig): The config to set. + + Yields: + The config context. """ from langsmith.run_helpers import _set_tracing_context @@ -598,9 +604,6 @@ async def run_in_executor( Returns: Output: The output of the function. - - Raises: - RuntimeError: If the function raises a StopIteration. """ def wrapper() -> T: diff --git a/libs/core/langchain_core/runnables/configurable.py b/libs/core/langchain_core/runnables/configurable.py index a0f9f53a06d..46138b64adf 100644 --- a/libs/core/langchain_core/runnables/configurable.py +++ b/libs/core/langchain_core/runnables/configurable.py @@ -70,11 +70,17 @@ class DynamicRunnable(RunnableSerializable[Input, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @property diff --git a/libs/core/langchain_core/runnables/fallbacks.py b/libs/core/langchain_core/runnables/fallbacks.py index 7b0b845c206..ede6fcb572d 100644 --- a/libs/core/langchain_core/runnables/fallbacks.py +++ b/libs/core/langchain_core/runnables/fallbacks.py @@ -140,6 +140,7 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @@ -147,13 +148,18 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): def get_lc_namespace(cls) -> list[str]: """Get the namespace of the langchain object. - Defaults to ["langchain", "schema", "runnable"]. + Returns: + ``["langchain", "schema", "runnable"]`` """ return ["langchain", "schema", "runnable"] @property def runnables(self) -> Iterator[Runnable[Input, Output]]: - """Iterator over the Runnable and its fallbacks.""" + """Iterator over the Runnable and its fallbacks. + + Yields: + The Runnable then its fallbacks. + """ yield self.runnable yield from self.fallbacks diff --git a/libs/core/langchain_core/runnables/graph.py b/libs/core/langchain_core/runnables/graph.py index 20a841d51a8..7dc5ffc2329 100644 --- a/libs/core/langchain_core/runnables/graph.py +++ b/libs/core/langchain_core/runnables/graph.py @@ -475,6 +475,10 @@ class Graph: If there is no such node, or there are multiple, return None. When drawing the graph, this node would be the origin. + + Returns: + The first node, or None if there is no such node or multiple + candidates. """ return _first_node(self) @@ -483,6 +487,10 @@ class Graph: If there is no such node, or there are multiple, return None. When drawing the graph, this node would be the destination. + + Returns: + The last node, or None if there is no such node or multiple + candidates. """ return _last_node(self) @@ -513,7 +521,11 @@ class Graph: self.remove_node(last_node) def draw_ascii(self) -> str: - """Draw the graph as an ASCII art string.""" + """Draw the graph as an ASCII art string. + + Returns: + The ASCII art string. + """ from langchain_core.runnables.graph_ascii import draw_ascii return draw_ascii( diff --git a/libs/core/langchain_core/runnables/graph_ascii.py b/libs/core/langchain_core/runnables/graph_ascii.py index c33353148d8..9c11c585cd1 100644 --- a/libs/core/langchain_core/runnables/graph_ascii.py +++ b/libs/core/langchain_core/runnables/graph_ascii.py @@ -50,8 +50,11 @@ class AsciiCanvas: """Create an ASCII canvas. Args: - cols (int): number of columns in the canvas. Should be > 1. - lines (int): number of lines in the canvas. Should be > 1. + cols: number of columns in the canvas. Should be ``> 1``. + lines: number of lines in the canvas. Should be ``> 1``. + + Raises: + ValueError: if canvas dimensions are invalid. """ if cols <= 1 or lines <= 1: msg = "Canvas dimensions should be > 1" @@ -63,7 +66,11 @@ class AsciiCanvas: self.canvas = [[" "] * cols for line in range(lines)] def draw(self) -> str: - """Draws ASCII canvas on the screen.""" + """Draws ASCII canvas on the screen. + + Returns: + The ASCII canvas string. + """ lines = map("".join, self.canvas) return os.linesep.join(lines) @@ -71,12 +78,16 @@ class AsciiCanvas: """Create a point on ASCII canvas. Args: - x (int): x coordinate. Should be >= 0 and < number of columns in + x: x coordinate. Should be ``>= 0`` and ``<`` number of columns in the canvas. - y (int): y coordinate. Should be >= 0 an < number of lines in the + y: y coordinate. Should be ``>= 0`` an ``<`` number of lines in the canvas. - char (str): character to place in the specified point on the + char: character to place in the specified point on the canvas. + + Raises: + ValueError: if char is not a single character or if + coordinates are out of bounds. """ if len(char) != 1: msg = "char should be a single character" @@ -225,11 +236,15 @@ def draw_ascii(vertices: Mapping[str, str], edges: Sequence[LangEdge]) -> str: """Build a DAG and draw it in ASCII. Args: - vertices (list): list of graph vertices. - edges (list): list of graph edges. + vertices: list of graph vertices. + edges: list of graph edges. + + Raises: + ValueError: if the canvas dimensions are invalid or if + edge coordinates are invalid. Returns: - str: ASCII representation + ASCII representation Example: diff --git a/libs/core/langchain_core/runnables/graph_png.py b/libs/core/langchain_core/runnables/graph_png.py index 504236188ce..c7d15c85127 100644 --- a/libs/core/langchain_core/runnables/graph_png.py +++ b/libs/core/langchain_core/runnables/graph_png.py @@ -85,9 +85,6 @@ class PngDrawer: Args: viz: The graphviz object. node: The node to add. - - Returns: - None """ viz.add_node( node, @@ -114,9 +111,6 @@ class PngDrawer: target: The target node. label: The label for the edge. Defaults to None. conditional: Whether the edge is conditional. Defaults to False. - - Returns: - None """ viz.add_edge( source, @@ -131,8 +125,16 @@ class PngDrawer: """Draw the given state graph into a PNG file. Requires `graphviz` and `pygraphviz` to be installed. - :param graph: The graph to draw - :param output_path: The path to save the PNG. If None, PNG bytes are returned. + + Args: + graph: The graph to draw + output_path: The path to save the PNG. If None, PNG bytes are returned. + + Raises: + ImportError: If ``pygraphviz`` is not installed. + + Returns: + The PNG bytes if ``output_path`` is None, else None. """ try: import pygraphviz as pgv # type: ignore[import-not-found] diff --git a/libs/core/langchain_core/runnables/passthrough.py b/libs/core/langchain_core/runnables/passthrough.py index afc28e54d42..848bf264c63 100644 --- a/libs/core/langchain_core/runnables/passthrough.py +++ b/libs/core/langchain_core/runnables/passthrough.py @@ -193,11 +193,16 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod - @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @property @@ -417,11 +422,17 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @override @@ -721,12 +732,17 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]): @classmethod @override def is_lc_serializable(cls) -> bool: + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @override diff --git a/libs/core/langchain_core/runnables/router.py b/libs/core/langchain_core/runnables/router.py index 7cc947fe9a8..827e75c6624 100644 --- a/libs/core/langchain_core/runnables/router.py +++ b/libs/core/langchain_core/runnables/router.py @@ -98,13 +98,17 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return whether this class is serializable.""" + """Return True as this class is serializable.""" return True @classmethod @override def get_lc_namespace(cls) -> list[str]: - """Get the namespace of the langchain object.""" + """Get the namespace of the langchain object. + + Returns: + ``["langchain", "schema", "runnable"]`` + """ return ["langchain", "schema", "runnable"] @override diff --git a/libs/core/langchain_core/runnables/utils.py b/libs/core/langchain_core/runnables/utils.py index 3a740e868eb..eb4c0cd43d5 100644 --- a/libs/core/langchain_core/runnables/utils.py +++ b/libs/core/langchain_core/runnables/utils.py @@ -122,7 +122,12 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002 @lru_cache(maxsize=1) def asyncio_accepts_context() -> bool: - """Cache the result of checking if asyncio.create_task accepts a ``context`` arg.""" + """Cache the result of checking if asyncio.create_task accepts a ``context`` arg. + + Returns: + bool: True if ``asyncio.create_task`` accepts a context argument, False + otherwise. + """ return accepts_context(asyncio.create_task) @@ -160,14 +165,11 @@ class IsLocalDict(ast.NodeVisitor): self.keys = keys @override - def visit_Subscript(self, node: ast.Subscript) -> Any: + def visit_Subscript(self, node: ast.Subscript) -> None: """Visit a subscript node. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if ( isinstance(node.ctx, ast.Load) @@ -180,14 +182,11 @@ class IsLocalDict(ast.NodeVisitor): self.keys.add(node.slice.value) @override - def visit_Call(self, node: ast.Call) -> Any: + def visit_Call(self, node: ast.Call) -> None: """Visit a call node. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if ( isinstance(node.func, ast.Attribute) @@ -210,14 +209,11 @@ class IsFunctionArgDict(ast.NodeVisitor): self.keys: set[str] = set() @override - def visit_Lambda(self, node: ast.Lambda) -> Any: + def visit_Lambda(self, node: ast.Lambda) -> None: """Visit a lambda function. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if not node.args.args: return @@ -225,14 +221,11 @@ class IsFunctionArgDict(ast.NodeVisitor): IsLocalDict(input_arg_name, self.keys).visit(node.body) @override - def visit_FunctionDef(self, node: ast.FunctionDef) -> Any: + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: """Visit a function definition. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if not node.args.args: return @@ -240,14 +233,11 @@ class IsFunctionArgDict(ast.NodeVisitor): IsLocalDict(input_arg_name, self.keys).visit(node) @override - def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> Any: + def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None: """Visit an async function definition. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if not node.args.args: return @@ -264,14 +254,11 @@ class NonLocals(ast.NodeVisitor): self.stores: set[str] = set() @override - def visit_Name(self, node: ast.Name) -> Any: + def visit_Name(self, node: ast.Name) -> None: """Visit a name node. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if isinstance(node.ctx, ast.Load): self.loads.add(node.id) @@ -279,14 +266,11 @@ class NonLocals(ast.NodeVisitor): self.stores.add(node.id) @override - def visit_Attribute(self, node: ast.Attribute) -> Any: + def visit_Attribute(self, node: ast.Attribute) -> None: """Visit an attribute node. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ if isinstance(node.ctx, ast.Load): parent = node.value @@ -321,42 +305,33 @@ class FunctionNonLocals(ast.NodeVisitor): self.nonlocals: set[str] = set() @override - def visit_FunctionDef(self, node: ast.FunctionDef) -> Any: + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: """Visit a function definition. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ visitor = NonLocals() visitor.visit(node) self.nonlocals.update(visitor.loads - visitor.stores) @override - def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> Any: + def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None: """Visit an async function definition. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ visitor = NonLocals() visitor.visit(node) self.nonlocals.update(visitor.loads - visitor.stores) @override - def visit_Lambda(self, node: ast.Lambda) -> Any: + def visit_Lambda(self, node: ast.Lambda) -> None: """Visit a lambda function. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ visitor = NonLocals() visitor.visit(node) @@ -372,14 +347,11 @@ class GetLambdaSource(ast.NodeVisitor): self.count = 0 @override - def visit_Lambda(self, node: ast.Lambda) -> Any: + def visit_Lambda(self, node: ast.Lambda) -> None: """Visit a lambda function. Args: node: The node to visit. - - Returns: - Any: The result of the visit. """ self.count += 1 if hasattr(ast, "unparse"): @@ -496,6 +468,9 @@ class AddableDict(dict[str, Any]): Args: other: The other dictionary to add. + + Returns: + A dictionary that is the result of adding the two dictionaries. """ chunk = AddableDict(self) for key in other: @@ -514,6 +489,9 @@ class AddableDict(dict[str, Any]): Args: other: The other dictionary to be added to. + + Returns: + A dictionary that is the result of adding the two dictionaries. """ chunk = AddableDict(other) for key in self: diff --git a/libs/core/langchain_core/stores.py b/libs/core/langchain_core/stores.py index e6df8fd93eb..7f51b4c4b5a 100644 --- a/libs/core/langchain_core/stores.py +++ b/libs/core/langchain_core/stores.py @@ -16,6 +16,8 @@ from typing import ( Union, ) +from typing_extensions import override + from langchain_core.exceptions import LangChainException from langchain_core.runnables import run_in_executor @@ -206,27 +208,13 @@ class InMemoryBaseStore(BaseStore[str, V], Generic[V]): """ return self.mget(keys) + @override def mset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None: - """Set the values for the given keys. - - Args: - key_value_pairs (Sequence[tuple[str, V]]): A sequence of key-value pairs. - - Returns: - None - """ for key, value in key_value_pairs: self.store[key] = value + @override async def amset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None: - """Async set the values for the given keys. - - Args: - key_value_pairs (Sequence[tuple[str, V]]): A sequence of key-value pairs. - - Returns: - None - """ return self.mset(key_value_pairs) def mdelete(self, keys: Sequence[str]) -> None: diff --git a/libs/core/langchain_core/tools/base.py b/libs/core/langchain_core/tools/base.py index e93cb74dc6b..d1b18a3aa42 100644 --- a/libs/core/langchain_core/tools/base.py +++ b/libs/core/langchain_core/tools/base.py @@ -506,7 +506,12 @@ class ChildTool(BaseTool): """ def __init__(self, **kwargs: Any) -> None: - """Initialize the tool.""" + """Initialize the tool. + + Raises: + TypeError: If ``args_schema`` is not a subclass of pydantic ``BaseModel`` or + dict. + """ if ( "args_schema" in kwargs and kwargs["args_schema"] is not None @@ -628,9 +633,10 @@ class ChildTool(BaseTool): The parsed and validated input. Raises: - ValueError: If string input is provided with JSON schema or if - InjectedToolCallId is required but not provided. - NotImplementedError: If args_schema is not a supported type. + ValueError: If string input is provided with JSON schema ``args_schema``. + ValueError: If InjectedToolCallId is required but ``tool_call_id`` is not + provided. + TypeError: If args_schema is not a Pydantic ``BaseModel`` or dict. """ input_args = self.args_schema if isinstance(tool_input, str): @@ -725,6 +731,9 @@ class ChildTool(BaseTool): Add run_manager: Optional[CallbackManagerForToolRun] = None to child implementations to enable tracing. + + Returns: + The result of the tool execution. """ async def _arun(self, *args: Any, **kwargs: Any) -> Any: @@ -732,6 +741,9 @@ class ChildTool(BaseTool): Add run_manager: Optional[AsyncCallbackManagerForToolRun] = None to child implementations to enable tracing. + + Returns: + The result of the tool execution. """ if kwargs.get("run_manager") and signature(self._run).parameters.get( "run_manager" @@ -1312,6 +1324,9 @@ def get_all_basemodel_annotations( Args: cls: The Pydantic BaseModel class. default_to_bound: Whether to default to the bound of a TypeVar if it exists. + + Returns: + A dictionary of field names to their type annotations. """ # cls has no subscript: cls = FooBar if isinstance(cls, type): diff --git a/libs/core/langchain_core/tools/convert.py b/libs/core/langchain_core/tools/convert.py index 2693ce80150..84b328f0bed 100644 --- a/libs/core/langchain_core/tools/convert.py +++ b/libs/core/langchain_core/tools/convert.py @@ -119,6 +119,17 @@ def tool( whether to raise ValueError on invalid Google Style docstrings. Defaults to True. + Raises: + ValueError: If too many positional arguments are provided. + ValueError: If a runnable is provided without a string name. + ValueError: If the first argument is not a string or callable with + a ``__name__`` attribute. + ValueError: If the function does not have a docstring and description + is not provided and ``infer_schema`` is False. + ValueError: If ``parse_docstring`` is True and the function has an invalid + Google-style docstring and ``error_on_invalid_docstring`` is True. + ValueError: If a Runnable is provided that does not have an object schema. + Returns: The tool. diff --git a/libs/core/langchain_core/tools/simple.py b/libs/core/langchain_core/tools/simple.py index 05dc1917644..40c58e372e1 100644 --- a/libs/core/langchain_core/tools/simple.py +++ b/libs/core/langchain_core/tools/simple.py @@ -76,7 +76,19 @@ class Tool(BaseTool): def _to_args_and_kwargs( self, tool_input: Union[str, dict], tool_call_id: Optional[str] ) -> tuple[tuple, dict]: - """Convert tool input to pydantic model.""" + """Convert tool input to pydantic model. + + Args: + tool_input: The input to the tool. + tool_call_id: The ID of the tool call. + + Raises: + ToolException: If the tool input is invalid. + + Returns: + the pydantic model args and kwargs. + + """ args, kwargs = super()._to_args_and_kwargs(tool_input, tool_call_id) # For backwards compatibility. The tool must be run with a single input all_args = list(args) + list(kwargs.values()) @@ -96,7 +108,17 @@ class Tool(BaseTool): run_manager: Optional[CallbackManagerForToolRun] = None, **kwargs: Any, ) -> Any: - """Use the tool.""" + """Use the tool. + + Args: + *args: Positional arguments to pass to the tool + config: Configuration for the run + run_manager: Optional callback manager to use for the run + **kwargs: Keyword arguments to pass to the tool + + Returns: + The result of the tool execution + """ if self.func: if run_manager and signature(self.func).parameters.get("callbacks"): kwargs["callbacks"] = run_manager.get_child() @@ -113,7 +135,17 @@ class Tool(BaseTool): run_manager: Optional[AsyncCallbackManagerForToolRun] = None, **kwargs: Any, ) -> Any: - """Use the tool asynchronously.""" + """Use the tool asynchronously. + + Args: + *args: Positional arguments to pass to the tool + config: Configuration for the run + run_manager: Optional callback manager to use for the run + **kwargs: Keyword arguments to pass to the tool + + Returns: + The result of the tool execution + """ if self.coroutine: if run_manager and signature(self.coroutine).parameters.get("callbacks"): kwargs["callbacks"] = run_manager.get_child() diff --git a/libs/core/langchain_core/tools/structured.py b/libs/core/langchain_core/tools/structured.py index 7fcc3c26e5a..08078e92771 100644 --- a/libs/core/langchain_core/tools/structured.py +++ b/libs/core/langchain_core/tools/structured.py @@ -84,7 +84,17 @@ class StructuredTool(BaseTool): run_manager: Optional[CallbackManagerForToolRun] = None, **kwargs: Any, ) -> Any: - """Use the tool.""" + """Use the tool. + + Args: + *args: Positional arguments to pass to the tool + config: Configuration for the run + run_manager: Optional callback manager to use for the run + **kwargs: Keyword arguments to pass to the tool + + Returns: + The result of the tool execution + """ if self.func: if run_manager and signature(self.func).parameters.get("callbacks"): kwargs["callbacks"] = run_manager.get_child() @@ -101,7 +111,17 @@ class StructuredTool(BaseTool): run_manager: Optional[AsyncCallbackManagerForToolRun] = None, **kwargs: Any, ) -> Any: - """Use the tool asynchronously.""" + """Use the tool asynchronously. + + Args: + *args: Positional arguments to pass to the tool + config: Configuration for the run + run_manager: Optional callback manager to use for the run + **kwargs: Keyword arguments to pass to the tool + + Returns: + The result of the tool execution + """ if self.coroutine: if run_manager and signature(self.coroutine).parameters.get("callbacks"): kwargs["callbacks"] = run_manager.get_child() @@ -164,6 +184,9 @@ class StructuredTool(BaseTool): Raises: ValueError: If the function is not provided. + ValueError: If the function does not have a docstring and description + is not provided. + TypeError: If the ``args_schema`` is not a ``BaseModel`` or dict. Examples: diff --git a/libs/core/langchain_core/tracers/base.py b/libs/core/langchain_core/tracers/base.py index ee588606165..e33f0339af7 100644 --- a/libs/core/langchain_core/tracers/base.py +++ b/libs/core/langchain_core/tracers/base.py @@ -520,11 +520,11 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC): return retrieval_run def __deepcopy__(self, memo: dict) -> BaseTracer: - """Deepcopy the tracer.""" + """Return self.""" return self def __copy__(self) -> BaseTracer: - """Copy the tracer.""" + """Return self.""" return self diff --git a/libs/core/langchain_core/tracers/context.py b/libs/core/langchain_core/tracers/context.py index 58471a09ecc..838eaa6d8f5 100644 --- a/libs/core/langchain_core/tracers/context.py +++ b/libs/core/langchain_core/tracers/context.py @@ -43,7 +43,11 @@ run_collector_var: ContextVar[Optional[RunCollectorCallbackHandler]] = ContextVa def tracing_enabled( session_name: str = "default", # noqa: ARG001 ) -> Generator[TracerSessionV1, None, None]: - """Throw an error because this has been replaced by tracing_v2_enabled.""" + """Throw an error because this has been replaced by ``tracing_v2_enabled``. + + Raises: + RuntimeError: Always, because this function is deprecated. + """ msg = ( "tracing_enabled is no longer supported. Please use tracing_enabled_v2 instead." ) diff --git a/libs/core/langchain_core/tracers/core.py b/libs/core/langchain_core/tracers/core.py index 0a10b06ecaf..54261a2c224 100644 --- a/libs/core/langchain_core/tracers/core.py +++ b/libs/core/langchain_core/tracers/core.py @@ -71,7 +71,7 @@ class _TracerCore(ABC): for streaming events. - 'original+chat' is a format that is the same as 'original' except it does NOT raise an attribute error on_chat_model_start - kwargs: Additional keyword arguments that will be passed to + **kwargs: Additional keyword arguments that will be passed to the superclass. """ super().__init__(**kwargs) @@ -531,27 +531,43 @@ class _TracerCore(ABC): return retrieval_run def __deepcopy__(self, memo: dict) -> _TracerCore: - """Deepcopy the tracer.""" + """Return self deepcopied.""" return self def __copy__(self) -> _TracerCore: - """Copy the tracer.""" + """Return self copied.""" return self def _end_trace(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """End a trace for a run.""" + """End a trace for a run. + + Args: + run: The run. + """ return None def _on_run_create(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process a run upon creation.""" + """Process a run upon creation. + + Args: + run: The created run. + """ return None def _on_run_update(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process a run upon update.""" + """Process a run upon update. + + Args: + run: The updated run. + """ return None def _on_llm_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the LLM Run upon start.""" + """Process the LLM Run upon start. + + Args: + run: The LLM run. + """ return None def _on_llm_new_token( @@ -560,53 +576,107 @@ class _TracerCore(ABC): token: str, # noqa: ARG002 chunk: Optional[Union[GenerationChunk, ChatGenerationChunk]], # noqa: ARG002 ) -> Union[None, Coroutine[Any, Any, None]]: - """Process new LLM token.""" + """Process new LLM token. + + Args: + run: The LLM run. + token: The new token. + chunk: Optional chunk. + """ return None def _on_llm_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the LLM Run.""" + """Process the LLM Run. + + Args: + run: The LLM run. + """ return None def _on_llm_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the LLM Run upon error.""" + """Process the LLM Run upon error. + + Args: + run: The LLM run. + """ return None def _on_chain_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Chain Run upon start.""" + """Process the Chain Run upon start. + + Args: + run: The chain run. + """ return None def _on_chain_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Chain Run.""" + """Process the Chain Run. + + Args: + run: The chain run. + """ return None def _on_chain_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Chain Run upon error.""" + """Process the Chain Run upon error. + + Args: + run: The chain run. + """ return None def _on_tool_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Tool Run upon start.""" + """Process the Tool Run upon start. + + Args: + run: The tool run. + """ return None def _on_tool_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Tool Run.""" + """Process the Tool Run. + + Args: + run: The tool run. + """ return None def _on_tool_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Tool Run upon error.""" + """Process the Tool Run upon error. + + Args: + run: The tool run. + """ return None def _on_chat_model_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Chat Model Run upon start.""" + """Process the Chat Model Run upon start. + + Args: + run: The chat model run. + """ return None def _on_retriever_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Retriever Run upon start.""" + """Process the Retriever Run upon start. + + Args: + run: The retriever run. + """ return None def _on_retriever_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Retriever Run.""" + """Process the Retriever Run. + + Args: + run: The retriever run. + """ return None def _on_retriever_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 - """Process the Retriever Run upon error.""" + """Process the Retriever Run upon error. + + Args: + run: The retriever run. + """ return None diff --git a/libs/core/langchain_core/tracers/event_stream.py b/libs/core/langchain_core/tracers/event_stream.py index eff11bbb06a..b0e44d4eca1 100644 --- a/libs/core/langchain_core/tracers/event_stream.py +++ b/libs/core/langchain_core/tracers/event_stream.py @@ -155,7 +155,11 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand self.send_stream.send_nowait(event) def __aiter__(self) -> AsyncIterator[Any]: - """Iterate over the receive stream.""" + """Iterate over the receive stream. + + Returns: + An async iterator over the receive stream. + """ return self.receive_stream.__aiter__() async def tap_output_aiter( @@ -412,7 +416,6 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand parent_run_id: Optional[UUID] = None, **kwargs: Any, ) -> None: - """Run on new LLM token. Only available when streaming is enabled.""" run_info = self.run_map.get(run_id) chunk_: Union[GenerationChunk, BaseMessageChunk] @@ -458,7 +461,15 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand async def on_llm_end( self, response: LLMResult, *, run_id: UUID, **kwargs: Any ) -> None: - """End a trace for an LLM run.""" + """End a trace for an LLM run. + + Args: + response (LLMResult): The response which was generated. + run_id (UUID): The run ID. This is the ID of the current run. + + Raises: + ValueError: If the run type is not ``'llm'`` or ``'chat_model'``. + """ run_info = self.run_map.pop(run_id) inputs_ = run_info["inputs"] @@ -636,7 +647,15 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand @override async def on_tool_end(self, output: Any, *, run_id: UUID, **kwargs: Any) -> None: - """End a trace for a tool run.""" + """End a trace for a tool run. + + Args: + output: The output of the tool. + run_id: The run ID. This is the ID of the current run. + + Raises: + AssertionError: If the run ID is a tool call and does not have inputs + """ run_info = self.run_map.pop(run_id) if "inputs" not in run_info: msg = ( @@ -730,11 +749,11 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand ) def __deepcopy__(self, memo: dict) -> _AstreamEventsCallbackHandler: - """Deepcopy the tracer.""" + """Return self.""" return self def __copy__(self) -> _AstreamEventsCallbackHandler: - """Copy the tracer.""" + """Return self.""" return self diff --git a/libs/core/langchain_core/tracers/langchain.py b/libs/core/langchain_core/tracers/langchain.py index 4a6d0d82344..07e6618573e 100644 --- a/libs/core/langchain_core/tracers/langchain.py +++ b/libs/core/langchain_core/tracers/langchain.py @@ -53,7 +53,11 @@ def wait_for_all_tracers() -> None: def get_client() -> Client: - """Get the client.""" + """Get the client. + + Returns: + The LangSmith client. + """ return rt.get_cached_client() @@ -235,7 +239,6 @@ class LangChainTracer(BaseTracer): chunk: Optional[Union[GenerationChunk, ChatGenerationChunk]] = None, parent_run_id: Optional[UUID] = None, ) -> Run: - """Append token event to LLM run and return the run.""" run_id_str = str(run_id) if run_id_str not in self.run_has_token_event_map: self.run_has_token_event_map[run_id_str] = True diff --git a/libs/core/langchain_core/tracers/langchain_v1.py b/libs/core/langchain_core/tracers/langchain_v1.py index 63aab51eeea..92634f5c912 100644 --- a/libs/core/langchain_core/tracers/langchain_v1.py +++ b/libs/core/langchain_core/tracers/langchain_v1.py @@ -7,7 +7,11 @@ from typing import Any def get_headers(*args: Any, **kwargs: Any) -> Any: # noqa: ARG001 - """Throw an error because this has been replaced by get_headers.""" + """Throw an error because this has been replaced by get_headers. + + Raises: + RuntimeError: Always, because this function is deprecated. + """ msg = ( "get_headers for LangChainTracerV1 is no longer supported. " "Please use LangChainTracer instead." @@ -16,7 +20,11 @@ def get_headers(*args: Any, **kwargs: Any) -> Any: # noqa: ARG001 def LangChainTracerV1(*args: Any, **kwargs: Any) -> Any: # noqa: N802,ARG001 - """Throw an error because this has been replaced by LangChainTracer.""" + """Throw an error because this has been replaced by ``LangChainTracer``. + + Raises: + RuntimeError: Always, because this class is deprecated. + """ msg = ( "LangChainTracerV1 is no longer supported. Please use LangChainTracer instead." ) diff --git a/libs/core/langchain_core/tracers/log_stream.py b/libs/core/langchain_core/tracers/log_stream.py index dbf5ef2a6ae..2821ade0dc5 100644 --- a/libs/core/langchain_core/tracers/log_stream.py +++ b/libs/core/langchain_core/tracers/log_stream.py @@ -110,7 +110,17 @@ class RunLogPatch: self.ops = list(ops) def __add__(self, other: Union[RunLogPatch, Any]) -> RunLog: - """Combine two RunLogPatch instances.""" + """Combine two ``RunLogPatch`` instances. + + Args: + other: The other ``RunLogPatch`` to combine with. + + Raises: + TypeError: If the other object is not a ``RunLogPatch``. + + Returns: + A new ``RunLog`` representing the combination of the two. + """ if type(other) is RunLogPatch: ops = self.ops + other.ops state = jsonpatch.apply_patch(None, copy.deepcopy(ops)) @@ -150,7 +160,17 @@ class RunLog(RunLogPatch): self.state = state def __add__(self, other: Union[RunLogPatch, Any]) -> RunLog: - """Combine two RunLogs.""" + """Combine two ``RunLog``s. + + Args: + other: The other ``RunLog`` or ``RunLogPatch`` to combine with. + + Raises: + TypeError: If the other object is not a ``RunLog`` or ``RunLogPatch``. + + Returns: + A new ``RunLog`` representing the combination of the two. + """ if type(other) is RunLogPatch: ops = self.ops + other.ops state = jsonpatch.apply_patch(self.state, other.ops) @@ -167,7 +187,14 @@ class RunLog(RunLogPatch): @override def __eq__(self, other: object) -> bool: - """Check if two RunLogs are equal.""" + """Check if two ``RunLog``s are equal. + + Args: + other: The other ``RunLog`` to compare to. + + Returns: + True if the ``RunLog``s are equal, False otherwise. + """ # First compare that the state is the same if not isinstance(other, RunLog): return False @@ -250,7 +277,11 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler): self.root_id: Optional[UUID] = None def __aiter__(self) -> AsyncIterator[RunLogPatch]: - """Iterate over the stream of run logs.""" + """Iterate over the stream of run logs. + + Returns: + An async iterator over the run log patches. + """ return self.receive_stream.__aiter__() def send(self, *ops: dict[str, Any]) -> bool: @@ -623,6 +654,23 @@ async def _astream_log_implementation( The implementation has been factored out (at least temporarily) as both astream_log and astream_events relies on it. + + Args: + runnable: The runnable to run in streaming mode. + value: The input to the runnable. + config: The config to pass to the runnable. + stream: The stream to send the run logs to. + diff: Whether to yield run log patches (True) or full run logs (False). + with_streamed_output_list: Whether to include a list of all streamed + outputs in each patch. If False, only the final output will be included + in the patches. + **kwargs: Additional keyword arguments to pass to the runnable. + + Raises: + ValueError: If the callbacks in the config are of an unexpected type. + + Yields: + The run log patches or states, depending on the value of ``diff``. """ import jsonpatch diff --git a/libs/core/langchain_core/tracers/schemas.py b/libs/core/langchain_core/tracers/schemas.py index ea06cb2f9dc..cd3dd71fea7 100644 --- a/libs/core/langchain_core/tracers/schemas.py +++ b/libs/core/langchain_core/tracers/schemas.py @@ -18,7 +18,11 @@ from langchain_core._api import deprecated @deprecated("0.1.0", alternative="Use string instead.", removal="1.0") def RunTypeEnum() -> type[RunTypeEnumDep]: # noqa: N802 - """RunTypeEnum.""" + """``RunTypeEnum``. + + Returns: + The ``RunTypeEnum`` class. + """ warnings.warn( "RunTypeEnum is deprecated. Please directly use a string instead" " (e.g. 'llm', 'chain', 'tool').", diff --git a/libs/core/langchain_core/utils/aiter.py b/libs/core/langchain_core/utils/aiter.py index 701a2321726..7a0477c658e 100644 --- a/libs/core/langchain_core/utils/aiter.py +++ b/libs/core/langchain_core/utils/aiter.py @@ -94,7 +94,7 @@ class NoLock: exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> bool: - """Exception not handled.""" + """Return False, exception not suppressed.""" return False @@ -236,7 +236,11 @@ class Tee(Generic[T]): return self._children[item] def __iter__(self) -> Iterator[AsyncIterator[T]]: - """Iterate over the child iterators.""" + """Iterate over the child iterators. + + Yields: + The child iterators. + """ yield from self._children async def __aenter__(self) -> "Tee[T]": @@ -249,7 +253,11 @@ class Tee(Generic[T]): exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> bool: - """Close all child iterators.""" + """Close all child iterators. + + Returns: + False, exceptions not suppressed. + """ await self.aclose() return False @@ -318,8 +326,8 @@ async def abatch_iterate( size: The size of the batch. iterable: The async iterable to batch. - Returns: - An async iterator over the batches. + Yields: + The batches. """ batch: list[T] = [] async for element in iterable: diff --git a/libs/core/langchain_core/utils/env.py b/libs/core/langchain_core/utils/env.py index 9f37b3c4f47..51fd3d66e21 100644 --- a/libs/core/langchain_core/utils/env.py +++ b/libs/core/langchain_core/utils/env.py @@ -39,6 +39,9 @@ def get_from_dict_or_env( in the dictionary. default: The default value to return if the key is not in the dictionary or the environment. Defaults to None. + + Returns: + The dict value or the environment variable value. """ if isinstance(key, (list, tuple)): for k in key: diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index 61849113d1b..fff700651ea 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -146,6 +146,9 @@ def _convert_pydantic_to_openai_function( of the schema will be used. rm_titles: Whether to remove titles from the schema. Defaults to True. + Raises: + TypeError: If the model is not a Pydantic model. + Returns: The function description. """ @@ -323,6 +326,9 @@ def _format_tool_to_openai_function(tool: BaseTool) -> FunctionDescription: Args: tool: The tool to format. + Raises: + ValueError: If the tool call schema is not supported. + Returns: The function description. """ @@ -602,7 +608,20 @@ def convert_to_json_schema( *, strict: Optional[bool] = None, ) -> dict[str, Any]: - """Convert a schema representation to a JSON schema.""" + """Convert a schema representation to a JSON schema. + + Args: + schema: The schema to convert. + strict: If True, model output is guaranteed to exactly match the JSON Schema + provided in the function definition. If None, ``strict`` argument will not + be included in function definition. + + Raises: + ValueError: If the input is not a valid OpenAI-format tool. + + Returns: + A JSON schema representation of the input schema. + """ openai_tool = convert_to_openai_tool(schema, strict=strict) if ( not isinstance(openai_tool, dict) diff --git a/libs/core/langchain_core/utils/interactive_env.py b/libs/core/langchain_core/utils/interactive_env.py index 12676d0bd52..b974b3091eb 100644 --- a/libs/core/langchain_core/utils/interactive_env.py +++ b/libs/core/langchain_core/utils/interactive_env.py @@ -2,7 +2,11 @@ def is_interactive_env() -> bool: - """Determine if running within IPython or Jupyter.""" + """Determine if running within IPython or Jupyter. + + Returns: + True if running in an interactive environment, False otherwise. + """ import sys return hasattr(sys, "ps2") diff --git a/libs/core/langchain_core/utils/iter.py b/libs/core/langchain_core/utils/iter.py index ecd4ba60976..5ef7c98b048 100644 --- a/libs/core/langchain_core/utils/iter.py +++ b/libs/core/langchain_core/utils/iter.py @@ -31,7 +31,7 @@ class NoLock: exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> Literal[False]: - """Exception not handled.""" + """Return False (exception not suppressed).""" return False @@ -173,7 +173,11 @@ class Tee(Generic[T]): return self._children[item] def __iter__(self) -> Iterator[Iterator[T]]: - """Return an iterator over the child iterators.""" + """Return an iterator over the child iterators. + + Yields: + The child iterators. + """ yield from self._children def __enter__(self) -> "Tee[T]": @@ -186,7 +190,11 @@ class Tee(Generic[T]): exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> Literal[False]: - """Close all child iterators.""" + """Close all child iterators. + + Returns: + False (exception not suppressed). + """ self.close() return False diff --git a/libs/core/langchain_core/utils/json.py b/libs/core/langchain_core/utils/json.py index 98450587e1c..1306bb9d73c 100644 --- a/libs/core/langchain_core/utils/json.py +++ b/libs/core/langchain_core/utils/json.py @@ -26,6 +26,9 @@ def _custom_parser(multiline_string: Union[str, bytes, bytearray]) -> str: string containing unescaped newlines, tabs or quotes. This function replaces those characters with their escaped counterparts. (newlines in JSON must be double-escaped: `\\n`). + + Returns: + The modified string with escaped newlines, tabs and quotes. """ if isinstance(multiline_string, (bytes, bytearray)): multiline_string = multiline_string.decode() diff --git a/libs/core/langchain_core/utils/json_schema.py b/libs/core/langchain_core/utils/json_schema.py index 5463c245b41..2c0672ab645 100644 --- a/libs/core/langchain_core/utils/json_schema.py +++ b/libs/core/langchain_core/utils/json_schema.py @@ -49,10 +49,14 @@ def _dereference_refs_helper( """Inline every pure {'$ref':...}. But: + - if shallow_refs=True: only break cycles, do not inline nested refs - if shallow_refs=False: deep-inline all nested refs Also skip recursion under any key in skip_keys. + + Returns: + The object with refs dereferenced. """ if processed_refs is None: processed_refs = set() @@ -118,6 +122,9 @@ def dereference_refs( shallow-inline refs. - If provided (even as an empty list), we will recurse under every key and deep-inline all refs. + + Returns: + The schema with refs dereferenced. """ full = full_schema or schema_obj keys_to_skip = list(skip_keys) if skip_keys is not None else ["$defs"] diff --git a/libs/core/langchain_core/utils/loading.py b/libs/core/langchain_core/utils/loading.py index 7921f6a06c1..55066a7bf45 100644 --- a/libs/core/langchain_core/utils/loading.py +++ b/libs/core/langchain_core/utils/loading.py @@ -19,7 +19,11 @@ def try_load_from_hub( *args: Any, # noqa: ARG001 **kwargs: Any, # noqa: ARG001 ) -> Any: - """[DEPRECATED] Try to load from the old Hub.""" + """[DEPRECATED] Try to load from the old Hub. + + Returns: + None always, indicating that we shouldn't load from the old hub. + """ warnings.warn( "Loading from the deprecated github-based Hub is no longer supported. " "Please use the new LangChain Hub at https://smith.langchain.com/hub instead.", diff --git a/libs/core/langchain_core/utils/mustache.py b/libs/core/langchain_core/utils/mustache.py index 12cab8da0a3..fd2ae359176 100644 --- a/libs/core/langchain_core/utils/mustache.py +++ b/libs/core/langchain_core/utils/mustache.py @@ -214,17 +214,22 @@ def tokenize( def_rdel: The default right delimiter ("}}" by default, as in spec compliant mustache) - Returns: - A generator of mustache tags in the form of a tuple (tag_type, tag_key) - Where tag_type is one of: - * literal - * section - * inverted section - * end - * partial - * no escape - And tag_key is either the key or in the case of a literal tag, - the literal itself. + Yields: + Mustache tags in the form of a tuple (tag_type, tag_key) + where tag_type is one of: + + * literal + * section + * inverted section + * end + * partial + * no escape + + and tag_key is either the key or in the case of a literal tag, + the literal itself. + + Raises: + ChevronError: If there is a syntax error in the template. """ global _CURRENT_LINE, _LAST_TAG_LINE _CURRENT_LINE = 1 @@ -326,7 +331,7 @@ def tokenize( def _html_escape(string: str) -> str: - """HTML escape all of these " & < >.""" + """Return the HTML-escaped string with these characters escaped: ``" & < >``.""" html_codes = { '"': """, "<": "<", @@ -349,7 +354,7 @@ def _get_key( def_ldel: str, def_rdel: str, ) -> Any: - """Get a key from the current scope.""" + """Return a key from the current scope.""" # If the key is a dot if key == ".": # Then just return the current scope @@ -407,7 +412,11 @@ def _get_key( def _get_partial(name: str, partials_dict: Mapping[str, str]) -> str: - """Load a partial.""" + """Load a partial. + + Returns: + The partial. + """ try: # Maybe the partial is in the dictionary return partials_dict[name] diff --git a/libs/core/langchain_core/utils/pydantic.py b/libs/core/langchain_core/utils/pydantic.py index 08cd7c4522f..272868032d3 100644 --- a/libs/core/langchain_core/utils/pydantic.py +++ b/libs/core/langchain_core/utils/pydantic.py @@ -57,6 +57,9 @@ def get_pydantic_major_version() -> int: """DEPRECATED - Get the major version of Pydantic. Use PYDANTIC_VERSION.major instead. + + Returns: + The major version of Pydantic. """ return PYDANTIC_VERSION.major @@ -74,12 +77,20 @@ TBaseModel = TypeVar("TBaseModel", bound=PydanticBaseModel) def is_pydantic_v1_subclass(cls: type) -> bool: - """Check if the installed Pydantic version is 1.x-like.""" + """Check if the given class is Pydantic v1-like. + + Returns: + True if the given class is a subclass of Pydantic ``BaseModel`` 1.x. + """ return issubclass(cls, BaseModelV1) def is_pydantic_v2_subclass(cls: type) -> bool: - """Check if the installed Pydantic version is 1.x-like.""" + """Check if the given class is Pydantic v2-like. + + Returns: + True if the given class is a subclass of Pydantic BaseModel 2.x. + """ return issubclass(cls, BaseModel) @@ -90,6 +101,9 @@ def is_basemodel_subclass(cls: type) -> bool: * pydantic.BaseModel in Pydantic 2.x * pydantic.v1.BaseModel in Pydantic 2.x + + Returns: + True if the given class is a subclass of Pydantic ``BaseModel``. """ # Before we can use issubclass on the cls we need to check if it is a class if not inspect.isclass(cls) or isinstance(cls, GenericAlias): @@ -105,6 +119,9 @@ def is_basemodel_instance(obj: Any) -> bool: * pydantic.BaseModel in Pydantic 2.x * pydantic.v1.BaseModel in Pydantic 2.x + + Returns: + True if the given class is an instance of Pydantic ``BaseModel``. """ return isinstance(obj, (BaseModel, BaseModelV1)) @@ -262,7 +279,11 @@ def _create_subset_model( descriptions: Optional[dict] = None, fn_description: Optional[str] = None, ) -> type[BaseModel]: - """Create subset model using the same pydantic version as the input model.""" + """Create subset model using the same pydantic version as the input model. + + Returns: + The created subset model. + """ if issubclass(model, BaseModelV1): return _create_subset_model_v1( name, @@ -299,7 +320,14 @@ def get_fields(model: BaseModelV1) -> dict[str, ModelField]: ... def get_fields( model: Union[type[Union[BaseModel, BaseModelV1]], BaseModel, BaseModelV1], ) -> Union[dict[str, FieldInfoV2], dict[str, ModelField]]: - """Get the field names of a Pydantic model.""" + """Return the field names of a Pydantic model. + + Args: + model: The Pydantic model or instance. + + Raises: + TypeError: If the model is not a Pydantic model. + """ if hasattr(model, "model_fields"): return model.model_fields diff --git a/libs/core/langchain_core/utils/utils.py b/libs/core/langchain_core/utils/utils.py index a7467ec51e9..1a41b63dc28 100644 --- a/libs/core/langchain_core/utils/utils.py +++ b/libs/core/langchain_core/utils/utils.py @@ -21,17 +21,14 @@ from langchain_core.utils.pydantic import ( def xor_args(*arg_groups: tuple[str, ...]) -> Callable: - """Validate specified keyword args are mutually exclusive.". + """Validate specified keyword args are mutually exclusive. Args: *arg_groups (tuple[str, ...]): Groups of mutually exclusive keyword args. Returns: Callable: Decorator that validates the specified keyword args - are mutually exclusive - - Raises: - ValueError: If more than one arg in a group is defined. + are mutually exclusive. """ def decorator(func: Callable) -> Callable: @@ -381,10 +378,21 @@ def from_env( error_message: the error message which will be raised if the key is not found and no default value is provided. This will be raised as a ValueError. + + Returns: + factory method that will look up the value from the environment. """ def get_from_env_fn() -> Optional[str]: - """Get a value from an environment variable.""" + """Get a value from an environment variable. + + Raises: + ValueError: If the environment variable is not set and no default is + provided. + + Returns: + The value from the environment. + """ if isinstance(key, (list, tuple)): for k in key: if k in os.environ: @@ -445,7 +453,15 @@ def secret_from_env( """ def get_secret_from_env() -> Optional[SecretStr]: - """Get a value from an environment variable.""" + """Get a value from an environment variable. + + Raises: + ValueError: If the environment variable is not set and no default is + provided. + + Returns: + The secret from the environment. + """ if isinstance(key, (list, tuple)): for k in key: if k in os.environ: diff --git a/libs/core/langchain_core/vectorstores/base.py b/libs/core/langchain_core/vectorstores/base.py index 17fa6592c72..2c4425c9c5a 100644 --- a/libs/core/langchain_core/vectorstores/base.py +++ b/libs/core/langchain_core/vectorstores/base.py @@ -270,9 +270,6 @@ class VectorStore(ABC): Returns: List of IDs of the added texts. - - Raises: - ValueError: If the number of ids does not match the number of documents. """ if type(self).add_texts != VectorStore.add_texts: if "ids" not in kwargs: @@ -303,9 +300,6 @@ class VectorStore(ABC): Returns: List of IDs of the added texts. - - Raises: - ValueError: If the number of IDs does not match the number of documents. """ # If the async method has been overridden, we'll use that. if type(self).aadd_texts != VectorStore.aadd_texts: diff --git a/libs/core/langchain_core/vectorstores/in_memory.py b/libs/core/langchain_core/vectorstores/in_memory.py index e7787f8a882..0395478dfe9 100644 --- a/libs/core/langchain_core/vectorstores/in_memory.py +++ b/libs/core/langchain_core/vectorstores/in_memory.py @@ -189,7 +189,6 @@ class InMemoryVectorStore(VectorStore): ids: Optional[list[str]] = None, **kwargs: Any, ) -> list[str]: - """Add documents to the store.""" texts = [doc.page_content for doc in documents] vectors = self.embedding.embed_documents(texts) @@ -223,7 +222,6 @@ class InMemoryVectorStore(VectorStore): async def aadd_documents( self, documents: list[Document], ids: Optional[list[str]] = None, **kwargs: Any ) -> list[str]: - """Add documents to the store.""" texts = [doc.page_content for doc in documents] vectors = await self.embedding.aembed_documents(texts) From 01fdeede5011ab861c868f911c0e3c92a41d1b30 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 17:55:20 +0200 Subject: [PATCH 28/30] chore(core): fix some ruff preview rules (#32785) Co-authored-by: Mason Daugherty --- libs/core/langchain_core/_api/deprecation.py | 11 +++-- libs/core/langchain_core/embeddings/fake.py | 3 +- .../language_models/chat_models.py | 2 - libs/core/langchain_core/messages/ai.py | 5 +- libs/core/langchain_core/messages/base.py | 4 +- .../langchain_core/output_parsers/json.py | 4 +- .../langchain_core/output_parsers/list.py | 3 ++ .../langchain_core/output_parsers/string.py | 3 ++ libs/core/langchain_core/prompts/base.py | 2 +- libs/core/langchain_core/prompts/string.py | 2 +- .../langchain_core/runnables/graph_mermaid.py | 4 +- libs/core/langchain_core/tracers/core.py | 38 +++++++-------- libs/core/langchain_core/utils/aiter.py | 2 +- libs/core/langchain_core/utils/mustache.py | 2 +- libs/core/langchain_core/utils/utils.py | 2 +- libs/core/pyproject.toml | 48 ++++++++++++------- .../unit_tests/document_loaders/test_base.py | 2 + .../unit_tests/example_selectors/test_base.py | 3 ++ .../indexing/test_in_memory_indexer.py | 3 ++ .../unit_tests/indexing/test_indexing.py | 20 ++++---- .../tests/unit_tests/prompts/test_chat.py | 24 ++++++---- .../tests/unit_tests/prompts/test_loading.py | 4 +- .../unit_tests/prompts/test_structured.py | 2 + .../unit_tests/runnables/test_context.py | 2 +- .../unit_tests/runnables/test_runnable.py | 2 + .../tests/unit_tests/stores/test_in_memory.py | 5 ++ libs/core/tests/unit_tests/test_messages.py | 23 ++++----- libs/core/tests/unit_tests/test_tools.py | 33 +++++++++++-- libs/core/tests/unit_tests/utils/test_env.py | 2 +- libs/core/tests/unit_tests/utils/test_html.py | 22 ++++----- .../tests/unit_tests/utils/test_strings.py | 2 +- .../core/tests/unit_tests/utils/test_usage.py | 4 +- .../core/tests/unit_tests/utils/test_utils.py | 4 +- 33 files changed, 172 insertions(+), 120 deletions(-) diff --git a/libs/core/langchain_core/_api/deprecation.py b/libs/core/langchain_core/_api/deprecation.py index 7999d8a3216..bac037fbce5 100644 --- a/libs/core/langchain_core/_api/deprecation.py +++ b/libs/core/langchain_core/_api/deprecation.py @@ -361,7 +361,8 @@ def deprecated( # Modify the docstring to include a deprecation notice. if ( _alternative - and _alternative.split(".")[-1].lower() == _alternative.split(".")[-1] + and _alternative.rsplit(".", maxsplit=1)[-1].lower() + == _alternative.rsplit(".", maxsplit=1)[-1] ): _alternative = f":meth:`~{_alternative}`" elif _alternative: @@ -369,8 +370,8 @@ def deprecated( if ( _alternative_import - and _alternative_import.split(".")[-1].lower() - == _alternative_import.split(".")[-1] + and _alternative_import.rsplit(".", maxsplit=1)[-1].lower() + == _alternative_import.rsplit(".", maxsplit=1)[-1] ): _alternative_import = f":meth:`~{_alternative_import}`" elif _alternative_import: @@ -474,7 +475,7 @@ def warn_deprecated( if not message: message = "" package_ = ( - package or name.split(".")[0].replace("_", "-") + package or name.split(".", maxsplit=1)[0].replace("_", "-") if "." in name else "LangChain" ) @@ -493,7 +494,7 @@ def warn_deprecated( message += f" and will be removed {removal}" if alternative_import: - alt_package = alternative_import.split(".")[0].replace("_", "-") + alt_package = alternative_import.split(".", maxsplit=1)[0].replace("_", "-") if alt_package == package_: message += f". Use {alternative_import} instead." else: diff --git a/libs/core/langchain_core/embeddings/fake.py b/libs/core/langchain_core/embeddings/fake.py index 73b605dfa4b..cd644bf8c69 100644 --- a/libs/core/langchain_core/embeddings/fake.py +++ b/libs/core/langchain_core/embeddings/fake.py @@ -119,7 +119,8 @@ class DeterministicFakeEmbedding(Embeddings, BaseModel): rng = np.random.default_rng(seed) return list(rng.normal(size=self.size)) - def _get_seed(self, text: str) -> int: + @staticmethod + def _get_seed(text: str) -> int: """Get a seed for the random generator, using the hash of the text.""" return int(hashlib.sha256(text.encode("utf-8")).hexdigest(), 16) % 10**8 diff --git a/libs/core/langchain_core/language_models/chat_models.py b/libs/core/langchain_core/language_models/chat_models.py index f4ec3d48af9..a07115196bd 100644 --- a/libs/core/langchain_core/language_models/chat_models.py +++ b/libs/core/langchain_core/language_models/chat_models.py @@ -148,8 +148,6 @@ def _format_for_tracing(messages: list[BaseMessage]) -> list[BaseMessage]: "type": key, key: block[key], } - else: - pass messages_to_trace.append(message_to_trace) return messages_to_trace diff --git a/libs/core/langchain_core/messages/ai.py b/libs/core/langchain_core/messages/ai.py index e8640545649..e0208d5f5a3 100644 --- a/libs/core/langchain_core/messages/ai.py +++ b/libs/core/langchain_core/messages/ai.py @@ -352,10 +352,7 @@ class AIMessageChunk(AIMessage, BaseMessageChunk): for chunk in self.tool_call_chunks: try: - if chunk["args"] is not None and chunk["args"] != "": - args_ = parse_partial_json(chunk["args"]) - else: - args_ = {} + args_ = parse_partial_json(chunk["args"]) if chunk["args"] else {} if isinstance(args_, dict): tool_calls.append( create_tool_call( diff --git a/libs/core/langchain_core/messages/base.py b/libs/core/langchain_core/messages/base.py index 2f831d79d02..8810d1ecf13 100644 --- a/libs/core/langchain_core/messages/base.py +++ b/libs/core/langchain_core/messages/base.py @@ -179,9 +179,7 @@ def merge_content( elif merged and isinstance(merged[-1], str): merged[-1] += content # If second content is an empty string, treat as a no-op - elif content == "": - pass - else: + elif content: # Otherwise, add the second content as a new element of the list merged.append(content) return merged diff --git a/libs/core/langchain_core/output_parsers/json.py b/libs/core/langchain_core/output_parsers/json.py index 54577037759..0d1513e6d86 100644 --- a/libs/core/langchain_core/output_parsers/json.py +++ b/libs/core/langchain_core/output_parsers/json.py @@ -46,11 +46,13 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]): def _diff(self, prev: Optional[Any], next: Any) -> Any: return jsonpatch.make_patch(prev, next).patch - def _get_schema(self, pydantic_object: type[TBaseModel]) -> dict[str, Any]: + @staticmethod + def _get_schema(pydantic_object: type[TBaseModel]) -> dict[str, Any]: if issubclass(pydantic_object, pydantic.BaseModel): return pydantic_object.model_json_schema() return pydantic_object.schema() + @override def parse_result(self, result: list[Generation], *, partial: bool = False) -> Any: """Parse the result of an LLM call to a JSON object. diff --git a/libs/core/langchain_core/output_parsers/list.py b/libs/core/langchain_core/output_parsers/list.py index cc8ca4238cb..b0d1ba4bfd4 100644 --- a/libs/core/langchain_core/output_parsers/list.py +++ b/libs/core/langchain_core/output_parsers/list.py @@ -155,6 +155,7 @@ class CommaSeparatedListOutputParser(ListOutputParser): """ return ["langchain", "output_parsers", "list"] + @override def get_format_instructions(self) -> str: """Return the format instructions for the comma-separated list output.""" return ( @@ -162,6 +163,7 @@ class CommaSeparatedListOutputParser(ListOutputParser): "eg: `foo, bar, baz` or `foo,bar,baz`" ) + @override def parse(self, text: str) -> list[str]: """Parse the output of an LLM call. @@ -224,6 +226,7 @@ class MarkdownListOutputParser(ListOutputParser): pattern: str = r"^\s*[-*]\s([^\n]+)$" """The pattern to match a Markdown list item.""" + @override def get_format_instructions(self) -> str: """Return the format instructions for the Markdown list output.""" return "Your response should be a markdown list, eg: `- foo\n- bar\n- baz`" diff --git a/libs/core/langchain_core/output_parsers/string.py b/libs/core/langchain_core/output_parsers/string.py index c2194e8bddf..35c9aab89f4 100644 --- a/libs/core/langchain_core/output_parsers/string.py +++ b/libs/core/langchain_core/output_parsers/string.py @@ -1,5 +1,7 @@ """String output parser.""" +from typing_extensions import override + from langchain_core.output_parsers.transform import BaseTransformOutputParser @@ -29,6 +31,7 @@ class StrOutputParser(BaseTransformOutputParser[str]): """Return the output parser type for serialization.""" return "default" + @override def parse(self, text: str) -> str: """Returns the input text with no changes.""" return text diff --git a/libs/core/langchain_core/prompts/base.py b/libs/core/langchain_core/prompts/base.py index 6581c56902c..370380d444b 100644 --- a/libs/core/langchain_core/prompts/base.py +++ b/libs/core/langchain_core/prompts/base.py @@ -210,7 +210,7 @@ class BasePromptTemplate( if self.metadata: config["metadata"] = {**config["metadata"], **self.metadata} if self.tags: - config["tags"] = config["tags"] + self.tags + config["tags"] += self.tags return self._call_with_config( self._format_prompt_with_error_handling, input, diff --git a/libs/core/langchain_core/prompts/string.py b/libs/core/langchain_core/prompts/string.py index 12357bf3a27..b6f1cdae28f 100644 --- a/libs/core/langchain_core/prompts/string.py +++ b/libs/core/langchain_core/prompts/string.py @@ -166,7 +166,7 @@ def mustache_schema( prefix = section_stack.pop() elif type_ in {"section", "inverted section"}: section_stack.append(prefix) - prefix = prefix + tuple(key.split(".")) + prefix += tuple(key.split(".")) fields[prefix] = False elif type_ in {"variable", "no escape"}: fields[prefix + tuple(key.split("."))] = True diff --git a/libs/core/langchain_core/runnables/graph_mermaid.py b/libs/core/langchain_core/runnables/graph_mermaid.py index a7655072d69..17ebc55a518 100644 --- a/libs/core/langchain_core/runnables/graph_mermaid.py +++ b/libs/core/langchain_core/runnables/graph_mermaid.py @@ -155,7 +155,7 @@ def draw_mermaid( nonlocal mermaid_graph self_loop = len(edges) == 1 and edges[0].source == edges[0].target if prefix and not self_loop: - subgraph = prefix.split(":")[-1] + subgraph = prefix.rsplit(":", maxsplit=1)[-1] if subgraph in seen_subgraphs: msg = ( f"Found duplicate subgraph '{subgraph}' -- this likely means that " @@ -214,7 +214,7 @@ def draw_mermaid( # Add remaining subgraphs with edges for prefix, edges_ in edge_groups.items(): - if ":" in prefix or prefix == "": + if not prefix or ":" in prefix: continue add_subgraph(edges_, prefix) seen_subgraphs.add(prefix) diff --git a/libs/core/langchain_core/tracers/core.py b/libs/core/langchain_core/tracers/core.py index 54261a2c224..9e680172a8f 100644 --- a/libs/core/langchain_core/tracers/core.py +++ b/libs/core/langchain_core/tracers/core.py @@ -82,7 +82,7 @@ class _TracerCore(ABC): """Map of run ID to (trace_id, dotted_order). Cleared when tracer GCed.""" @abstractmethod - def _persist_run(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: + def _persist_run(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: """Persist a run.""" @staticmethod @@ -108,7 +108,7 @@ class _TracerCore(ABC): except: # noqa: E722 return msg - def _start_trace(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # type: ignore[return] + def _start_trace(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # type: ignore[return] current_dotted_order = run.start_time.strftime("%Y%m%dT%H%M%S%fZ") + str(run.id) if run.parent_run_id: if parent := self.order_map.get(run.parent_run_id): @@ -538,7 +538,7 @@ class _TracerCore(ABC): """Return self copied.""" return self - def _end_trace(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _end_trace(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """End a trace for a run. Args: @@ -546,7 +546,7 @@ class _TracerCore(ABC): """ return None - def _on_run_create(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_run_create(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process a run upon creation. Args: @@ -554,7 +554,7 @@ class _TracerCore(ABC): """ return None - def _on_run_update(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_run_update(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process a run upon update. Args: @@ -562,7 +562,7 @@ class _TracerCore(ABC): """ return None - def _on_llm_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_llm_start(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the LLM Run upon start. Args: @@ -575,7 +575,7 @@ class _TracerCore(ABC): run: Run, # noqa: ARG002 token: str, # noqa: ARG002 chunk: Optional[Union[GenerationChunk, ChatGenerationChunk]], # noqa: ARG002 - ) -> Union[None, Coroutine[Any, Any, None]]: + ) -> Union[Coroutine[Any, Any, None], None]: """Process new LLM token. Args: @@ -585,7 +585,7 @@ class _TracerCore(ABC): """ return None - def _on_llm_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_llm_end(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the LLM Run. Args: @@ -593,7 +593,7 @@ class _TracerCore(ABC): """ return None - def _on_llm_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_llm_error(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the LLM Run upon error. Args: @@ -601,7 +601,7 @@ class _TracerCore(ABC): """ return None - def _on_chain_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_chain_start(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Chain Run upon start. Args: @@ -609,7 +609,7 @@ class _TracerCore(ABC): """ return None - def _on_chain_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_chain_end(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Chain Run. Args: @@ -617,7 +617,7 @@ class _TracerCore(ABC): """ return None - def _on_chain_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_chain_error(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Chain Run upon error. Args: @@ -625,7 +625,7 @@ class _TracerCore(ABC): """ return None - def _on_tool_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_tool_start(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Tool Run upon start. Args: @@ -633,7 +633,7 @@ class _TracerCore(ABC): """ return None - def _on_tool_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_tool_end(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Tool Run. Args: @@ -641,7 +641,7 @@ class _TracerCore(ABC): """ return None - def _on_tool_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_tool_error(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Tool Run upon error. Args: @@ -649,7 +649,7 @@ class _TracerCore(ABC): """ return None - def _on_chat_model_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_chat_model_start(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Chat Model Run upon start. Args: @@ -657,7 +657,7 @@ class _TracerCore(ABC): """ return None - def _on_retriever_start(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_retriever_start(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Retriever Run upon start. Args: @@ -665,7 +665,7 @@ class _TracerCore(ABC): """ return None - def _on_retriever_end(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_retriever_end(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Retriever Run. Args: @@ -673,7 +673,7 @@ class _TracerCore(ABC): """ return None - def _on_retriever_error(self, run: Run) -> Union[None, Coroutine[Any, Any, None]]: # noqa: ARG002 + def _on_retriever_error(self, run: Run) -> Union[Coroutine[Any, Any, None], None]: # noqa: ARG002 """Process the Retriever Run upon error. Args: diff --git a/libs/core/langchain_core/utils/aiter.py b/libs/core/langchain_core/utils/aiter.py index 7a0477c658e..e319fb08911 100644 --- a/libs/core/langchain_core/utils/aiter.py +++ b/libs/core/langchain_core/utils/aiter.py @@ -37,7 +37,7 @@ _no_default = object() # before 3.10, the builtin anext() was not available def py_anext( iterator: AsyncIterator[T], default: Union[T, Any] = _no_default -) -> Awaitable[Union[T, None, Any]]: +) -> Awaitable[Union[T, Any, None]]: """Pure-Python implementation of anext() for testing purposes. Closely matches the builtin anext() C implementation. diff --git a/libs/core/langchain_core/utils/mustache.py b/libs/core/langchain_core/utils/mustache.py index fd2ae359176..9c8a93cacc8 100644 --- a/libs/core/langchain_core/utils/mustache.py +++ b/libs/core/langchain_core/utils/mustache.py @@ -82,7 +82,7 @@ def l_sa_check( """ # If there is a newline, or the previous tag was a standalone if literal.find("\n") != -1 or is_standalone: - padding = literal.split("\n")[-1] + padding = literal.rsplit("\n", maxsplit=1)[-1] # If all the characters since the last newline are spaces # Then the next tag could be a standalone diff --git a/libs/core/langchain_core/utils/utils.py b/libs/core/langchain_core/utils/utils.py index 1a41b63dc28..122f1c0af2d 100644 --- a/libs/core/langchain_core/utils/utils.py +++ b/libs/core/langchain_core/utils/utils.py @@ -134,7 +134,7 @@ def guard_import( try: module = importlib.import_module(module_name, package) except (ImportError, ModuleNotFoundError) as e: - pip_name = pip_name or module_name.split(".")[0].replace("_", "-") + pip_name = pip_name or module_name.split(".", maxsplit=1)[0].replace("_", "-") msg = ( f"Could not import {module_name} python package. " f"Please install it with `pip install {pip_name}`." diff --git a/libs/core/pyproject.toml b/libs/core/pyproject.toml index 1ea42cee123..8f48ba5d5e8 100644 --- a/libs/core/pyproject.toml +++ b/libs/core/pyproject.toml @@ -83,27 +83,39 @@ docstring-code-format = true [tool.ruff.lint] select = [ "ALL",] ignore = [ - "C90", # McCabe complexity - "COM812", # Messes with the formatter - "FA100", # Can't activate since we exclude UP007 for now - "FIX002", # Line contains TODO - "ISC001", # Messes with the formatter + "C90", # McCabe complexity + "COM812", # Messes with the formatter + "CPY", # No copyright + "FIX002", # Line contains TODO + "ISC001", # Messes with the formatter + "C90", # McCabe complexity + "COM812", # Messes with the formatter + "CPY", # No copyright + "FIX002", # Line contains TODO + "ISC001", # Messes with the formatter "PERF203", # Rarely useful - "PLC0414", # Enable re-export - "PLR09", # Too many something (arg, statements, etc) - "RUF012", # Doesn't play well with Pydantic - "TC001", # Doesn't play well with Pydantic - "TC002", # Doesn't play well with Pydantic - "TC003", # Doesn't play well with Pydantic - "TD002", # Missing author in TODO - "TD003", # Missing issue link in TODO + "PLR09", # Too many something (arg, statements, etc) + "RUF012", # Doesn't play well with Pydantic + "TC001", # Doesn't play well with Pydantic + "TC002", # Doesn't play well with Pydantic + "TC003", # Doesn't play well with Pydantic + "TD002", # Missing author in TODO + "TD003", # Missing issue link in TODO + "PLR09", # Too many something (arg, statements, etc) + "RUF012", # Doesn't play well with Pydantic + "TC001", # Doesn't play well with Pydantic + "TC002", # Doesn't play well with Pydantic + "TC003", # Doesn't play well with Pydantic + "TD002", # Missing author in TODO + "TD003", # Missing issue link in TODO # TODO rules - "ANN401", - "BLE", - "ERA", - "PLC0415", - "PLR2004", + "ANN401", # No Any types + "BLE", # Blind exceptions + "DOC", # Docstrings (preview) + "ERA", # No commented-out code + "PLC0415", # Imports outside top level + "PLR2004", # Comparison to magic number ] unfixable = ["PLW1510",] diff --git a/libs/core/tests/unit_tests/document_loaders/test_base.py b/libs/core/tests/unit_tests/document_loaders/test_base.py index 87ab70e9e09..c7d5811e188 100644 --- a/libs/core/tests/unit_tests/document_loaders/test_base.py +++ b/libs/core/tests/unit_tests/document_loaders/test_base.py @@ -35,6 +35,7 @@ def test_base_blob_parser() -> None: def test_default_lazy_load() -> None: class FakeLoader(BaseLoader): + @override def load(self) -> list[Document]: return [ Document(page_content="foo"), @@ -57,6 +58,7 @@ def test_lazy_load_not_implemented() -> None: async def test_default_aload() -> None: class FakeLoader(BaseLoader): + @override def lazy_load(self) -> Iterator[Document]: yield from [ Document(page_content="foo"), diff --git a/libs/core/tests/unit_tests/example_selectors/test_base.py b/libs/core/tests/unit_tests/example_selectors/test_base.py index 54793627987..c49e7745f07 100644 --- a/libs/core/tests/unit_tests/example_selectors/test_base.py +++ b/libs/core/tests/unit_tests/example_selectors/test_base.py @@ -1,5 +1,7 @@ from typing import Optional +from typing_extensions import override + from langchain_core.example_selectors import BaseExampleSelector @@ -10,6 +12,7 @@ class DummyExampleSelector(BaseExampleSelector): def add_example(self, example: dict[str, str]) -> None: self.example = example + @override def select_examples(self, input_variables: dict[str, str]) -> list[dict]: return [input_variables] diff --git a/libs/core/tests/unit_tests/indexing/test_in_memory_indexer.py b/libs/core/tests/unit_tests/indexing/test_in_memory_indexer.py index b16823a7626..decf9f67ac7 100644 --- a/libs/core/tests/unit_tests/indexing/test_in_memory_indexer.py +++ b/libs/core/tests/unit_tests/indexing/test_in_memory_indexer.py @@ -7,6 +7,7 @@ from langchain_tests.integration_tests.indexer import ( AsyncDocumentIndexTestSuite, DocumentIndexerTestSuite, ) +from typing_extensions import override from langchain_core.documents import Document from langchain_core.indexing.base import DocumentIndex @@ -17,6 +18,7 @@ from langchain_core.indexing.in_memory import ( class TestDocumentIndexerTestSuite(DocumentIndexerTestSuite): @pytest.fixture + @override def index(self) -> Generator[DocumentIndex, None, None]: yield InMemoryDocumentIndex() # noqa: PT022 @@ -24,6 +26,7 @@ class TestDocumentIndexerTestSuite(DocumentIndexerTestSuite): class TestAsyncDocumentIndexerTestSuite(AsyncDocumentIndexTestSuite): # Something funky is going on with mypy and async pytest fixture @pytest.fixture + @override async def index(self) -> AsyncGenerator[DocumentIndex, None]: yield InMemoryDocumentIndex() # noqa: PT022 diff --git a/libs/core/tests/unit_tests/indexing/test_indexing.py b/libs/core/tests/unit_tests/indexing/test_indexing.py index cc579d4d032..a3e88e7535b 100644 --- a/libs/core/tests/unit_tests/indexing/test_indexing.py +++ b/libs/core/tests/unit_tests/indexing/test_indexing.py @@ -501,15 +501,14 @@ def test_incremental_fails_with_bad_source_ids( with pytest.raises( ValueError, match="Source id key is required when cleanup mode is " - "incremental or scoped_full.", + "incremental or scoped_full", ): # Should raise an error because no source id function was specified index(loader, record_manager, vector_store, cleanup="incremental") with pytest.raises( ValueError, - match="Source ids are required when cleanup mode " - "is incremental or scoped_full.", + match="Source ids are required when cleanup mode is incremental or scoped_full", ): # Should raise an error because no source id function was specified index( @@ -545,7 +544,7 @@ async def test_aincremental_fails_with_bad_source_ids( with pytest.raises( ValueError, match="Source id key is required when cleanup mode " - "is incremental or scoped_full.", + "is incremental or scoped_full", ): # Should raise an error because no source id function was specified await aindex( @@ -557,8 +556,7 @@ async def test_aincremental_fails_with_bad_source_ids( with pytest.raises( ValueError, - match="Source ids are required when cleanup mode " - "is incremental or scoped_full.", + match="Source ids are required when cleanup mode is incremental or scoped_full", ): # Should raise an error because no source id function was specified await aindex( @@ -838,15 +836,14 @@ def test_scoped_full_fails_with_bad_source_ids( with pytest.raises( ValueError, match="Source id key is required when cleanup mode " - "is incremental or scoped_full.", + "is incremental or scoped_full", ): # Should raise an error because no source id function was specified index(loader, record_manager, vector_store, cleanup="scoped_full") with pytest.raises( ValueError, - match="Source ids are required when cleanup mode " - "is incremental or scoped_full.", + match="Source ids are required when cleanup mode is incremental or scoped_full", ): # Should raise an error because no source id function was specified index( @@ -882,15 +879,14 @@ async def test_ascoped_full_fails_with_bad_source_ids( with pytest.raises( ValueError, match="Source id key is required when cleanup mode " - "is incremental or scoped_full.", + "is incremental or scoped_full", ): # Should raise an error because no source id function was specified await aindex(loader, arecord_manager, vector_store, cleanup="scoped_full") with pytest.raises( ValueError, - match="Source ids are required when cleanup mode " - "is incremental or scoped_full.", + match="Source ids are required when cleanup mode is incremental or scoped_full", ): # Should raise an error because no source id function was specified await aindex( diff --git a/libs/core/tests/unit_tests/prompts/test_chat.py b/libs/core/tests/unit_tests/prompts/test_chat.py index f873deb0877..1b1fee580f4 100644 --- a/libs/core/tests/unit_tests/prompts/test_chat.py +++ b/libs/core/tests/unit_tests/prompts/test_chat.py @@ -173,7 +173,7 @@ def test_create_system_message_prompt_list_template_partial_variables_not_null() """ with pytest.raises( - ValueError, match="Partial variables are not supported for list of templates." + ValueError, match="Partial variables are not supported for list of templates" ): _ = SystemMessagePromptTemplate.from_template( template=[graph_creator_content1, graph_creator_content2], @@ -568,7 +568,7 @@ def test_chat_prompt_template_append_and_extend() -> None: def test_convert_to_message_is_strict() -> None: """Verify that _convert_to_message is strict.""" - with pytest.raises(ValueError, match="Unexpected message type: meow."): + with pytest.raises(ValueError, match="Unexpected message type: meow"): # meow does not correspond to a valid message type. # this test is here to ensure that functionality to interpret `meow` # as a role is NOT added. @@ -758,7 +758,7 @@ async def test_chat_tmpl_from_messages_multipart_image() -> None: async def test_chat_tmpl_from_messages_multipart_formatting_with_path() -> None: """Verify that we cannot pass `path` for an image as a variable.""" - in_mem = "base64mem" + in_mem_ = "base64mem" template = ChatPromptTemplate.from_messages( [ @@ -781,23 +781,27 @@ async def test_chat_tmpl_from_messages_multipart_formatting_with_path() -> None: ) with pytest.raises( ValueError, - match="Loading images from 'path' has been removed " - "as of 0.3.15 for security reasons.", + match=re.escape( + "Loading images from 'path' has been removed as of 0.3.15 " + "for security reasons." + ), ): template.format_messages( name="R2D2", - in_mem=in_mem, + in_mem=in_mem_, file_path="some/path", ) with pytest.raises( ValueError, - match="Loading images from 'path' has been removed " - "as of 0.3.15 for security reasons.", + match=re.escape( + "Loading images from 'path' has been removed as of 0.3.15 " + "for security reasons." + ), ): await template.aformat_messages( name="R2D2", - in_mem=in_mem, + in_mem=in_mem_, file_path="some/path", ) @@ -900,7 +904,7 @@ def test_chat_prompt_message_dict() -> None: with pytest.raises(ValueError, match="Invalid template: False"): ChatPromptTemplate([{"role": "system", "content": False}]) - with pytest.raises(ValueError, match="Unexpected message type: foo."): + with pytest.raises(ValueError, match="Unexpected message type: foo"): ChatPromptTemplate([{"role": "foo", "content": "foo"}]) diff --git a/libs/core/tests/unit_tests/prompts/test_loading.py b/libs/core/tests/unit_tests/prompts/test_loading.py index 76d75314775..3e230c54bbb 100644 --- a/libs/core/tests/unit_tests/prompts/test_loading.py +++ b/libs/core/tests/unit_tests/prompts/test_loading.py @@ -49,14 +49,14 @@ def test_loading_from_json() -> None: def test_loading_jinja_from_json() -> None: """Test that loading jinja2 format prompts from JSON raises ValueError.""" prompt_path = EXAMPLE_DIR / "jinja_injection_prompt.json" - with pytest.raises(ValueError, match=".*can lead to arbitrary code execution.*"): + with pytest.raises(ValueError, match=r".*can lead to arbitrary code execution.*"): load_prompt(prompt_path) def test_loading_jinja_from_yaml() -> None: """Test that loading jinja2 format prompts from YAML raises ValueError.""" prompt_path = EXAMPLE_DIR / "jinja_injection_prompt.yaml" - with pytest.raises(ValueError, match=".*can lead to arbitrary code execution.*"): + with pytest.raises(ValueError, match=r".*can lead to arbitrary code execution.*"): load_prompt(prompt_path) diff --git a/libs/core/tests/unit_tests/prompts/test_structured.py b/libs/core/tests/unit_tests/prompts/test_structured.py index 4f5cbc9ab79..9758f1d1d1e 100644 --- a/libs/core/tests/unit_tests/prompts/test_structured.py +++ b/libs/core/tests/unit_tests/prompts/test_structured.py @@ -4,6 +4,7 @@ from typing import Any, Union, cast import pytest from pydantic import BaseModel +from typing_extensions import override from langchain_core.language_models import FakeListChatModel from langchain_core.load.dump import dumps @@ -27,6 +28,7 @@ def _fake_runnable( class FakeStructuredChatModel(FakeListChatModel): """Fake ChatModel for testing purposes.""" + @override def with_structured_output( self, schema: Union[dict, type[BaseModel]], **kwargs: Any ) -> Runnable: diff --git a/libs/core/tests/unit_tests/runnables/test_context.py b/libs/core/tests/unit_tests/runnables/test_context.py index b638ac78f57..073b972fe0f 100644 --- a/libs/core/tests/unit_tests/runnables/test_context.py +++ b/libs/core/tests/unit_tests/runnables/test_context.py @@ -368,7 +368,7 @@ def test_runnable_context_seq_key_order() -> None: with pytest.raises( ValueError, - match="Context setter for key foo must be defined after all getters.", + match="Context setter for key foo must be defined after all getters", ): seq.invoke("foo") diff --git a/libs/core/tests/unit_tests/runnables/test_runnable.py b/libs/core/tests/unit_tests/runnables/test_runnable.py index 5c33c5a99c4..530ce185743 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable.py @@ -3799,12 +3799,14 @@ class FakeSplitIntoListParser(BaseOutputParser[list[str]]): """Return whether or not the class is serializable.""" return True + @override def get_format_instructions(self) -> str: return ( "Your response should be a list of comma separated values, " "eg: `foo, bar, baz`" ) + @override def parse(self, text: str) -> list[str]: """Parse the output of an LLM call.""" return text.strip().split(", ") diff --git a/libs/core/tests/unit_tests/stores/test_in_memory.py b/libs/core/tests/unit_tests/stores/test_in_memory.py index cc8ec684fbe..7a0036b5787 100644 --- a/libs/core/tests/unit_tests/stores/test_in_memory.py +++ b/libs/core/tests/unit_tests/stores/test_in_memory.py @@ -3,6 +3,7 @@ from langchain_tests.integration_tests.base_store import ( BaseStoreAsyncTests, BaseStoreSyncTests, ) +from typing_extensions import override from langchain_core.stores import InMemoryStore @@ -10,20 +11,24 @@ from langchain_core.stores import InMemoryStore # Check against standard tests class TestSyncInMemoryStore(BaseStoreSyncTests): @pytest.fixture + @override def kv_store(self) -> InMemoryStore: return InMemoryStore() @pytest.fixture + @override def three_values(self) -> tuple[str, str, str]: return "value1", "value2", "value3" class TestAsyncInMemoryStore(BaseStoreAsyncTests): @pytest.fixture + @override async def kv_store(self) -> InMemoryStore: return InMemoryStore() @pytest.fixture + @override def three_values(self) -> tuple[str, str, str]: return "value1", "value2", "value3" diff --git a/libs/core/tests/unit_tests/test_messages.py b/libs/core/tests/unit_tests/test_messages.py index b1df4955232..9f0f43474e9 100644 --- a/libs/core/tests/unit_tests/test_messages.py +++ b/libs/core/tests/unit_tests/test_messages.py @@ -202,7 +202,7 @@ def test_chat_message_chunks() -> None: ) with pytest.raises( - ValueError, match="Cannot concatenate ChatMessageChunks with different roles." + ValueError, match="Cannot concatenate ChatMessageChunks with different roles" ): ChatMessageChunk(role="User", content="I am") + ChatMessageChunk( role="Assistant", content=" indeed." @@ -311,7 +311,7 @@ def test_function_message_chunks() -> None: with pytest.raises( ValueError, - match="Cannot concatenate FunctionMessageChunks with different names.", + match="Cannot concatenate FunctionMessageChunks with different names", ): FunctionMessageChunk(name="hello", content="I am") + FunctionMessageChunk( name="bye", content=" indeed." @@ -327,7 +327,7 @@ def test_ai_message_chunks() -> None: with pytest.raises( ValueError, - match="Cannot concatenate AIMessageChunks with different example values.", + match="Cannot concatenate AIMessageChunks with different example values", ): AIMessageChunk(example=True, content="I am") + AIMessageChunk( example=False, content=" indeed." @@ -339,7 +339,7 @@ class TestGetBufferString: _AI_MSG = AIMessage(content="ai") def test_empty_input(self) -> None: - assert get_buffer_string([]) == "" + assert not get_buffer_string([]) def test_valid_single_message(self) -> None: expected_output = "Human: human" @@ -1052,7 +1052,7 @@ def test_message_text() -> None: # content dict types: [text], [not text], [no type] assert HumanMessage(content="foo").text() == "foo" - assert AIMessage(content=[]).text() == "" + assert not AIMessage(content=[]).text() assert AIMessage(content=["foo", "bar"]).text() == "foobar" assert ( AIMessage( @@ -1092,14 +1092,11 @@ def test_message_text() -> None: assert ( AIMessage(content=[{"text": "hi there"}, "hi"]).text() == "hi" ) # missing type: text - assert AIMessage(content=[{"type": "nottext", "text": "hi"}]).text() == "" - assert AIMessage(content=[]).text() == "" - assert ( - AIMessage( - content="", tool_calls=[create_tool_call(name="a", args={"b": 1}, id=None)] - ).text() - == "" - ) + assert not AIMessage(content=[{"type": "nottext", "text": "hi"}]).text() + assert not AIMessage(content=[]).text() + assert not AIMessage( + content="", tool_calls=[create_tool_call(name="a", args={"b": 1}, id=None)] + ).text() def test_is_data_content_block() -> None: diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index 72c6a5a387c..63107361224 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -24,7 +24,7 @@ import pytest from pydantic import BaseModel, Field, ValidationError from pydantic.v1 import BaseModel as BaseModelV1 from pydantic.v1 import ValidationError as ValidationErrorV1 -from typing_extensions import TypedDict +from typing_extensions import TypedDict, override from langchain_core import tools from langchain_core.callbacks import ( @@ -119,6 +119,7 @@ class _MockStructuredTool(BaseTool): args_schema: type[BaseModel] = _MockSchema description: str = "A Structured Tool" + @override def _run(self, *, arg1: int, arg2: bool, arg3: Optional[dict] = None) -> str: return f"{arg1} {arg2} {arg3}" @@ -146,6 +147,7 @@ def test_misannotated_base_tool_raises_error() -> None: args_schema: BaseModel = _MockSchema # type: ignore[assignment] description: str = "A Structured Tool" + @override def _run( self, *, arg1: int, arg2: bool, arg3: Optional[dict] = None ) -> str: @@ -165,6 +167,7 @@ def test_forward_ref_annotated_base_tool_accepted() -> None: args_schema: "type[BaseModel]" = _MockSchema description: str = "A Structured Tool" + @override def _run(self, *, arg1: int, arg2: bool, arg3: Optional[dict] = None) -> str: return f"{arg1} {arg2} {arg3}" @@ -182,6 +185,7 @@ def test_subclass_annotated_base_tool_accepted() -> None: args_schema: type[_MockSchema] = _MockSchema description: str = "A Structured Tool" + @override def _run(self, *, arg1: int, arg2: bool, arg3: Optional[dict] = None) -> str: return f"{arg1} {arg2} {arg3}" @@ -237,6 +241,7 @@ def test_args_kwargs_filtered() -> None: name: str = "single_arg_tool" description: str = "A single arged tool with kwargs" + @override def _run( self, some_arg: str, @@ -260,6 +265,7 @@ def test_args_kwargs_filtered() -> None: name: str = "single_arg_tool" description: str = "A single arged tool with kwargs" + @override def _run( self, *args: Any, @@ -396,9 +402,11 @@ def test_base_tool_inheritance_base_schema() -> None: name: str = "simple_tool" description: str = "A Simple Tool" + @override def _run(self, tool_input: str) -> str: return f"{tool_input}" + @override async def _arun(self, tool_input: str) -> str: raise NotImplementedError @@ -705,7 +713,7 @@ def test_missing_docstring() -> None: class MyTool(BaseModel): foo: str - assert MyTool.description == "" # type: ignore[attr-defined] + assert not MyTool.description # type: ignore[attr-defined] def test_create_tool_positional_args() -> None: @@ -909,9 +917,11 @@ def test_validation_error_handling_non_validation_error( ) -> Union[str, dict[str, Any]]: raise NotImplementedError + @override def _run(self) -> str: return "dummy" + @override async def _arun(self) -> str: return "dummy" @@ -975,9 +985,11 @@ async def test_async_validation_error_handling_non_validation_error( ) -> Union[str, dict[str, Any]]: raise NotImplementedError + @override def _run(self) -> str: return "dummy" + @override async def _arun(self) -> str: return "dummy" @@ -1096,11 +1108,13 @@ class FooBase(BaseTool): name: str = "Foo" description: str = "Foo" + @override def _run(self, bar: Any, bar_config: RunnableConfig, **kwargs: Any) -> Any: return assert_bar(bar, bar_config) class AFooBase(FooBase): + @override async def _arun(self, bar: Any, bar_config: RunnableConfig, **kwargs: Any) -> Any: return assert_bar(bar, bar_config) @@ -1121,6 +1135,7 @@ def test_tool_pass_config(tool: BaseTool) -> None: class FooBaseNonPickleable(FooBase): + @override def _run(self, bar: Any, bar_config: RunnableConfig, **kwargs: Any) -> Any: return True @@ -1332,7 +1347,7 @@ def test_tool_invalid_docstrings() -> None: return bar for func in {foo3, foo4}: - with pytest.raises(ValueError, match="Found invalid Google-Style docstring."): + with pytest.raises(ValueError, match="Found invalid Google-Style docstring"): _ = tool(func, parse_docstring=True) def foo5(bar: str, baz: int) -> str: # noqa: D417 @@ -1345,7 +1360,7 @@ def test_tool_invalid_docstrings() -> None: return bar with pytest.raises( - ValueError, match="Arg banana in docstring not found in function signature." + ValueError, match="Arg banana in docstring not found in function signature" ): _ = tool(foo5, parse_docstring=True) @@ -1404,10 +1419,11 @@ class _MockStructuredToolWithRawOutput(BaseTool): description: str = "A Structured Tool" response_format: Literal["content_and_artifact"] = "content_and_artifact" + @override def _run( self, arg1: int, - arg2: bool, # noqa: FBT001 + arg2: bool, arg3: Optional[dict] = None, ) -> tuple[str, dict]: return f"{arg1} {arg2}", {"arg1": arg1, "arg2": arg2, "arg3": arg3} @@ -1554,6 +1570,7 @@ class InjectedTool(BaseTool): name: str = "foo" description: str = "foo." + @override def _run(self, x: int, y: Annotated[str, InjectedToolArg]) -> Any: """Foo. @@ -1578,6 +1595,7 @@ class InjectedToolWithSchema(BaseTool): description: str = "foo." args_schema: type[BaseModel] = fooSchema + @override def _run(self, x: int, y: str) -> Any: return y @@ -1743,6 +1761,7 @@ def test_tool_inherited_injected_arg() -> None: description: str = "foo." args_schema: type[BaseModel] = FooSchema + @override def _run(self, x: int, y: str) -> Any: return y @@ -1854,6 +1873,7 @@ def test_args_schema_as_pydantic(pydantic_model: Any) -> None: class SomeTool(BaseTool): args_schema: type[pydantic_model] = pydantic_model + @override def _run(self, *args: Any, **kwargs: Any) -> str: return "foo" @@ -1913,6 +1933,7 @@ def test_args_schema_explicitly_typed() -> None: # for pydantic 2! args_schema: type[BaseModel] = Foo + @override def _run(self, *args: Any, **kwargs: Any) -> str: return "foo" @@ -2136,6 +2157,7 @@ def test_tool_annotations_preserved() -> None: def test_create_retriever_tool() -> None: class MyRetriever(BaseRetriever): + @override def _get_relevant_documents( self, query: str, *, run_manager: CallbackManagerForRetrieverRun ) -> list[Document]: @@ -2364,6 +2386,7 @@ def test_tool_mutate_input() -> None: name: str = "MyTool" description: str = "a tool" + @override def _run( self, x: str, diff --git a/libs/core/tests/unit_tests/utils/test_env.py b/libs/core/tests/unit_tests/utils/test_env.py index ea49268cee8..0d52e8534c6 100644 --- a/libs/core/tests/unit_tests/utils/test_env.py +++ b/libs/core/tests/unit_tests/utils/test_env.py @@ -55,7 +55,7 @@ def test_get_from_dict_or_env() -> None: ValueError, match="Did not find not exists, " "please add an environment variable `__SOME_KEY_IN_ENV` which contains it, " - "or pass `not exists` as a named parameter.", + "or pass `not exists` as a named parameter", ): assert ( get_from_dict_or_env( diff --git a/libs/core/tests/unit_tests/utils/test_html.py b/libs/core/tests/unit_tests/utils/test_html.py index a6332e4b606..7d6c00dab69 100644 --- a/libs/core/tests/unit_tests/utils/test_html.py +++ b/libs/core/tests/unit_tests/utils/test_html.py @@ -36,31 +36,31 @@ def test_find_all_links_multiple() -> None: def test_find_all_links_ignore_suffix() -> None: html = 'href="foobar{suffix}"' - for suffix in SUFFIXES_TO_IGNORE: - actual = find_all_links(html.format(suffix=suffix)) + for suffix_ in SUFFIXES_TO_IGNORE: + actual = find_all_links(html.format(suffix=suffix_)) assert actual == [] # Don't ignore if pattern doesn't occur at end of link. html = 'href="foobar{suffix}more"' - for suffix in SUFFIXES_TO_IGNORE: - actual = find_all_links(html.format(suffix=suffix)) - assert actual == [f"foobar{suffix}more"] + for suffix_ in SUFFIXES_TO_IGNORE: + actual = find_all_links(html.format(suffix=suffix_)) + assert actual == [f"foobar{suffix_}more"] def test_find_all_links_ignore_prefix() -> None: html = 'href="{prefix}foobar"' - for prefix in PREFIXES_TO_IGNORE: - actual = find_all_links(html.format(prefix=prefix)) + for prefix_ in PREFIXES_TO_IGNORE: + actual = find_all_links(html.format(prefix=prefix_)) assert actual == [] # Don't ignore if pattern doesn't occur at beginning of link. html = 'href="foobar{prefix}more"' - for prefix in PREFIXES_TO_IGNORE: + for prefix_ in PREFIXES_TO_IGNORE: # Pound signs are split on when not prefixes. - if prefix == "#": + if prefix_ == "#": continue - actual = find_all_links(html.format(prefix=prefix)) - assert actual == [f"foobar{prefix}more"] + actual = find_all_links(html.format(prefix=prefix_)) + assert actual == [f"foobar{prefix_}more"] def test_find_all_links_drop_fragment() -> None: diff --git a/libs/core/tests/unit_tests/utils/test_strings.py b/libs/core/tests/unit_tests/utils/test_strings.py index 2162fb3efe8..85c328a4758 100644 --- a/libs/core/tests/unit_tests/utils/test_strings.py +++ b/libs/core/tests/unit_tests/utils/test_strings.py @@ -24,7 +24,7 @@ def test_sanitize_for_postgres() -> None: assert sanitize_for_postgres(clean_text) == clean_text # Test empty string - assert sanitize_for_postgres("") == "" + assert not sanitize_for_postgres("") # Test with multiple consecutive NUL bytes text_with_multiple_nuls = "Hello\x00\x00\x00world" diff --git a/libs/core/tests/unit_tests/utils/test_usage.py b/libs/core/tests/unit_tests/utils/test_usage.py index 04c89b0537e..1ad3500d6d8 100644 --- a/libs/core/tests/unit_tests/utils/test_usage.py +++ b/libs/core/tests/unit_tests/utils/test_usage.py @@ -30,7 +30,7 @@ def test_dict_int_op_max_depth_exceeded() -> None: left = {"a": {"b": {"c": 1}}} right = {"a": {"b": {"c": 2}}} with pytest.raises( - ValueError, match="max_depth=2 exceeded, unable to combine dicts." + ValueError, match="max_depth=2 exceeded, unable to combine dicts" ): _dict_int_op(left, right, operator.add, max_depth=2) @@ -40,6 +40,6 @@ def test_dict_int_op_invalid_types() -> None: right = {"a": 2, "b": 3} with pytest.raises( ValueError, - match="Only dict and int values are supported.", + match="Only dict and int values are supported", ): _dict_int_op(left, right, operator.add) diff --git a/libs/core/tests/unit_tests/utils/test_utils.py b/libs/core/tests/unit_tests/utils/test_utils.py index c38b951da65..51967b82a19 100644 --- a/libs/core/tests/unit_tests/utils/test_utils.py +++ b/libs/core/tests/unit_tests/utils/test_utils.py @@ -96,7 +96,7 @@ def test_check_package_version( TypeError, match=( "Additional kwargs key a already exists in left dict and value " - "has unsupported type .+tuple.+." + r"has unsupported type .+tuple.+." ), ), ), @@ -136,7 +136,7 @@ def test_merge_dicts( ( {"type": "foo"}, {"type": "bar"}, - pytest.raises(ValueError, match="Unable to merge."), + pytest.raises(ValueError, match="Unable to merge"), ), ], ) From 16420cad71761b3b1f7a69df6523d68abc39b18c Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 19:52:17 +0200 Subject: [PATCH 29/30] chore(core): fix some pydocs to use google-style (#32764) Co-authored-by: Mason Daugherty --- libs/core/langchain_core/indexing/api.py | 91 ++++++++++--------- .../langchain_core/language_models/base.py | 18 ++-- .../language_models/chat_models.py | 18 ++-- .../langchain_core/language_models/llms.py | 18 ++-- libs/core/langchain_core/load/serializable.py | 64 ++++++------- libs/core/langchain_core/messages/utils.py | 41 +++++---- .../core/langchain_core/output_parsers/xml.py | 13 +-- libs/core/langchain_core/prompts/pipeline.py | 15 +-- libs/core/langchain_core/runnables/branch.py | 6 +- .../langchain_core/runnables/configurable.py | 14 +-- libs/core/langchain_core/runnables/graph.py | 46 ++++------ .../langchain_core/runnables/graph_png.py | 27 ++---- libs/core/langchain_core/runnables/history.py | 43 ++++----- libs/core/langchain_core/runnables/router.py | 9 +- libs/core/langchain_core/runnables/utils.py | 72 ++++++--------- libs/core/langchain_core/tools/base.py | 9 +- libs/core/langchain_core/tools/convert.py | 13 +-- .../core/langchain_core/tracers/evaluation.py | 48 +++++----- .../langchain_core/tracers/event_stream.py | 17 ++-- .../langchain_core/tracers/root_listeners.py | 24 +---- .../langchain_core/tracers/run_collector.py | 22 ++--- libs/core/langchain_core/utils/json_schema.py | 4 +- libs/core/langchain_core/vectorstores/base.py | 1 + .../unit_tests/runnables/test_runnable.py | 8 +- 24 files changed, 281 insertions(+), 360 deletions(-) diff --git a/libs/core/langchain_core/indexing/api.py b/libs/core/langchain_core/indexing/api.py index 7e938355fb1..fdf7273bad1 100644 --- a/libs/core/langchain_core/indexing/api.py +++ b/libs/core/langchain_core/indexing/api.py @@ -294,21 +294,21 @@ def index( documents were deleted, which documents should be skipped. For the time being, documents are indexed using their hashes, and users - are not able to specify the uid of the document. + are not able to specify the uid of the document. Important: - * In full mode, the loader should be returning - the entire dataset, and not just a subset of the dataset. - Otherwise, the auto_cleanup will remove documents that it is not - supposed to. - * In incremental mode, if documents associated with a particular - source id appear across different batches, the indexing API - will do some redundant work. This will still result in the - correct end state of the index, but will unfortunately not be - 100% efficient. For example, if a given document is split into 15 - chunks, and we index them using a batch size of 5, we'll have 3 batches - all with the same source id. In general, to avoid doing too much - redundant work select as big a batch size as possible. + * In full mode, the loader should be returning + the entire dataset, and not just a subset of the dataset. + Otherwise, the auto_cleanup will remove documents that it is not + supposed to. + * In incremental mode, if documents associated with a particular + source id appear across different batches, the indexing API + will do some redundant work. This will still result in the + correct end state of the index, but will unfortunately not be + 100% efficient. For example, if a given document is split into 15 + chunks, and we index them using a batch size of 5, we'll have 3 batches + all with the same source id. In general, to avoid doing too much + redundant work select as big a batch size as possible. * The `scoped_full` mode is suitable if determining an appropriate batch size is challenging or if your data loader cannot return the entire dataset at once. This mode keeps track of source IDs in memory, which should be fine @@ -318,23 +318,22 @@ def index( Args: docs_source: Data loader or iterable of documents to index. record_manager: Timestamped set to keep track of which documents were - updated. + updated. vector_store: VectorStore or DocumentIndex to index the documents into. batch_size: Batch size to use when indexing. Default is 100. cleanup: How to handle clean up of documents. Default is None. + - incremental: Cleans up all documents that haven't been updated AND - that are associated with source ids that were seen - during indexing. - Clean up is done continuously during indexing helping - to minimize the probability of users seeing duplicated - content. + that are associated with source ids that were seen during indexing. + Clean up is done continuously during indexing helping to minimize the + probability of users seeing duplicated content. - full: Delete all documents that have not been returned by the loader - during this run of indexing. - Clean up runs after all documents have been indexed. - This means that users may see duplicated content during indexing. + during this run of indexing. + Clean up runs after all documents have been indexed. + This means that users may see duplicated content during indexing. - scoped_full: Similar to Full, but only deletes all documents - that haven't been updated AND that are associated with - source ids that were seen during indexing. + that haven't been updated AND that are associated with + source ids that were seen during indexing. - None: Do not delete any documents. source_id_key: Optional key that helps identify the original source of the document. Default is None. @@ -361,10 +360,9 @@ def index( When changing the key encoder, you must change the index as well to avoid duplicated documents in the cache. upsert_kwargs: Additional keyword arguments to pass to the add_documents - method of the VectorStore or the upsert method of the - DocumentIndex. For example, you can use this to - specify a custom vector_field: - upsert_kwargs={"vector_field": "embedding"} + method of the VectorStore or the upsert method of the DocumentIndex. + For example, you can use this to specify a custom vector_field: + upsert_kwargs={"vector_field": "embedding"} .. versionadded:: 0.3.10 Returns: @@ -662,22 +660,22 @@ async def aindex( Args: docs_source: Data loader or iterable of documents to index. record_manager: Timestamped set to keep track of which documents were - updated. + updated. vector_store: VectorStore or DocumentIndex to index the documents into. batch_size: Batch size to use when indexing. Default is 100. cleanup: How to handle clean up of documents. Default is None. + - incremental: Cleans up all documents that haven't been updated AND - that are associated with source ids that were seen - during indexing. - Clean up is done continuously during indexing helping - to minimize the probability of users seeing duplicated - content. - - full: Delete all documents that haven to been returned by the loader. - Clean up runs after all documents have been indexed. - This means that users may see duplicated content during indexing. + that are associated with source ids that were seen during indexing. + Clean up is done continuously during indexing helping to minimize the + probability of users seeing duplicated content. + - full: Delete all documents that have not been returned by the loader + during this run of indexing. + Clean up runs after all documents have been indexed. + This means that users may see duplicated content during indexing. - scoped_full: Similar to Full, but only deletes all documents - that haven't been updated AND that are associated with - source ids that were seen during indexing. + that haven't been updated AND that are associated with + source ids that were seen during indexing. - None: Do not delete any documents. source_id_key: Optional key that helps identify the original source of the document. Default is None. @@ -686,6 +684,12 @@ async def aindex( force_update: Force update documents even if they are present in the record manager. Useful if you are re-indexing with updated embeddings. Default is False. + key_encoder: Hashing algorithm to use for hashing the document content and + metadata. Default is "sha1". + Other options include "blake2b", "sha256", and "sha512". + + .. versionadded:: 0.3.66 + key_encoder: Hashing algorithm to use for hashing the document. If not provided, a default encoder using SHA-1 will be used. SHA-1 is not collision-resistant, and a motivated attacker @@ -697,11 +701,10 @@ async def aindex( When changing the key encoder, you must change the index as well to avoid duplicated documents in the cache. - upsert_kwargs: Additional keyword arguments to pass to the aadd_documents - method of the VectorStore or the aupsert method of the - DocumentIndex. For example, you can use this to - specify a custom vector_field: - upsert_kwargs={"vector_field": "embedding"} + upsert_kwargs: Additional keyword arguments to pass to the add_documents + method of the VectorStore or the upsert method of the DocumentIndex. + For example, you can use this to specify a custom vector_field: + upsert_kwargs={"vector_field": "embedding"} .. versionadded:: 0.3.10 Returns: diff --git a/libs/core/langchain_core/language_models/base.py b/libs/core/langchain_core/language_models/base.py index 80be6ff7305..46bb954e95b 100644 --- a/libs/core/langchain_core/language_models/base.py +++ b/libs/core/langchain_core/language_models/base.py @@ -186,10 +186,11 @@ class BaseLanguageModel( API. Use this method when you want to: - 1. take advantage of batched calls, - 2. need more output from the model than just the top generated value, - 3. are building chains that are agnostic to the underlying language model - type (e.g., pure text completion models vs chat models). + + 1. Take advantage of batched calls, + 2. Need more output from the model than just the top generated value, + 3. Are building chains that are agnostic to the underlying language model + type (e.g., pure text completion models vs chat models). Args: prompts: List of PromptValues. A PromptValue is an object that can be @@ -222,10 +223,11 @@ class BaseLanguageModel( API. Use this method when you want to: - 1. take advantage of batched calls, - 2. need more output from the model than just the top generated value, - 3. are building chains that are agnostic to the underlying language model - type (e.g., pure text completion models vs chat models). + + 1. Take advantage of batched calls, + 2. Need more output from the model than just the top generated value, + 3. Are building chains that are agnostic to the underlying language model + type (e.g., pure text completion models vs chat models). Args: prompts: List of PromptValues. A PromptValue is an object that can be diff --git a/libs/core/langchain_core/language_models/chat_models.py b/libs/core/langchain_core/language_models/chat_models.py index a07115196bd..1d931689a3d 100644 --- a/libs/core/langchain_core/language_models/chat_models.py +++ b/libs/core/langchain_core/language_models/chat_models.py @@ -767,10 +767,11 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): API. Use this method when you want to: - 1. take advantage of batched calls, - 2. need more output from the model than just the top generated value, - 3. are building chains that are agnostic to the underlying language model - type (e.g., pure text completion models vs chat models). + + 1. Take advantage of batched calls, + 2. Need more output from the model than just the top generated value, + 3. Are building chains that are agnostic to the underlying language model + type (e.g., pure text completion models vs chat models). Args: messages: List of list of messages. @@ -882,10 +883,11 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): API. Use this method when you want to: - 1. take advantage of batched calls, - 2. need more output from the model than just the top generated value, - 3. are building chains that are agnostic to the underlying language model - type (e.g., pure text completion models vs chat models). + + 1. Take advantage of batched calls, + 2. Need more output from the model than just the top generated value, + 3. Are building chains that are agnostic to the underlying language model + type (e.g., pure text completion models vs chat models). Args: messages: List of list of messages. diff --git a/libs/core/langchain_core/language_models/llms.py b/libs/core/langchain_core/language_models/llms.py index c274e02310d..9516b115d81 100644 --- a/libs/core/langchain_core/language_models/llms.py +++ b/libs/core/langchain_core/language_models/llms.py @@ -853,10 +853,11 @@ class BaseLLM(BaseLanguageModel[str], ABC): API. Use this method when you want to: - 1. take advantage of batched calls, - 2. need more output from the model than just the top generated value, - 3. are building chains that are agnostic to the underlying language model - type (e.g., pure text completion models vs chat models). + + 1. Take advantage of batched calls, + 2. Need more output from the model than just the top generated value, + 3. Are building chains that are agnostic to the underlying language model + type (e.g., pure text completion models vs chat models). Args: prompts: List of string prompts. @@ -1118,10 +1119,11 @@ class BaseLLM(BaseLanguageModel[str], ABC): API. Use this method when you want to: - 1. take advantage of batched calls, - 2. need more output from the model than just the top generated value, - 3. are building chains that are agnostic to the underlying language model - type (e.g., pure text completion models vs chat models). + + 1. Take advantage of batched calls, + 2. Need more output from the model than just the top generated value, + 3. Are building chains that are agnostic to the underlying language model + type (e.g., pure text completion models vs chat models). Args: prompts: List of string prompts. diff --git a/libs/core/langchain_core/load/serializable.py b/libs/core/langchain_core/load/serializable.py index b9d612be45c..d1523bfed53 100644 --- a/libs/core/langchain_core/load/serializable.py +++ b/libs/core/langchain_core/load/serializable.py @@ -20,53 +20,41 @@ logger = logging.getLogger(__name__) class BaseSerialized(TypedDict): - """Base class for serialized objects. - - Parameters: - lc: The version of the serialization format. - id: The unique identifier of the object. - name: The name of the object. Optional. - graph: The graph of the object. Optional. - """ + """Base class for serialized objects.""" lc: int + """The version of the serialization format.""" id: list[str] + """The unique identifier of the object.""" name: NotRequired[str] + """The name of the object. Optional.""" graph: NotRequired[dict[str, Any]] + """The graph of the object. Optional.""" class SerializedConstructor(BaseSerialized): - """Serialized constructor. - - Parameters: - type: The type of the object. Must be "constructor". - kwargs: The constructor arguments. - """ + """Serialized constructor.""" type: Literal["constructor"] + """The type of the object. Must be ``'constructor'``.""" kwargs: dict[str, Any] + """The constructor arguments.""" class SerializedSecret(BaseSerialized): - """Serialized secret. - - Parameters: - type: The type of the object. Must be "secret". - """ + """Serialized secret.""" type: Literal["secret"] + """The type of the object. Must be ``'secret'``.""" class SerializedNotImplemented(BaseSerialized): - """Serialized not implemented. - - Parameters: - type: The type of the object. Must be "not_implemented". - repr: The representation of the object. Optional. - """ + """Serialized not implemented.""" type: Literal["not_implemented"] + """The type of the object. Must be ``'not_implemented'``.""" repr: Optional[str] + """The representation of the object. Optional.""" def try_neq_default(value: Any, key: str, model: BaseModel) -> bool: @@ -106,19 +94,19 @@ class Serializable(BaseModel, ABC): It relies on the following methods and properties: - - `is_lc_serializable`: Is this class serializable? - By design, even if a class inherits from Serializable, it is not serializable by - default. This is to prevent accidental serialization of objects that should not - be serialized. - - `get_lc_namespace`: Get the namespace of the langchain object. - During deserialization, this namespace is used to identify - the correct class to instantiate. - Please see the `Reviver` class in `langchain_core.load.load` for more details. - During deserialization an additional mapping is handle - classes that have moved or been renamed across package versions. - - `lc_secrets`: A map of constructor argument names to secret ids. - - `lc_attributes`: List of additional attribute names that should be included - as part of the serialized representation. + - ``is_lc_serializable``: Is this class serializable? + By design, even if a class inherits from Serializable, it is not serializable by + default. This is to prevent accidental serialization of objects that should not + be serialized. + - ``get_lc_namespace``: Get the namespace of the langchain object. + During deserialization, this namespace is used to identify + the correct class to instantiate. + Please see the ``Reviver`` class in ``langchain_core.load.load`` for more details. + During deserialization an additional mapping is handle + classes that have moved or been renamed across package versions. + - ``lc_secrets``: A map of constructor argument names to secret ids. + - ``lc_attributes``: List of additional attribute names that should be included + as part of the serialized representation. """ # Remove default BaseModel init docstring. diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index c63f5b1c421..65723ddc3a9 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -425,8 +425,8 @@ def filter_messages( exclude_tool_calls: Tool call IDs to exclude. Default is None. Can be one of the following: - - ``True``: all AIMessages with tool calls and all ToolMessages will be - excluded. + - ``True``: Each ``AIMessages`` with tool calls and all ``ToolMessages`` + will be excluded. - a sequence of tool call IDs to exclude: - ToolMessages with the corresponding tool call ID will be excluded. @@ -736,9 +736,11 @@ def trim_messages( exact token counting is not necessary. strategy: Strategy for trimming. + - "first": Keep the first <= n_count tokens of the messages. - "last": Keep the last <= n_count tokens of the messages. - Default is "last". + + Default is ``'last'``. allow_partial: Whether to split a message if only part of the message can be included. If ``strategy="last"`` then the last partial contents of a message are included. If ``strategy="first"`` then the first partial contents of a @@ -1035,16 +1037,16 @@ def convert_to_openai_messages( in OpenAI, Anthropic, Bedrock Converse, or VertexAI formats. text_format: How to format string or text block contents: - - "string": - If a message has a string content, this is left as a string. If - a message has content blocks that are all of type 'text', these are - joined with a newline to make a single string. If a message has - content blocks and at least one isn't of type 'text', then - all blocks are left as dicts. - - "block": - If a message has a string content, this is turned into a list - with a single content block of type 'text'. If a message has content - blocks these are left as is. + - ``'string'``: + If a message has a string content, this is left as a string. If + a message has content blocks that are all of type 'text', these are + joined with a newline to make a single string. If a message has + content blocks and at least one isn't of type 'text', then + all blocks are left as dicts. + - ``'block'``: + If a message has a string content, this is turned into a list + with a single content block of type 'text'. If a message has content + blocks these are left as is. Raises: ValueError: if an unrecognized ``text_format`` is specified, or if a message @@ -1052,12 +1054,13 @@ def convert_to_openai_messages( Returns: The return type depends on the input type: - - dict: - If a single message-like object is passed in, a single OpenAI message - dict is returned. - - list[dict]: - If a sequence of message-like objects are passed in, a list of OpenAI - message dicts is returned. + + - dict: + If a single message-like object is passed in, a single OpenAI message + dict is returned. + - list[dict]: + If a sequence of message-like objects are passed in, a list of OpenAI + message dicts is returned. Example: diff --git a/libs/core/langchain_core/output_parsers/xml.py b/libs/core/langchain_core/output_parsers/xml.py index fcbd68a89d0..0d7ef8b1e79 100644 --- a/libs/core/langchain_core/output_parsers/xml.py +++ b/libs/core/langchain_core/output_parsers/xml.py @@ -151,14 +151,15 @@ class XMLOutputParser(BaseTransformOutputParser): Note this may not be perfect depending on the LLM implementation. For example, with tags=["foo", "bar", "baz"]: - 1. A well-formatted XML instance: - "\n \n \n \n" - 2. A badly-formatted XML instance (missing closing tag for 'bar'): - "\n \n " + 1. A well-formatted XML instance: + "\n \n \n \n" - 3. A badly-formatted XML instance (unexpected 'tag' element): - "\n \n \n" + 2. A badly-formatted XML instance (missing closing tag for 'bar'): + "\n \n " + + 3. A badly-formatted XML instance (unexpected 'tag' element): + "\n \n \n" """ encoding_matcher: re.Pattern = re.compile( r"<([^>]*encoding[^>]*)>\n(.*)", re.MULTILINE | re.DOTALL diff --git a/libs/core/langchain_core/prompts/pipeline.py b/libs/core/langchain_core/prompts/pipeline.py index ee4ea4b0dca..194979fcfee 100644 --- a/libs/core/langchain_core/prompts/pipeline.py +++ b/libs/core/langchain_core/prompts/pipeline.py @@ -39,19 +39,20 @@ class PipelinePromptTemplate(BasePromptTemplate): This can be useful when you want to reuse parts of prompts. A PipelinePrompt consists of two main parts: - - final_prompt: This is the final prompt that is returned - - pipeline_prompts: This is a list of tuples, consisting - of a string (`name`) and a Prompt Template. - Each PromptTemplate will be formatted and then passed - to future prompt templates as a variable with - the same name as `name` + + - final_prompt: This is the final prompt that is returned + - pipeline_prompts: This is a list of tuples, consisting + of a string (``name``) and a Prompt Template. + Each PromptTemplate will be formatted and then passed + to future prompt templates as a variable with + the same name as ``name`` """ final_prompt: BasePromptTemplate """The final prompt that is returned.""" pipeline_prompts: list[tuple[str, BasePromptTemplate]] - """A list of tuples, consisting of a string (`name`) and a Prompt Template.""" + """A list of tuples, consisting of a string (``name``) and a Prompt Template.""" @classmethod def get_lc_namespace(cls) -> list[str]: diff --git a/libs/core/langchain_core/runnables/branch.py b/libs/core/langchain_core/runnables/branch.py index bd8e8c64a76..ed8d0ed0cdd 100644 --- a/libs/core/langchain_core/runnables/branch.py +++ b/libs/core/langchain_core/runnables/branch.py @@ -44,10 +44,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]): If no condition evaluates to True, the default branch is run on the input. - Parameters: - branches: A list of (condition, Runnable) pairs. - default: A Runnable to run if no condition is met. - Examples: .. code-block:: python @@ -67,7 +63,9 @@ class RunnableBranch(RunnableSerializable[Input, Output]): """ branches: Sequence[tuple[Runnable[Input, bool], Runnable[Input, Output]]] + """A list of (condition, Runnable) pairs.""" default: Runnable[Input, Output] + """A Runnable to run if no condition is met.""" def __init__( self, diff --git a/libs/core/langchain_core/runnables/configurable.py b/libs/core/langchain_core/runnables/configurable.py index 46138b64adf..763a10303a6 100644 --- a/libs/core/langchain_core/runnables/configurable.py +++ b/libs/core/langchain_core/runnables/configurable.py @@ -51,17 +51,15 @@ if TYPE_CHECKING: class DynamicRunnable(RunnableSerializable[Input, Output]): """Serializable Runnable that can be dynamically configured. - A DynamicRunnable should be initiated using the `configurable_fields` or - `configurable_alternatives` method of a Runnable. - - Parameters: - default: The default Runnable to use. - config: The configuration to use. + A DynamicRunnable should be initiated using the ``configurable_fields`` or + ``configurable_alternatives`` method of a Runnable. """ default: RunnableSerializable[Input, Output] + """The default Runnable to use.""" config: Optional[RunnableConfig] = None + """The configuration to use.""" model_config = ConfigDict( arbitrary_types_allowed=True, @@ -328,9 +326,6 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]): A RunnableConfigurableFields should be initiated using the `configurable_fields` method of a Runnable. - Parameters: - fields: The configurable fields to use. - Here is an example of using a RunnableConfigurableFields with LLMs: .. code-block:: python @@ -388,6 +383,7 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]): """ fields: dict[str, AnyConfigurableField] + """The configurable fields to use.""" @property def config_specs(self) -> list[ConfigurableFieldSpec]: diff --git a/libs/core/langchain_core/runnables/graph.py b/libs/core/langchain_core/runnables/graph.py index 7dc5ffc2329..389572a23b3 100644 --- a/libs/core/langchain_core/runnables/graph.py +++ b/libs/core/langchain_core/runnables/graph.py @@ -62,19 +62,16 @@ def is_uuid(value: str) -> bool: class Edge(NamedTuple): - """Edge in a graph. - - Parameters: - source: The source node id. - target: The target node id. - data: Optional data associated with the edge. Defaults to None. - conditional: Whether the edge is conditional. Defaults to False. - """ + """Edge in a graph.""" source: str + """The source node id.""" target: str + """The target node id.""" data: Optional[Stringifiable] = None + """Optional data associated with the edge. Defaults to None.""" conditional: bool = False + """Whether the edge is conditional. Defaults to False.""" def copy( self, *, source: Optional[str] = None, target: Optional[str] = None @@ -97,19 +94,16 @@ class Edge(NamedTuple): class Node(NamedTuple): - """Node in a graph. - - Parameters: - id: The unique identifier of the node. - name: The name of the node. - data: The data of the node. - metadata: Optional metadata for the node. Defaults to None. - """ + """Node in a graph.""" id: str + """The unique identifier of the node.""" name: str + """The name of the node.""" data: Union[type[BaseModel], RunnableType, None] + """The data of the node.""" metadata: Optional[dict[str, Any]] + """Optional metadata for the node. Defaults to None.""" def copy( self, @@ -135,16 +129,12 @@ class Node(NamedTuple): class Branch(NamedTuple): - """Branch in a graph. - - Parameters: - condition: A callable that returns a string representation of the condition. - ends: Optional dictionary of end node ids for the branches. Defaults - to None. - """ + """Branch in a graph.""" condition: Callable[..., str] + """A callable that returns a string representation of the condition.""" ends: Optional[dict[str, str]] + """Optional dictionary of end node ids for the branches. Defaults to None.""" class CurveStyle(Enum): @@ -168,7 +158,7 @@ class CurveStyle(Enum): class NodeStyles: """Schema for Hexadecimal color codes for different node types. - Parameters: + Args: default: The default color code. Defaults to "fill:#f2f0ff,line-height:1.2". first: The color code for the first node. Defaults to "fill-opacity:0". last: The color code for the last node. Defaults to "fill:#bfb6fc". @@ -182,8 +172,10 @@ class NodeStyles: class MermaidDrawMethod(Enum): """Enum for different draw methods supported by Mermaid.""" - PYPPETEER = "pyppeteer" # Uses Pyppeteer to render the graph - API = "api" # Uses Mermaid.INK API to render the graph + PYPPETEER = "pyppeteer" + """Uses Pyppeteer to render the graph""" + API = "api" + """Uses Mermaid.INK API to render the graph""" def node_data_str( @@ -269,7 +261,7 @@ def node_data_json( class Graph: """Graph of nodes and edges. - Parameters: + Args: nodes: Dictionary of nodes in the graph. Defaults to an empty dictionary. edges: List of edges in the graph. Defaults to an empty list. """ diff --git a/libs/core/langchain_core/runnables/graph_png.py b/libs/core/langchain_core/runnables/graph_png.py index c7d15c85127..27162907843 100644 --- a/libs/core/langchain_core/runnables/graph_png.py +++ b/libs/core/langchain_core/runnables/graph_png.py @@ -8,25 +8,14 @@ from langchain_core.runnables.graph import Graph, LabelsDict class PngDrawer: """Helper class to draw a state graph into a PNG file. - It requires `graphviz` and `pygraphviz` to be installed. - :param fontname: The font to use for the labels - :param labels: A dictionary of label overrides. The dictionary - should have the following format: - { - "nodes": { - "node1": "CustomLabel1", - "node2": "CustomLabel2", - "__end__": "End Node" - }, - "edges": { - "continue": "ContinueLabel", - "end": "EndLabel" - } - } - The keys are the original labels, and the values are the new labels. - Usage: - drawer = PngDrawer() - drawer.draw(state_graph, 'graph.png') + It requires ``graphviz`` and ``pygraphviz`` to be installed. + + Example: + + .. code-block:: python + + drawer = PngDrawer() + drawer.draw(state_graph, "graph.png") """ def __init__( diff --git a/libs/core/langchain_core/runnables/history.py b/libs/core/langchain_core/runnables/history.py index e838ee1e16f..24bfe22df0e 100644 --- a/libs/core/langchain_core/runnables/history.py +++ b/libs/core/langchain_core/runnables/history.py @@ -72,20 +72,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] For production use cases, you will want to use a persistent implementation of chat message history, such as ``RedisChatMessageHistory``. - Parameters: - get_session_history: Function that returns a new BaseChatMessageHistory. - This function should either take a single positional argument - `session_id` of type string and return a corresponding - chat message history instance. - input_messages_key: Must be specified if the base runnable accepts a dict - as input. The key in the input dict that contains the messages. - output_messages_key: Must be specified if the base Runnable returns a dict - as output. The key in the output dict that contains the messages. - history_messages_key: Must be specified if the base runnable accepts a dict - as input and expects a separate key for historical messages. - history_factory_config: Configure fields that should be passed to the - chat history factory. See ``ConfigurableFieldSpec`` for more details. - Example: Chat message history with an in-memory implementation for testing. .. code-block:: python @@ -242,10 +228,21 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] """ get_session_history: GetSessionHistoryCallable + """Function that returns a new BaseChatMessageHistory. + This function should either take a single positional argument ``session_id`` of type + string and return a corresponding chat message history instance""" input_messages_key: Optional[str] = None + """Must be specified if the base runnable accepts a dict as input. + The key in the input dict that contains the messages.""" output_messages_key: Optional[str] = None + """Must be specified if the base Runnable returns a dict as output. + The key in the output dict that contains the messages.""" history_messages_key: Optional[str] = None + """Must be specified if the base runnable accepts a dict as input and expects a + separate key for historical messages.""" history_factory_config: Sequence[ConfigurableFieldSpec] + """Configure fields that should be passed to the chat history factory. + See ``ConfigurableFieldSpec`` for more details.""" def __init__( self, @@ -271,17 +268,21 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] """Initialize RunnableWithMessageHistory. Args: - runnable: The base Runnable to be wrapped. Must take as input one of: - 1. A list of BaseMessages + runnable: The base Runnable to be wrapped. + Must take as input one of: + + 1. A list of ``BaseMessage`` 2. A dict with one key for all messages 3. A dict with one key for the current input string/message(s) and - a separate key for historical messages. If the input key points - to a string, it will be treated as a HumanMessage in history. + a separate key for historical messages. If the input key points + to a string, it will be treated as a ``HumanMessage`` in history. Must return as output one of: - 1. A string which can be treated as an AIMessage - 2. A BaseMessage or sequence of BaseMessages - 3. A dict with a key for a BaseMessage or sequence of BaseMessages + + 1. A string which can be treated as an ``AIMessage`` + 2. A ``BaseMessage`` or sequence of ``BaseMessage`` + 3. A dict with a key for a ``BaseMessage`` or sequence of + ``BaseMessage`` get_session_history: Function that returns a new BaseChatMessageHistory. This function should either take a single positional argument diff --git a/libs/core/langchain_core/runnables/router.py b/libs/core/langchain_core/runnables/router.py index 827e75c6624..0515db43ac8 100644 --- a/libs/core/langchain_core/runnables/router.py +++ b/libs/core/langchain_core/runnables/router.py @@ -38,15 +38,12 @@ if TYPE_CHECKING: class RouterInput(TypedDict): - """Router input. - - Attributes: - key: The key to route on. - input: The input to pass to the selected Runnable. - """ + """Router input.""" key: str + """The key to route on.""" input: Any + """The input to pass to the selected Runnable.""" class RouterRunnable(RunnableSerializable[RouterInput, Output]): diff --git a/libs/core/langchain_core/runnables/utils.py b/libs/core/langchain_core/runnables/utils.py index eb4c0cd43d5..cebb81dfe50 100644 --- a/libs/core/langchain_core/runnables/utils.py +++ b/libs/core/langchain_core/runnables/utils.py @@ -551,22 +551,18 @@ async def aadd(addables: AsyncIterable[Addable]) -> Optional[Addable]: class ConfigurableField(NamedTuple): - """Field that can be configured by the user. - - Parameters: - id: The unique identifier of the field. - name: The name of the field. Defaults to None. - description: The description of the field. Defaults to None. - annotation: The annotation of the field. Defaults to None. - is_shared: Whether the field is shared. Defaults to False. - """ + """Field that can be configured by the user.""" id: str - + """The unique identifier of the field.""" name: Optional[str] = None + """The name of the field. Defaults to None.""" description: Optional[str] = None + """The description of the field. Defaults to None.""" annotation: Optional[Any] = None + """The annotation of the field. Defaults to None.""" is_shared: bool = False + """Whether the field is shared. Defaults to False.""" @override def __hash__(self) -> int: @@ -574,24 +570,20 @@ class ConfigurableField(NamedTuple): class ConfigurableFieldSingleOption(NamedTuple): - """Field that can be configured by the user with a default value. - - Parameters: - id: The unique identifier of the field. - options: The options for the field. - default: The default value for the field. - name: The name of the field. Defaults to None. - description: The description of the field. Defaults to None. - is_shared: Whether the field is shared. Defaults to False. - """ + """Field that can be configured by the user with a default value.""" id: str + """The unique identifier of the field.""" options: Mapping[str, Any] + """The options for the field.""" default: str - + """The default value for the field.""" name: Optional[str] = None + """The name of the field. Defaults to None.""" description: Optional[str] = None + """The description of the field. Defaults to None.""" is_shared: bool = False + """Whether the field is shared. Defaults to False.""" @override def __hash__(self) -> int: @@ -599,24 +591,20 @@ class ConfigurableFieldSingleOption(NamedTuple): class ConfigurableFieldMultiOption(NamedTuple): - """Field that can be configured by the user with multiple default values. - - Parameters: - id: The unique identifier of the field. - options: The options for the field. - default: The default values for the field. - name: The name of the field. Defaults to None. - description: The description of the field. Defaults to None. - is_shared: Whether the field is shared. Defaults to False. - """ + """Field that can be configured by the user with multiple default values.""" id: str + """The unique identifier of the field.""" options: Mapping[str, Any] + """The options for the field.""" default: Sequence[str] - + """The default values for the field.""" name: Optional[str] = None + """The name of the field. Defaults to None.""" description: Optional[str] = None + """The description of the field. Defaults to None.""" is_shared: bool = False + """Whether the field is shared. Defaults to False.""" @override def __hash__(self) -> int: @@ -629,26 +617,22 @@ AnyConfigurableField = Union[ class ConfigurableFieldSpec(NamedTuple): - """Field that can be configured by the user. It is a specification of a field. - - Parameters: - id: The unique identifier of the field. - annotation: The annotation of the field. - name: The name of the field. Defaults to None. - description: The description of the field. Defaults to None. - default: The default value for the field. Defaults to None. - is_shared: Whether the field is shared. Defaults to False. - dependencies: The dependencies of the field. Defaults to None. - """ + """Field that can be configured by the user. It is a specification of a field.""" id: str + """The unique identifier of the field.""" annotation: Any - + """The annotation of the field.""" name: Optional[str] = None + """The name of the field. Defaults to None.""" description: Optional[str] = None + """The description of the field. Defaults to None.""" default: Any = None + """The default value for the field. Defaults to None.""" is_shared: bool = False + """Whether the field is shared. Defaults to False.""" dependencies: Optional[list[str]] = None + """The dependencies of the field. Defaults to None.""" def get_unique_config_specs( diff --git a/libs/core/langchain_core/tools/base.py b/libs/core/langchain_core/tools/base.py index d1b18a3aa42..c4de10ddeb7 100644 --- a/libs/core/langchain_core/tools/base.py +++ b/libs/core/langchain_core/tools/base.py @@ -271,15 +271,12 @@ def _function_annotations_are_pydantic_v1( class _SchemaConfig: - """Configuration for Pydantic models generated from function signatures. - - Attributes: - extra: Whether to allow extra fields in the model. - arbitrary_types_allowed: Whether to allow arbitrary types in the model. - """ + """Configuration for Pydantic models generated from function signatures.""" extra: str = "forbid" + """Whether to allow extra fields in the model.""" arbitrary_types_allowed: bool = True + """Whether to allow arbitrary types in the model.""" def create_schema_from_function( diff --git a/libs/core/langchain_core/tools/convert.py b/libs/core/langchain_core/tools/convert.py index 84b328f0bed..691550439c1 100644 --- a/libs/core/langchain_core/tools/convert.py +++ b/libs/core/langchain_core/tools/convert.py @@ -92,12 +92,13 @@ def tool( positional argument. description: Optional description for the tool. Precedence for the tool description value is as follows: - - `description` argument - (used even if docstring and/or `args_schema` are provided) - - tool function docstring - (used even if `args_schema` is provided) - - `args_schema` description - (used only if `description` / docstring are not provided) + + - ``description`` argument + (used even if docstring and/or ``args_schema`` are provided) + - tool function docstring + (used even if ``args_schema`` is provided) + - ``args_schema`` description + (used only if `description` / docstring are not provided) *args: Extra positional arguments. Must be empty. return_direct: Whether to return directly from the tool rather than continuing the agent loop. Defaults to False. diff --git a/libs/core/langchain_core/tracers/evaluation.py b/libs/core/langchain_core/tracers/evaluation.py index c7447ad4d81..a1e9ffb4785 100644 --- a/libs/core/langchain_core/tracers/evaluation.py +++ b/libs/core/langchain_core/tracers/evaluation.py @@ -38,24 +38,27 @@ class EvaluatorCallbackHandler(BaseTracer): """Tracer that runs a run evaluator whenever a run is persisted. Attributes: - example_id : Union[UUID, None] - The example ID associated with the runs. client : Client The LangSmith client instance used for evaluating the runs. - evaluators : Sequence[RunEvaluator] - The sequence of run evaluators to be executed. - executor : ThreadPoolExecutor - The thread pool executor used for running the evaluators. - futures : set[Future] - The set of futures representing the running evaluators. - skip_unfinished : bool - Whether to skip runs that are not finished or raised - an error. - project_name : Optional[str] - The LangSmith project name to be organize eval chain runs under. """ name: str = "evaluator_callback_handler" + example_id: Optional[UUID] = None + """The example ID associated with the runs.""" + client: langsmith.Client + """The LangSmith client instance used for evaluating the runs.""" + evaluators: Sequence[langsmith.RunEvaluator] = () + """The sequence of run evaluators to be executed.""" + executor: Optional[ThreadPoolExecutor] = None + """The thread pool executor used for running the evaluators.""" + futures: weakref.WeakSet[Future] = weakref.WeakSet() + """The set of futures representing the running evaluators.""" + skip_unfinished: bool = True + """Whether to skip runs that are not finished or raised an error.""" + project_name: Optional[str] = None + """The LangSmith project name to be organize eval chain runs under.""" + logged_eval_results: dict[tuple[str, str], list[EvaluationResult]] + lock: threading.Lock def __init__( self, @@ -91,7 +94,7 @@ class EvaluatorCallbackHandler(BaseTracer): self.client = client or langchain_tracer.get_client() self.evaluators = evaluators if max_concurrency is None: - self.executor: Optional[ThreadPoolExecutor] = _get_executor() + self.executor = _get_executor() elif max_concurrency > 0: self.executor = ThreadPoolExecutor(max_workers=max_concurrency) weakref.finalize( @@ -100,10 +103,10 @@ class EvaluatorCallbackHandler(BaseTracer): ) else: self.executor = None - self.futures: weakref.WeakSet[Future] = weakref.WeakSet() + self.futures = weakref.WeakSet() self.skip_unfinished = skip_unfinished self.project_name = project_name - self.logged_eval_results: dict[tuple[str, str], list[EvaluationResult]] = {} + self.logged_eval_results = {} self.lock = threading.Lock() _TRACERS.add(self) @@ -111,12 +114,8 @@ class EvaluatorCallbackHandler(BaseTracer): """Evaluate the run in the project. Args: - ---------- - run : Run - The run to be evaluated. - evaluator : RunEvaluator - The evaluator to use for evaluating the run. - + run: The run to be evaluated. + evaluator: The evaluator to use for evaluating the run. """ try: if self.project_name is None: @@ -202,10 +201,7 @@ class EvaluatorCallbackHandler(BaseTracer): """Run the evaluator on the run. Args: - ---------- - run : Run - The run to be evaluated. - + run: The run to be evaluated. """ if self.skip_unfinished and not run.outputs: logger.debug("Skipping unfinished run %s", run.id) diff --git a/libs/core/langchain_core/tracers/event_stream.py b/libs/core/langchain_core/tracers/event_stream.py index b0e44d4eca1..5b150604516 100644 --- a/libs/core/langchain_core/tracers/event_stream.py +++ b/libs/core/langchain_core/tracers/event_stream.py @@ -9,13 +9,14 @@ from typing import ( TYPE_CHECKING, Any, Optional, + TypedDict, TypeVar, Union, cast, ) from uuid import UUID, uuid4 -from typing_extensions import NotRequired, TypedDict, override +from typing_extensions import NotRequired, override from langchain_core.callbacks.base import AsyncCallbackHandler from langchain_core.messages import AIMessageChunk, BaseMessage, BaseMessageChunk @@ -53,22 +54,20 @@ class RunInfo(TypedDict): """Information about a run. This is used to keep track of the metadata associated with a run. - - Parameters: - name: The name of the run. - tags: The tags associated with the run. - metadata: The metadata associated with the run. - run_type: The type of the run. - inputs: The inputs to the run. - parent_run_id: The ID of the parent run. """ name: str + """The name of the run.""" tags: list[str] + """The tags associated with the run.""" metadata: dict[str, Any] + """The metadata associated with the run.""" run_type: str + """The type of the run.""" inputs: NotRequired[Any] + """The inputs to the run.""" parent_run_id: Optional[UUID] + """The ID of the parent run.""" def _assign_name(name: Optional[str], serialized: Optional[dict[str, Any]]) -> str: diff --git a/libs/core/langchain_core/tracers/root_listeners.py b/libs/core/langchain_core/tracers/root_listeners.py index efe1a56e24d..5b07553631a 100644 --- a/libs/core/langchain_core/tracers/root_listeners.py +++ b/libs/core/langchain_core/tracers/root_listeners.py @@ -21,18 +21,10 @@ AsyncListener = Union[ class RootListenersTracer(BaseTracer): - """Tracer that calls listeners on run start, end, and error. - - Parameters: - log_missing_parent: Whether to log a warning if the parent is missing. - Default is False. - config: The runnable config. - on_start: The listener to call on run start. - on_end: The listener to call on run end. - on_error: The listener to call on run error. - """ + """Tracer that calls listeners on run start, end, and error.""" log_missing_parent = False + """Whether to log a warning if the parent is missing. Default is False.""" def __init__( self, @@ -84,18 +76,10 @@ class RootListenersTracer(BaseTracer): class AsyncRootListenersTracer(AsyncBaseTracer): - """Async Tracer that calls listeners on run start, end, and error. - - Parameters: - log_missing_parent: Whether to log a warning if the parent is missing. - Default is False. - config: The runnable config. - on_start: The listener to call on run start. - on_end: The listener to call on run end. - on_error: The listener to call on run error. - """ + """Async Tracer that calls listeners on run start, end, and error.""" log_missing_parent = False + """Whether to log a warning if the parent is missing. Default is False.""" def __init__( self, diff --git a/libs/core/langchain_core/tracers/run_collector.py b/libs/core/langchain_core/tracers/run_collector.py index e7a7dfc7add..afac1ad3267 100644 --- a/libs/core/langchain_core/tracers/run_collector.py +++ b/libs/core/langchain_core/tracers/run_collector.py @@ -11,12 +11,6 @@ class RunCollectorCallbackHandler(BaseTracer): """Tracer that collects all nested runs in a list. This tracer is useful for inspection and evaluation purposes. - - Parameters - ---------- - name : str, default="run-collector_callback_handler" - example_id : Optional[Union[UUID, str]], default=None - The ID of the example being traced. It can be either a UUID or a string. """ name: str = "run-collector_callback_handler" @@ -26,12 +20,10 @@ class RunCollectorCallbackHandler(BaseTracer): ) -> None: """Initialize the RunCollectorCallbackHandler. - Parameters - ---------- - example_id : Optional[Union[UUID, str]], default=None - The ID of the example being traced. It can be either a UUID or a string. - **kwargs : Any - Additional keyword arguments + Args: + example_id: The ID of the example being traced. (default: None). + It can be either a UUID or a string. + **kwargs: Additional keyword arguments. """ super().__init__(**kwargs) self.example_id = ( @@ -42,10 +34,8 @@ class RunCollectorCallbackHandler(BaseTracer): def _persist_run(self, run: Run) -> None: """Persist a run by adding it to the traced_runs list. - Parameters - ---------- - run : Run - The run to be persisted. + Args: + run: The run to be persisted. """ run_ = run.copy() run_.reference_example_id = self.example_id diff --git a/libs/core/langchain_core/utils/json_schema.py b/libs/core/langchain_core/utils/json_schema.py index 2c0672ab645..54c9a922d34 100644 --- a/libs/core/langchain_core/utils/json_schema.py +++ b/libs/core/langchain_core/utils/json_schema.py @@ -119,9 +119,9 @@ def dereference_refs( full_schema: The complete schema (defaults to schema_obj). skip_keys: - If None (the default), we skip recursion under '$defs' *and* only - shallow-inline refs. + shallow-inline refs. - If provided (even as an empty list), we will recurse under every key and - deep-inline all refs. + deep-inline all refs. Returns: The schema with refs dereferenced. diff --git a/libs/core/langchain_core/vectorstores/base.py b/libs/core/langchain_core/vectorstores/base.py index 2c4425c9c5a..888136b8929 100644 --- a/libs/core/langchain_core/vectorstores/base.py +++ b/libs/core/langchain_core/vectorstores/base.py @@ -429,6 +429,7 @@ class VectorStore(ABC): """The 'correct' relevance function. may differ depending on a few things, including: + - the distance / similarity metric used by the VectorStore - the scale of your embeddings (OpenAI's are unit normed. Many others are not!) - embedding dimensionality diff --git a/libs/core/tests/unit_tests/runnables/test_runnable.py b/libs/core/tests/unit_tests/runnables/test_runnable.py index 530ce185743..14a5334a844 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable.py @@ -432,13 +432,7 @@ def test_schemas(snapshot: SnapshotAssertion) -> None: "$ref": "#/definitions/RouterInput", "definitions": { "RouterInput": { - "description": "Router input.\n" - "\n" - "Attributes:\n" - " key: The key to route " - "on.\n" - " input: The input to pass " - "to the selected Runnable.", + "description": "Router input.", "properties": { "input": {"title": "Input"}, "key": {"title": "Key", "type": "string"}, From cc98fb9bee98b231babf9e39a7245b330b68760d Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Mon, 8 Sep 2025 20:15:04 +0200 Subject: [PATCH 30/30] chore(core): add ruff rule PLC0415 (#32351) See https://docs.astral.sh/ruff/rules/import-outside-top-level/ Co-authored-by: Mason Daugherty --- libs/core/langchain_core/callbacks/manager.py | 32 ++--- libs/core/langchain_core/callbacks/usage.py | 3 +- libs/core/langchain_core/chat_history.py | 7 +- .../langchain_core/document_loaders/base.py | 13 +- libs/core/langchain_core/embeddings/fake.py | 8 +- libs/core/langchain_core/env.py | 5 +- libs/core/langchain_core/globals.py | 43 +++--- .../langchain_core/language_models/base.py | 27 ++-- .../language_models/chat_models.py | 9 +- libs/core/langchain_core/load/dump.py | 5 +- libs/core/langchain_core/messages/base.py | 3 +- libs/core/langchain_core/messages/utils.py | 29 ++-- .../core/langchain_core/output_parsers/xml.py | 22 +-- libs/core/langchain_core/prompts/message.py | 3 +- libs/core/langchain_core/prompts/string.py | 20 +-- libs/core/langchain_core/retrievers.py | 5 +- libs/core/langchain_core/runnables/base.py | 125 +++++++++++------- libs/core/langchain_core/runnables/branch.py | 9 +- libs/core/langchain_core/runnables/config.py | 15 +-- .../langchain_core/runnables/fallbacks.py | 5 +- libs/core/langchain_core/runnables/graph.py | 21 +-- .../langchain_core/runnables/graph_ascii.py | 24 ++-- .../langchain_core/runnables/graph_mermaid.py | 38 ++++-- .../langchain_core/runnables/graph_png.py | 13 +- libs/core/langchain_core/runnables/history.py | 12 +- libs/core/langchain_core/sys_info.py | 11 +- .../langchain_core/tracers/event_stream.py | 19 +-- .../core/langchain_core/tracers/log_stream.py | 17 +-- .../langchain_core/utils/function_calling.py | 28 ++-- .../langchain_core/utils/interactive_env.py | 4 +- libs/core/langchain_core/vectorstores/base.py | 8 +- .../langchain_core/vectorstores/in_memory.py | 13 +- .../core/langchain_core/vectorstores/utils.py | 30 +++-- libs/core/pyproject.toml | 1 - .../language_models/chat_models/test_cache.py | 5 +- .../chat_models/test_rate_limiting.py | 3 +- .../unit_tests/load/test_serializable.py | 5 +- .../output_parsers/test_openai_tools.py | 5 +- .../output_parsers/test_pydantic_parser.py | 2 - .../tests/unit_tests/prompts/test_prompt.py | 7 +- .../unit_tests/runnables/test_concurrency.py | 3 +- .../unit_tests/runnables/test_history.py | 15 +-- .../unit_tests/runnables/test_imports.py | 2 +- .../unit_tests/runnables/test_runnable.py | 15 +-- .../runnables/test_runnable_events_v2.py | 6 +- libs/core/tests/unit_tests/test_globals.py | 9 +- libs/core/tests/unit_tests/test_tools.py | 25 +--- .../tests/unit_tests/utils/test_pydantic.py | 30 +---- .../core/tests/unit_tests/utils/test_utils.py | 13 +- 49 files changed, 360 insertions(+), 412 deletions(-) diff --git a/libs/core/langchain_core/callbacks/manager.py b/libs/core/langchain_core/callbacks/manager.py index 4851a1c1c1d..676bb15e525 100644 --- a/libs/core/langchain_core/callbacks/manager.py +++ b/libs/core/langchain_core/callbacks/manager.py @@ -28,8 +28,18 @@ from langchain_core.callbacks.base import ( ToolManagerMixin, ) from langchain_core.callbacks.stdout import StdOutCallbackHandler +from langchain_core.globals import get_debug from langchain_core.messages import BaseMessage, get_buffer_string +from langchain_core.tracers.context import ( + _configure_hooks, + _get_trace_callbacks, + _get_tracer_project, + _tracing_v2_is_enabled, + tracing_v2_callback_var, +) +from langchain_core.tracers.langchain import LangChainTracer from langchain_core.tracers.schemas import Run +from langchain_core.tracers.stdout import ConsoleCallbackHandler from langchain_core.utils.env import env_var_is_set if TYPE_CHECKING: @@ -46,8 +56,6 @@ logger = logging.getLogger(__name__) def _get_debug() -> bool: - from langchain_core.globals import get_debug - return get_debug() @@ -103,8 +111,6 @@ def trace_as_chain_group( manager.on_chain_end({"output": res}) """ - from langchain_core.tracers.context import _get_trace_callbacks - cb = _get_trace_callbacks( project_name, example_id, callback_manager=callback_manager ) @@ -189,8 +195,6 @@ async def atrace_as_chain_group( await manager.on_chain_end({"output": res}) """ - from langchain_core.tracers.context import _get_trace_callbacks - cb = _get_trace_callbacks( project_name, example_id, callback_manager=callback_manager ) @@ -2376,13 +2380,6 @@ def _configure( Returns: T: The configured callback manager. """ - from langchain_core.tracers.context import ( - _configure_hooks, - _get_tracer_project, - _tracing_v2_is_enabled, - tracing_v2_callback_var, - ) - tracing_context = get_tracing_context() tracing_metadata = tracing_context["metadata"] tracing_tags = tracing_context["tags"] @@ -2459,9 +2456,6 @@ def _configure( tracer_project = _get_tracer_project() debug = _get_debug() if verbose or debug or tracing_v2_enabled_: - from langchain_core.tracers.langchain import LangChainTracer - from langchain_core.tracers.stdout import ConsoleCallbackHandler - if verbose and not any( isinstance(handler, StdOutCallbackHandler) for handler in callback_manager.handlers @@ -2630,7 +2624,8 @@ async def adispatch_custom_event( .. versionadded:: 0.2.15 """ - from langchain_core.runnables.config import ( + # Import locally to prevent circular imports. + from langchain_core.runnables.config import ( # noqa: PLC0415 ensure_config, get_async_callback_manager_for_config, ) @@ -2705,7 +2700,8 @@ def dispatch_custom_event( .. versionadded:: 0.2.15 """ - from langchain_core.runnables.config import ( + # Import locally to prevent circular imports. + from langchain_core.runnables.config import ( # noqa: PLC0415 ensure_config, get_callback_manager_for_config, ) diff --git a/libs/core/langchain_core/callbacks/usage.py b/libs/core/langchain_core/callbacks/usage.py index 497b6ff4912..90fa7573997 100644 --- a/libs/core/langchain_core/callbacks/usage.py +++ b/libs/core/langchain_core/callbacks/usage.py @@ -12,6 +12,7 @@ from langchain_core.callbacks import BaseCallbackHandler from langchain_core.messages import AIMessage from langchain_core.messages.ai import UsageMetadata, add_usage from langchain_core.outputs import ChatGeneration, LLMResult +from langchain_core.tracers.context import register_configure_hook class UsageMetadataCallbackHandler(BaseCallbackHandler): @@ -133,8 +134,6 @@ def get_usage_metadata_callback( .. versionadded:: 0.3.49 """ - from langchain_core.tracers.context import register_configure_hook - usage_metadata_callback_var: ContextVar[Optional[UsageMetadataCallbackHandler]] = ( ContextVar(name, default=None) ) diff --git a/libs/core/langchain_core/chat_history.py b/libs/core/langchain_core/chat_history.py index 0091b240b69..6f66b7aba75 100644 --- a/libs/core/langchain_core/chat_history.py +++ b/libs/core/langchain_core/chat_history.py @@ -27,6 +27,7 @@ from langchain_core.messages import ( HumanMessage, get_buffer_string, ) +from langchain_core.runnables.config import run_in_executor if TYPE_CHECKING: from collections.abc import Sequence @@ -113,8 +114,6 @@ class BaseChatMessageHistory(ABC): Returns: The messages. """ - from langchain_core.runnables.config import run_in_executor - return await run_in_executor(None, lambda: self.messages) def add_user_message(self, message: Union[HumanMessage, str]) -> None: @@ -190,8 +189,6 @@ class BaseChatMessageHistory(ABC): Args: messages: A sequence of BaseMessage objects to store. """ - from langchain_core.runnables.config import run_in_executor - await run_in_executor(None, self.add_messages, messages) @abstractmethod @@ -200,8 +197,6 @@ class BaseChatMessageHistory(ABC): async def aclear(self) -> None: """Async remove all messages from the store.""" - from langchain_core.runnables.config import run_in_executor - await run_in_executor(None, self.clear) def __str__(self) -> str: diff --git a/libs/core/langchain_core/document_loaders/base.py b/libs/core/langchain_core/document_loaders/base.py index 7208529da17..deeb9569ad2 100644 --- a/libs/core/langchain_core/document_loaders/base.py +++ b/libs/core/langchain_core/document_loaders/base.py @@ -15,6 +15,13 @@ if TYPE_CHECKING: from langchain_core.documents import Document from langchain_core.documents.base import Blob +try: + from langchain_text_splitters import RecursiveCharacterTextSplitter + + _HAS_TEXT_SPLITTERS = True +except ImportError: + _HAS_TEXT_SPLITTERS = False + class BaseLoader(ABC): # noqa: B024 """Interface for Document Loader. @@ -62,15 +69,13 @@ class BaseLoader(ABC): # noqa: B024 List of Documents. """ if text_splitter is None: - try: - from langchain_text_splitters import RecursiveCharacterTextSplitter - except ImportError as e: + if not _HAS_TEXT_SPLITTERS: msg = ( "Unable to import from langchain_text_splitters. Please specify " "text_splitter or install langchain_text_splitters with " "`pip install -U langchain-text-splitters`." ) - raise ImportError(msg) from e + raise ImportError(msg) text_splitter_: TextSplitter = RecursiveCharacterTextSplitter() else: diff --git a/libs/core/langchain_core/embeddings/fake.py b/libs/core/langchain_core/embeddings/fake.py index cd644bf8c69..c33281c484a 100644 --- a/libs/core/langchain_core/embeddings/fake.py +++ b/libs/core/langchain_core/embeddings/fake.py @@ -1,6 +1,7 @@ """Module contains a few fake embedding models for testing purposes.""" # Please do not add additional fake embedding model implementations here. +import contextlib import hashlib from pydantic import BaseModel @@ -8,6 +9,9 @@ from typing_extensions import override from langchain_core.embeddings import Embeddings +with contextlib.suppress(ImportError): + import numpy as np + class FakeEmbeddings(Embeddings, BaseModel): """Fake embedding model for unit testing purposes. @@ -54,8 +58,6 @@ class FakeEmbeddings(Embeddings, BaseModel): """The size of the embedding vector.""" def _get_embedding(self) -> list[float]: - import numpy as np - return list(np.random.default_rng().normal(size=self.size)) @override @@ -113,8 +115,6 @@ class DeterministicFakeEmbedding(Embeddings, BaseModel): """The size of the embedding vector.""" def _get_embedding(self, seed: int) -> list[float]: - import numpy as np - # set the seed for the random generator rng = np.random.default_rng(seed) return list(rng.normal(size=self.size)) diff --git a/libs/core/langchain_core/env.py b/libs/core/langchain_core/env.py index fd619bc1d94..240e62a8e6e 100644 --- a/libs/core/langchain_core/env.py +++ b/libs/core/langchain_core/env.py @@ -3,6 +3,8 @@ import platform from functools import lru_cache +from langchain_core import __version__ + @lru_cache(maxsize=1) def get_runtime_environment() -> dict: @@ -11,9 +13,6 @@ def get_runtime_environment() -> dict: Returns: A dictionary with information about the runtime environment. """ - # Lazy import to avoid circular imports - from langchain_core import __version__ - return { "library_version": __version__, "library": "langchain-core", diff --git a/libs/core/langchain_core/globals.py b/libs/core/langchain_core/globals.py index faf26578f35..01e851f942e 100644 --- a/libs/core/langchain_core/globals.py +++ b/libs/core/langchain_core/globals.py @@ -6,6 +6,13 @@ from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from langchain_core.caches import BaseCache +try: + import langchain # type: ignore[import-not-found] + + _HAS_LANGCHAIN = True +except ImportError: + _HAS_LANGCHAIN = False + # DO NOT USE THESE VALUES DIRECTLY! # Use them only via `get_()` and `set_()` below, @@ -22,9 +29,7 @@ def set_verbose(value: bool) -> None: # noqa: FBT001 Args: value: The new value for the `verbose` global setting. """ - try: - import langchain # type: ignore[import-not-found] - + if _HAS_LANGCHAIN: # We're about to run some deprecated code, don't report warnings from it. # The user called the correct (non-deprecated) code path and shouldn't get # warnings. @@ -43,8 +48,6 @@ def set_verbose(value: bool) -> None: # noqa: FBT001 # Remove it once `langchain.verbose` is no longer supported, and once all # users have migrated to using `set_verbose()` here. langchain.verbose = value - except ImportError: - pass global _verbose # noqa: PLW0603 _verbose = value @@ -56,9 +59,7 @@ def get_verbose() -> bool: Returns: The value of the `verbose` global setting. """ - try: - import langchain - + if _HAS_LANGCHAIN: # We're about to run some deprecated code, don't report warnings from it. # The user called the correct (non-deprecated) code path and shouldn't get # warnings. @@ -83,7 +84,7 @@ def get_verbose() -> bool: # deprecation warnings directing them to use `set_verbose()` when they # import `langchain.verbose`. old_verbose = langchain.verbose - except ImportError: + else: old_verbose = False return _verbose or old_verbose @@ -95,9 +96,7 @@ def set_debug(value: bool) -> None: # noqa: FBT001 Args: value: The new value for the `debug` global setting. """ - try: - import langchain - + if _HAS_LANGCHAIN: # We're about to run some deprecated code, don't report warnings from it. # The user called the correct (non-deprecated) code path and shouldn't get # warnings. @@ -114,8 +113,6 @@ def set_debug(value: bool) -> None: # noqa: FBT001 # Remove it once `langchain.debug` is no longer supported, and once all # users have migrated to using `set_debug()` here. langchain.debug = value - except ImportError: - pass global _debug # noqa: PLW0603 _debug = value @@ -127,9 +124,7 @@ def get_debug() -> bool: Returns: The value of the `debug` global setting. """ - try: - import langchain - + if _HAS_LANGCHAIN: # We're about to run some deprecated code, don't report warnings from it. # The user called the correct (non-deprecated) code path and shouldn't get # warnings. @@ -151,7 +146,7 @@ def get_debug() -> bool: # to using `set_debug()` yet. Those users are getting deprecation warnings # directing them to use `set_debug()` when they import `langchain.debug`. old_debug = langchain.debug - except ImportError: + else: old_debug = False return _debug or old_debug @@ -163,9 +158,7 @@ def set_llm_cache(value: Optional["BaseCache"]) -> None: Args: value: The new LLM cache to use. If `None`, the LLM cache is disabled. """ - try: - import langchain - + if _HAS_LANGCHAIN: # We're about to run some deprecated code, don't report warnings from it. # The user called the correct (non-deprecated) code path and shouldn't get # warnings. @@ -184,8 +177,6 @@ def set_llm_cache(value: Optional["BaseCache"]) -> None: # Remove it once `langchain.llm_cache` is no longer supported, and # once all users have migrated to using `set_llm_cache()` here. langchain.llm_cache = value - except ImportError: - pass global _llm_cache # noqa: PLW0603 _llm_cache = value @@ -197,9 +188,7 @@ def get_llm_cache() -> Optional["BaseCache"]: Returns: The value of the `llm_cache` global setting. """ - try: - import langchain - + if _HAS_LANGCHAIN: # We're about to run some deprecated code, don't report warnings from it. # The user called the correct (non-deprecated) code path and shouldn't get # warnings. @@ -225,7 +214,7 @@ def get_llm_cache() -> Optional["BaseCache"]: # Those users are getting deprecation warnings directing them # to use `set_llm_cache()` when they import `langchain.llm_cache`. old_llm_cache = langchain.llm_cache - except ImportError: + else: old_llm_cache = None return _llm_cache or old_llm_cache diff --git a/libs/core/langchain_core/language_models/base.py b/libs/core/langchain_core/language_models/base.py index 46bb954e95b..f0e444b5859 100644 --- a/libs/core/langchain_core/language_models/base.py +++ b/libs/core/langchain_core/language_models/base.py @@ -22,19 +22,31 @@ from typing_extensions import TypeAlias, TypedDict, override from langchain_core._api import deprecated from langchain_core.caches import BaseCache from langchain_core.callbacks import Callbacks +from langchain_core.globals import get_verbose from langchain_core.messages import ( AnyMessage, BaseMessage, MessageLikeRepresentation, get_buffer_string, ) -from langchain_core.prompt_values import PromptValue +from langchain_core.prompt_values import ( + ChatPromptValueConcrete, + PromptValue, + StringPromptValue, +) from langchain_core.runnables import Runnable, RunnableSerializable from langchain_core.utils import get_pydantic_field_names if TYPE_CHECKING: from langchain_core.outputs import LLMResult +try: + from transformers import GPT2TokenizerFast # type: ignore[import-not-found] + + _HAS_TRANSFORMERS = True +except ImportError: + _HAS_TRANSFORMERS = False + class LangSmithParams(TypedDict, total=False): """LangSmith parameters for tracing.""" @@ -66,15 +78,13 @@ def get_tokenizer() -> Any: The GPT-2 tokenizer instance. """ - try: - from transformers import GPT2TokenizerFast # type: ignore[import-not-found] - except ImportError as e: + if not _HAS_TRANSFORMERS: msg = ( "Could not import transformers python package. " "This is needed in order to calculate get_token_ids. " "Please install it with `pip install transformers`." ) - raise ImportError(msg) from e + raise ImportError(msg) # create a GPT-2 tokenizer instance return GPT2TokenizerFast.from_pretrained("gpt2") @@ -95,8 +105,6 @@ LanguageModelOutputVar = TypeVar("LanguageModelOutputVar", BaseMessage, str) def _get_verbosity() -> bool: - from langchain_core.globals import get_verbose - return get_verbose() @@ -158,11 +166,6 @@ class BaseLanguageModel( @override def InputType(self) -> TypeAlias: """Get the input type for this runnable.""" - from langchain_core.prompt_values import ( - ChatPromptValueConcrete, - StringPromptValue, - ) - # This is a version of LanguageModelInput which replaces the abstract # base class BaseMessage with a union of its subclasses, which makes # for a much better schema. diff --git a/libs/core/langchain_core/language_models/chat_models.py b/libs/core/langchain_core/language_models/chat_models.py index 1d931689a3d..81ce5cbc505 100644 --- a/libs/core/langchain_core/language_models/chat_models.py +++ b/libs/core/langchain_core/language_models/chat_models.py @@ -46,6 +46,10 @@ from langchain_core.messages import ( message_chunk_to_message, ) from langchain_core.messages.ai import _LC_ID_PREFIX +from langchain_core.output_parsers.openai_tools import ( + JsonOutputKeyToolsParser, + PydanticToolsParser, +) from langchain_core.outputs import ( ChatGeneration, ChatGenerationChunk, @@ -1590,11 +1594,6 @@ class BaseChatModel(BaseLanguageModel[BaseMessage], ABC): msg = f"Received unsupported arguments {kwargs}" raise ValueError(msg) - from langchain_core.output_parsers.openai_tools import ( - JsonOutputKeyToolsParser, - PydanticToolsParser, - ) - if type(self).bind_tools is BaseChatModel.bind_tools: msg = "with_structured_output is not implemented for this model." raise NotImplementedError(msg) diff --git a/libs/core/langchain_core/load/dump.py b/libs/core/langchain_core/load/dump.py index f8ab13a7f97..c7cd819a4ae 100644 --- a/libs/core/langchain_core/load/dump.py +++ b/libs/core/langchain_core/load/dump.py @@ -6,6 +6,8 @@ from typing import Any from pydantic import BaseModel from langchain_core.load.serializable import Serializable, to_json_not_implemented +from langchain_core.messages import AIMessage +from langchain_core.outputs import ChatGeneration def default(obj: Any) -> Any: @@ -23,9 +25,6 @@ def default(obj: Any) -> Any: def _dump_pydantic_models(obj: Any) -> Any: - from langchain_core.messages import AIMessage - from langchain_core.outputs import ChatGeneration - if ( isinstance(obj, ChatGeneration) and isinstance(obj.message, AIMessage) diff --git a/libs/core/langchain_core/messages/base.py b/libs/core/langchain_core/messages/base.py index 8810d1ecf13..4b5b296614b 100644 --- a/libs/core/langchain_core/messages/base.py +++ b/libs/core/langchain_core/messages/base.py @@ -118,7 +118,8 @@ class BaseMessage(Serializable): Returns: A ChatPromptTemplate containing both messages. """ - from langchain_core.prompts.chat import ChatPromptTemplate + # Import locally to prevent circular imports. + from langchain_core.prompts.chat import ChatPromptTemplate # noqa: PLC0415 prompt = ChatPromptTemplate(messages=[self]) return prompt + other diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index 65723ddc3a9..d6971e2ebd0 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -42,12 +42,17 @@ from langchain_core.messages.system import SystemMessage, SystemMessageChunk from langchain_core.messages.tool import ToolCall, ToolMessage, ToolMessageChunk if TYPE_CHECKING: - from langchain_text_splitters import TextSplitter - from langchain_core.language_models import BaseLanguageModel from langchain_core.prompt_values import PromptValue from langchain_core.runnables.base import Runnable +try: + from langchain_text_splitters import TextSplitter + + _HAS_LANGCHAIN_TEXT_SPLITTERS = True +except ImportError: + _HAS_LANGCHAIN_TEXT_SPLITTERS = False + logger = logging.getLogger(__name__) @@ -361,7 +366,7 @@ def convert_to_messages( list of messages (BaseMessages). """ # Import here to avoid circular imports - from langchain_core.prompt_values import PromptValue + from langchain_core.prompt_values import PromptValue # noqa: PLC0415 if isinstance(messages, PromptValue): return messages.to_messages() @@ -386,7 +391,8 @@ def _runnable_support(func: Callable) -> Callable: list[BaseMessage], Runnable[Sequence[MessageLikeRepresentation], list[BaseMessage]], ]: - from langchain_core.runnables.base import RunnableLambda + # Import locally to prevent circular import. + from langchain_core.runnables.base import RunnableLambda # noqa: PLC0415 if messages is not None: return func(messages, **kwargs) @@ -989,17 +995,12 @@ def trim_messages( ) raise ValueError(msg) - try: - from langchain_text_splitters import TextSplitter - except ImportError: - text_splitter_fn: Optional[Callable] = cast("Optional[Callable]", text_splitter) + if _HAS_LANGCHAIN_TEXT_SPLITTERS and isinstance(text_splitter, TextSplitter): + text_splitter_fn = text_splitter.split_text + elif text_splitter: + text_splitter_fn = cast("Callable", text_splitter) else: - if isinstance(text_splitter, TextSplitter): - text_splitter_fn = text_splitter.split_text - else: - text_splitter_fn = text_splitter - - text_splitter_fn = text_splitter_fn or _default_text_splitter + text_splitter_fn = _default_text_splitter if strategy == "first": return _first_max_tokens( diff --git a/libs/core/langchain_core/output_parsers/xml.py b/libs/core/langchain_core/output_parsers/xml.py index 0d7ef8b1e79..be12760fade 100644 --- a/libs/core/langchain_core/output_parsers/xml.py +++ b/libs/core/langchain_core/output_parsers/xml.py @@ -15,6 +15,14 @@ from langchain_core.messages import BaseMessage from langchain_core.output_parsers.transform import BaseTransformOutputParser from langchain_core.runnables.utils import AddableDict +try: + from defusedxml import ElementTree # type: ignore[import-untyped] + from defusedxml.ElementTree import XMLParser # type: ignore[import-untyped] + + _HAS_DEFUSEDXML = True +except ImportError: + _HAS_DEFUSEDXML = False + XML_FORMAT_INSTRUCTIONS = """The output should be formatted as a XML file. 1. Output should conform to the tags below. 2. If tags are not given, make them on your own. @@ -50,17 +58,13 @@ class _StreamingParser: parser is requested. """ if parser == "defusedxml": - try: - from defusedxml.ElementTree import ( # type: ignore[import-untyped] - XMLParser, - ) - except ImportError as e: + if not _HAS_DEFUSEDXML: msg = ( "defusedxml is not installed. " "Please install it to use the defusedxml parser." "You can install it with `pip install defusedxml` " ) - raise ImportError(msg) from e + raise ImportError(msg) parser_ = XMLParser(target=TreeBuilder()) else: parser_ = None @@ -207,16 +211,14 @@ class XMLOutputParser(BaseTransformOutputParser): # Imports are temporarily placed here to avoid issue with caching on CI # likely if you're reading this you can move them to the top of the file if self.parser == "defusedxml": - try: - from defusedxml import ElementTree # type: ignore[import-untyped] - except ImportError as e: + if not _HAS_DEFUSEDXML: msg = ( "defusedxml is not installed. " "Please install it to use the defusedxml parser." "You can install it with `pip install defusedxml`" "See https://github.com/tiran/defusedxml for more details" ) - raise ImportError(msg) from e + raise ImportError(msg) et = ElementTree # Use the defusedxml parser else: et = ET # Use the standard library parser diff --git a/libs/core/langchain_core/prompts/message.py b/libs/core/langchain_core/prompts/message.py index 409f54320b1..b8642a53bca 100644 --- a/libs/core/langchain_core/prompts/message.py +++ b/libs/core/langchain_core/prompts/message.py @@ -88,7 +88,8 @@ class BaseMessagePromptTemplate(Serializable, ABC): Returns: Combined prompt template. """ - from langchain_core.prompts.chat import ChatPromptTemplate + # Import locally to avoid circular import. + from langchain_core.prompts.chat import ChatPromptTemplate # noqa: PLC0415 prompt = ChatPromptTemplate(messages=[self]) return prompt + other diff --git a/libs/core/langchain_core/prompts/string.py b/libs/core/langchain_core/prompts/string.py index b6f1cdae28f..8b147c3c0bc 100644 --- a/libs/core/langchain_core/prompts/string.py +++ b/libs/core/langchain_core/prompts/string.py @@ -15,6 +15,14 @@ from langchain_core.utils import get_colored_text, mustache from langchain_core.utils.formatting import formatter from langchain_core.utils.interactive_env import is_interactive_env +try: + from jinja2 import Environment, meta + from jinja2.sandbox import SandboxedEnvironment + + _HAS_JINJA2 = True +except ImportError: + _HAS_JINJA2 = False + PromptTemplateFormat = Literal["f-string", "mustache", "jinja2"] @@ -40,9 +48,7 @@ def jinja2_formatter(template: str, /, **kwargs: Any) -> str: Raises: ImportError: If jinja2 is not installed. """ - try: - from jinja2.sandbox import SandboxedEnvironment - except ImportError as e: + if not _HAS_JINJA2: msg = ( "jinja2 not installed, which is needed to use the jinja2_formatter. " "Please install it with `pip install jinja2`." @@ -50,7 +56,7 @@ def jinja2_formatter(template: str, /, **kwargs: Any) -> str: "Do not expand jinja2 templates using unverified or user-controlled " "inputs as that can result in arbitrary Python code execution." ) - raise ImportError(msg) from e + raise ImportError(msg) # This uses a sandboxed environment to prevent arbitrary code execution. # Jinja2 uses an opt-out rather than opt-in approach for sand-boxing. @@ -88,14 +94,12 @@ def validate_jinja2(template: str, input_variables: list[str]) -> None: def _get_jinja2_variables_from_template(template: str) -> set[str]: - try: - from jinja2 import Environment, meta - except ImportError as e: + if not _HAS_JINJA2: msg = ( "jinja2 not installed, which is needed to use the jinja2_formatter. " "Please install it with `pip install jinja2`." ) - raise ImportError(msg) from e + raise ImportError(msg) env = Environment() # noqa: S701 ast = env.parse(template) return meta.find_undeclared_variables(ast) diff --git a/libs/core/langchain_core/retrievers.py b/libs/core/langchain_core/retrievers.py index 8e1acf56c16..c015747f138 100644 --- a/libs/core/langchain_core/retrievers.py +++ b/libs/core/langchain_core/retrievers.py @@ -31,6 +31,7 @@ from typing_extensions import Self, TypedDict, override from langchain_core._api import deprecated from langchain_core.callbacks import Callbacks +from langchain_core.callbacks.manager import AsyncCallbackManager, CallbackManager from langchain_core.documents import Document from langchain_core.runnables import ( Runnable, @@ -236,8 +237,6 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC): retriever.invoke("query") """ - from langchain_core.callbacks.manager import CallbackManager - config = ensure_config(config) inheritable_metadata = { **(config.get("metadata") or {}), @@ -301,8 +300,6 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC): await retriever.ainvoke("query") """ - from langchain_core.callbacks.manager import AsyncCallbackManager - config = ensure_config(config) inheritable_metadata = { **(config.get("metadata") or {}), diff --git a/libs/core/langchain_core/runnables/base.py b/libs/core/langchain_core/runnables/base.py index 1f90b2f608c..74f2a9049a2 100644 --- a/libs/core/langchain_core/runnables/base.py +++ b/libs/core/langchain_core/runnables/base.py @@ -41,6 +41,7 @@ from pydantic import BaseModel, ConfigDict, Field, RootModel from typing_extensions import Literal, get_args, override from langchain_core._api import beta_decorator +from langchain_core.callbacks.manager import AsyncCallbackManager, CallbackManager from langchain_core.load.serializable import ( Serializable, SerializedConstructor, @@ -60,7 +61,6 @@ from langchain_core.runnables.config import ( run_in_executor, set_config_context, ) -from langchain_core.runnables.graph import Graph from langchain_core.runnables.utils import ( AddableDict, AnyConfigurableField, @@ -81,6 +81,19 @@ from langchain_core.runnables.utils import ( is_async_callable, is_async_generator, ) +from langchain_core.tracers._streaming import _StreamingCallbackHandler +from langchain_core.tracers.event_stream import ( + _astream_events_implementation_v1, + _astream_events_implementation_v2, +) +from langchain_core.tracers.log_stream import ( + LogStreamCallbackHandler, + _astream_log_implementation, +) +from langchain_core.tracers.root_listeners import ( + AsyncRootListenersTracer, + RootListenersTracer, +) from langchain_core.utils.aiter import aclosing, atee, py_anext from langchain_core.utils.iter import safetee from langchain_core.utils.pydantic import create_model_v2 @@ -94,6 +107,7 @@ if TYPE_CHECKING: from langchain_core.runnables.fallbacks import ( RunnableWithFallbacks as RunnableWithFallbacksT, ) + from langchain_core.runnables.graph import Graph from langchain_core.runnables.retry import ExponentialJitterParams from langchain_core.runnables.schema import StreamEvent from langchain_core.tools import BaseTool @@ -565,6 +579,9 @@ class Runnable(ABC, Generic[Input, Output]): def get_graph(self, config: Optional[RunnableConfig] = None) -> Graph: """Return a graph representation of this ``Runnable``.""" + # Import locally to prevent circular import + from langchain_core.runnables.graph import Graph # noqa: PLC0415 + graph = Graph() try: input_node = graph.add_node(self.get_input_schema(config)) @@ -585,7 +602,8 @@ class Runnable(ABC, Generic[Input, Output]): self, config: Optional[RunnableConfig] = None ) -> list[BasePromptTemplate]: """Return a list of prompts used by this ``Runnable``.""" - from langchain_core.prompts.base import BasePromptTemplate + # Import locally to prevent circular import + from langchain_core.prompts.base import BasePromptTemplate # noqa: PLC0415 return [ node.data @@ -747,7 +765,8 @@ class Runnable(ABC, Generic[Input, Output]): a new ``Runnable``. """ - from langchain_core.runnables.passthrough import RunnablePick + # Import locally to prevent circular import + from langchain_core.runnables.passthrough import RunnablePick # noqa: PLC0415 return self | RunnablePick(keys) @@ -798,7 +817,8 @@ class Runnable(ABC, Generic[Input, Output]): A new ``Runnable``. """ - from langchain_core.runnables.passthrough import RunnableAssign + # Import locally to prevent circular import + from langchain_core.runnables.passthrough import RunnableAssign # noqa: PLC0415 return self | RunnableAssign(RunnableParallel[dict[str, Any]](kwargs)) @@ -1231,11 +1251,6 @@ class Runnable(ABC, Generic[Input, Output]): A ``RunLogPatch`` or ``RunLog`` object. """ - from langchain_core.tracers.log_stream import ( - LogStreamCallbackHandler, - _astream_log_implementation, - ) - stream = LogStreamCallbackHandler( auto_close=False, include_names=include_names, @@ -1489,11 +1504,6 @@ class Runnable(ABC, Generic[Input, Output]): NotImplementedError: If the version is not ``'v1'`` or ``'v2'``. """ # noqa: E501 - from langchain_core.tracers.event_stream import ( - _astream_events_implementation_v1, - _astream_events_implementation_v2, - ) - if version == "v2": event_stream = _astream_events_implementation_v2( self, @@ -1740,8 +1750,6 @@ class Runnable(ABC, Generic[Input, Output]): chain.invoke(2) """ - from langchain_core.tracers.root_listeners import RootListenersTracer - return RunnableBinding( bound=self, config_factories=[ @@ -1834,8 +1842,6 @@ class Runnable(ABC, Generic[Input, Output]): on end callback ends at 2025-03-01T07:05:30.884831+00:00 """ - from langchain_core.tracers.root_listeners import AsyncRootListenersTracer - return RunnableBinding( bound=self, config_factories=[ @@ -1928,7 +1934,8 @@ class Runnable(ABC, Generic[Input, Output]): assert count == 2 """ - from langchain_core.runnables.retry import RunnableRetry + # Import locally to prevent circular import + from langchain_core.runnables.retry import RunnableRetry # noqa: PLC0415 return RunnableRetry( bound=self, @@ -2030,7 +2037,10 @@ class Runnable(ABC, Generic[Input, Output]): fallback in order, upon failures. """ - from langchain_core.runnables.fallbacks import RunnableWithFallbacks + # Import locally to prevent circular import + from langchain_core.runnables.fallbacks import ( # noqa: PLC0415 + RunnableWithFallbacks, + ) return RunnableWithFallbacks( runnable=self, @@ -2316,9 +2326,6 @@ class Runnable(ABC, Generic[Input, Output]): Use this to implement ``stream`` or ``transform`` in ``Runnable`` subclasses. """ - # Mixin that is used by both astream log and astream events implementation - from langchain_core.tracers._streaming import _StreamingCallbackHandler - # tee the input so we can iterate over it twice input_for_tracing, input_for_transform = tee(inputs, 2) # Start the input iterator to ensure the input Runnable starts before this one @@ -2422,9 +2429,6 @@ class Runnable(ABC, Generic[Input, Output]): Use this to implement ``astream`` or ``atransform`` in ``Runnable`` subclasses. """ - # Mixin that is used by both astream log and astream events implementation - from langchain_core.tracers._streaming import _StreamingCallbackHandler - # tee the input so we can iterate over it twice input_for_tracing, input_for_transform = atee(inputs, 2) # Start the input iterator to ensure the input Runnable starts before this one @@ -2614,7 +2618,7 @@ class Runnable(ABC, Generic[Input, Output]): """ # Avoid circular import - from langchain_core.tools import convert_runnable_to_tool + from langchain_core.tools import convert_runnable_to_tool # noqa: PLC0415 return convert_runnable_to_tool( self, @@ -2690,7 +2694,10 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): ) """ - from langchain_core.runnables.configurable import RunnableConfigurableFields + # Import locally to prevent circular import + from langchain_core.runnables.configurable import ( # noqa: PLC0415 + RunnableConfigurableFields, + ) model_fields = type(self).model_fields for key in kwargs: @@ -2751,7 +2758,8 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): ) """ - from langchain_core.runnables.configurable import ( + # Import locally to prevent circular import + from langchain_core.runnables.configurable import ( # noqa: PLC0415 RunnableConfigurableAlternatives, ) @@ -2767,7 +2775,11 @@ class RunnableSerializable(Serializable, Runnable[Input, Output]): def _seq_input_schema( steps: list[Runnable[Any, Any]], config: Optional[RunnableConfig] ) -> type[BaseModel]: - from langchain_core.runnables.passthrough import RunnableAssign, RunnablePick + # Import locally to prevent circular import + from langchain_core.runnables.passthrough import ( # noqa: PLC0415 + RunnableAssign, + RunnablePick, + ) first = steps[0] if len(steps) == 1: @@ -2793,7 +2805,11 @@ def _seq_input_schema( def _seq_output_schema( steps: list[Runnable[Any, Any]], config: Optional[RunnableConfig] ) -> type[BaseModel]: - from langchain_core.runnables.passthrough import RunnableAssign, RunnablePick + # Import locally to prevent circular import + from langchain_core.runnables.passthrough import ( # noqa: PLC0415 + RunnableAssign, + RunnablePick, + ) last = steps[-1] if len(steps) == 1: @@ -3050,7 +3066,8 @@ class RunnableSequence(RunnableSerializable[Input, Output]): The config specs of the ``Runnable``. """ - from langchain_core.beta.runnables.context import ( + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 CONTEXT_CONFIG_PREFIX, _key_from_id, ) @@ -3108,7 +3125,8 @@ class RunnableSequence(RunnableSerializable[Input, Output]): ValueError: If a ``Runnable`` has no first or last node. """ - from langchain_core.runnables.graph import Graph + # Import locally to prevent circular import + from langchain_core.runnables.graph import Graph # noqa: PLC0415 graph = Graph() for step in self.steps: @@ -3196,7 +3214,10 @@ class RunnableSequence(RunnableSerializable[Input, Output]): def invoke( self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any ) -> Output: - from langchain_core.beta.runnables.context import config_with_context + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 + config_with_context, + ) # setup callbacks and context config = config_with_context(ensure_config(config), self.steps) @@ -3237,7 +3258,10 @@ class RunnableSequence(RunnableSerializable[Input, Output]): config: Optional[RunnableConfig] = None, **kwargs: Optional[Any], ) -> Output: - from langchain_core.beta.runnables.context import aconfig_with_context + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 + aconfig_with_context, + ) # setup callbacks and context config = aconfig_with_context(ensure_config(config), self.steps) @@ -3281,8 +3305,10 @@ class RunnableSequence(RunnableSerializable[Input, Output]): return_exceptions: bool = False, **kwargs: Optional[Any], ) -> list[Output]: - from langchain_core.beta.runnables.context import config_with_context - from langchain_core.callbacks.manager import CallbackManager + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 + config_with_context, + ) if not inputs: return [] @@ -3411,8 +3437,10 @@ class RunnableSequence(RunnableSerializable[Input, Output]): return_exceptions: bool = False, **kwargs: Optional[Any], ) -> list[Output]: - from langchain_core.beta.runnables.context import aconfig_with_context - from langchain_core.callbacks.manager import AsyncCallbackManager + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 + aconfig_with_context, + ) if not inputs: return [] @@ -3542,7 +3570,10 @@ class RunnableSequence(RunnableSerializable[Input, Output]): config: RunnableConfig, **kwargs: Any, ) -> Iterator[Output]: - from langchain_core.beta.runnables.context import config_with_context + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 + config_with_context, + ) steps = [self.first, *self.middle, self.last] config = config_with_context(config, self.steps) @@ -3569,7 +3600,10 @@ class RunnableSequence(RunnableSerializable[Input, Output]): config: RunnableConfig, **kwargs: Any, ) -> AsyncIterator[Output]: - from langchain_core.beta.runnables.context import aconfig_with_context + # Import locally to prevent circular import + from langchain_core.beta.runnables.context import ( # noqa: PLC0415 + aconfig_with_context, + ) steps = [self.first, *self.middle, self.last] config = aconfig_with_context(config, self.steps) @@ -3882,7 +3916,8 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]): ValueError: If a ``Runnable`` has no first or last node. """ - from langchain_core.runnables.graph import Graph + # Import locally to prevent circular import + from langchain_core.runnables.graph import Graph # noqa: PLC0415 graph = Graph() input_node = graph.add_node(self.get_input_schema(config)) @@ -3918,8 +3953,6 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]): def invoke( self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any ) -> dict[str, Any]: - from langchain_core.callbacks.manager import CallbackManager - # setup callbacks config = ensure_config(config) callback_manager = CallbackManager.configure( @@ -4767,6 +4800,9 @@ class RunnableLambda(Runnable[Input, Output]): @override def get_graph(self, config: RunnableConfig | None = None) -> Graph: if deps := self.deps: + # Import locally to prevent circular import + from langchain_core.runnables.graph import Graph # noqa: PLC0415 + graph = Graph() input_node = graph.add_node(self.get_input_schema(config)) output_node = graph.add_node(self.get_output_schema(config)) @@ -6030,7 +6066,6 @@ class RunnableBinding(RunnableBindingBase[Input, Output]): # type: ignore[no-re Returns: A new ``Runnable`` with the listeners bound. """ - from langchain_core.tracers.root_listeners import RootListenersTracer def listener_config_factory(config: RunnableConfig) -> RunnableConfig: return { diff --git a/libs/core/langchain_core/runnables/branch.py b/libs/core/langchain_core/runnables/branch.py index ed8d0ed0cdd..66ecb9592c8 100644 --- a/libs/core/langchain_core/runnables/branch.py +++ b/libs/core/langchain_core/runnables/branch.py @@ -12,6 +12,10 @@ from typing import ( from pydantic import BaseModel, ConfigDict from typing_extensions import override +from langchain_core.beta.runnables.context import ( + CONTEXT_CONFIG_PREFIX, + CONTEXT_CONFIG_SUFFIX_SET, +) from langchain_core.runnables.base import ( Runnable, RunnableLike, @@ -177,11 +181,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]): @property @override def config_specs(self) -> list[ConfigurableFieldSpec]: - from langchain_core.beta.runnables.context import ( - CONTEXT_CONFIG_PREFIX, - CONTEXT_CONFIG_SUFFIX_SET, - ) - specs = get_unique_config_specs( spec for step in ( diff --git a/libs/core/langchain_core/runnables/config.py b/libs/core/langchain_core/runnables/config.py index 98090872a34..041d1d2629e 100644 --- a/libs/core/langchain_core/runnables/config.py +++ b/libs/core/langchain_core/runnables/config.py @@ -12,21 +12,22 @@ from contextvars import Context, ContextVar, Token, copy_context from functools import partial from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union, cast +from langsmith.run_helpers import _set_tracing_context, get_tracing_context from typing_extensions import ParamSpec, TypedDict +from langchain_core.callbacks.manager import AsyncCallbackManager, CallbackManager from langchain_core.runnables.utils import ( Input, Output, accepts_config, accepts_run_manager, ) +from langchain_core.tracers.langchain import LangChainTracer if TYPE_CHECKING: from langchain_core.callbacks.base import BaseCallbackManager, Callbacks from langchain_core.callbacks.manager import ( - AsyncCallbackManager, AsyncCallbackManagerForChainRun, - CallbackManager, CallbackManagerForChainRun, ) else: @@ -129,8 +130,6 @@ def _set_config_context( Returns: The token to reset the config and the previous tracing context. """ - from langchain_core.tracers.langchain import LangChainTracer - config_token = var_child_runnable_config.set(config) current_context = None if ( @@ -150,8 +149,6 @@ def _set_config_context( ) and (run := tracer.run_map.get(str(parent_run_id))) ): - from langsmith.run_helpers import _set_tracing_context, get_tracing_context - current_context = get_tracing_context() _set_tracing_context({"parent": run}) return config_token, current_context @@ -167,8 +164,6 @@ def set_config_context(config: RunnableConfig) -> Generator[Context, None, None] Yields: The config context. """ - from langsmith.run_helpers import _set_tracing_context - ctx = copy_context() config_token, _ = ctx.run(_set_config_context, config) try: @@ -481,8 +476,6 @@ def get_callback_manager_for_config(config: RunnableConfig) -> CallbackManager: Returns: CallbackManager: The callback manager. """ - from langchain_core.callbacks.manager import CallbackManager - return CallbackManager.configure( inheritable_callbacks=config.get("callbacks"), inheritable_tags=config.get("tags"), @@ -501,8 +494,6 @@ def get_async_callback_manager_for_config( Returns: AsyncCallbackManager: The async callback manager. """ - from langchain_core.callbacks.manager import AsyncCallbackManager - return AsyncCallbackManager.configure( inheritable_callbacks=config.get("callbacks"), inheritable_tags=config.get("tags"), diff --git a/libs/core/langchain_core/runnables/fallbacks.py b/libs/core/langchain_core/runnables/fallbacks.py index ede6fcb572d..f72850f3413 100644 --- a/libs/core/langchain_core/runnables/fallbacks.py +++ b/libs/core/langchain_core/runnables/fallbacks.py @@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Any, Optional, Union, cast from pydantic import BaseModel, ConfigDict from typing_extensions import override +from langchain_core.callbacks.manager import AsyncCallbackManager, CallbackManager from langchain_core.runnables.base import Runnable, RunnableSerializable from langchain_core.runnables.config import ( RunnableConfig, @@ -272,8 +273,6 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): return_exceptions: bool = False, **kwargs: Optional[Any], ) -> list[Output]: - from langchain_core.callbacks.manager import CallbackManager - if self.exception_key is not None and not all( isinstance(input_, dict) for input_ in inputs ): @@ -366,8 +365,6 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): return_exceptions: bool = False, **kwargs: Optional[Any], ) -> list[Output]: - from langchain_core.callbacks.manager import AsyncCallbackManager - if self.exception_key is not None and not all( isinstance(input_, dict) for input_ in inputs ): diff --git a/libs/core/langchain_core/runnables/graph.py b/libs/core/langchain_core/runnables/graph.py index 389572a23b3..cebf2a667c1 100644 --- a/libs/core/langchain_core/runnables/graph.py +++ b/libs/core/langchain_core/runnables/graph.py @@ -19,6 +19,8 @@ from typing import ( ) from uuid import UUID, uuid4 +from langchain_core.load.serializable import to_json_not_implemented +from langchain_core.runnables.base import Runnable, RunnableSerializable from langchain_core.utils.pydantic import _IgnoreUnserializable, is_basemodel_subclass if TYPE_CHECKING: @@ -191,8 +193,6 @@ def node_data_str( Returns: A string representation of the data. """ - from langchain_core.runnables.base import Runnable - if not is_uuid(id) or data is None: return id data_str = data.get_name() if isinstance(data, Runnable) else data.__name__ @@ -212,9 +212,6 @@ def node_data_json( Returns: A dictionary with the type of the data and the data itself. """ - from langchain_core.load.serializable import to_json_not_implemented - from langchain_core.runnables.base import Runnable, RunnableSerializable - if node.data is None: json: dict[str, Any] = {} elif isinstance(node.data, RunnableSerializable): @@ -518,7 +515,8 @@ class Graph: Returns: The ASCII art string. """ - from langchain_core.runnables.graph_ascii import draw_ascii + # Import locally to prevent circular import + from langchain_core.runnables.graph_ascii import draw_ascii # noqa: PLC0415 return draw_ascii( {node.id: node.name for node in self.nodes.values()}, @@ -562,7 +560,8 @@ class Graph: Returns: The PNG image as bytes if output_file_path is None, None otherwise. """ - from langchain_core.runnables.graph_png import PngDrawer + # Import locally to prevent circular import + from langchain_core.runnables.graph_png import PngDrawer # noqa: PLC0415 default_node_labels = {node.id: node.name for node in self.nodes.values()} @@ -617,7 +616,8 @@ class Graph: The Mermaid syntax string. """ - from langchain_core.runnables.graph_mermaid import draw_mermaid + # Import locally to prevent circular import + from langchain_core.runnables.graph_mermaid import draw_mermaid # noqa: PLC0415 graph = self.reid() first_node = graph.first_node() @@ -688,7 +688,10 @@ class Graph: The PNG image as bytes. """ - from langchain_core.runnables.graph_mermaid import draw_mermaid_png + # Import locally to prevent circular import + from langchain_core.runnables.graph_mermaid import ( # noqa: PLC0415 + draw_mermaid_png, + ) mermaid_syntax = self.draw_mermaid( curve_style=curve_style, diff --git a/libs/core/langchain_core/runnables/graph_ascii.py b/libs/core/langchain_core/runnables/graph_ascii.py index 9c11c585cd1..39ad3f165e6 100644 --- a/libs/core/langchain_core/runnables/graph_ascii.py +++ b/libs/core/langchain_core/runnables/graph_ascii.py @@ -3,12 +3,24 @@ Adapted from https://github.com/iterative/dvc/blob/main/dvc/dagascii.py. """ +from __future__ import annotations + import math import os from collections.abc import Mapping, Sequence -from typing import Any +from typing import TYPE_CHECKING, Any -from langchain_core.runnables.graph import Edge as LangEdge +try: + from grandalf.graphs import Edge, Graph, Vertex # type: ignore[import-untyped] + from grandalf.layouts import SugiyamaLayout # type: ignore[import-untyped] + from grandalf.routing import route_with_lines # type: ignore[import-untyped] + + _HAS_GRANDALF = True +except ImportError: + _HAS_GRANDALF = False + +if TYPE_CHECKING: + from langchain_core.runnables.graph import Edge as LangEdge class VertexViewer: @@ -185,13 +197,9 @@ class _EdgeViewer: def _build_sugiyama_layout( vertices: Mapping[str, str], edges: Sequence[LangEdge] ) -> Any: - try: - from grandalf.graphs import Edge, Graph, Vertex # type: ignore[import-untyped] - from grandalf.layouts import SugiyamaLayout # type: ignore[import-untyped] - from grandalf.routing import route_with_lines # type: ignore[import-untyped] - except ImportError as exc: + if not _HAS_GRANDALF: msg = "Install grandalf to draw graphs: `pip install grandalf`." - raise ImportError(msg) from exc + raise ImportError(msg) # # Just a reminder about naming conventions: diff --git a/libs/core/langchain_core/runnables/graph_mermaid.py b/libs/core/langchain_core/runnables/graph_mermaid.py index 17ebc55a518..df1468fc437 100644 --- a/libs/core/langchain_core/runnables/graph_mermaid.py +++ b/libs/core/langchain_core/runnables/graph_mermaid.py @@ -1,5 +1,7 @@ """Mermaid graph drawing utilities.""" +from __future__ import annotations + import asyncio import base64 import random @@ -7,18 +9,34 @@ import re import time from dataclasses import asdict from pathlib import Path -from typing import Any, Literal, Optional +from typing import TYPE_CHECKING, Any, Literal, Optional import yaml from langchain_core.runnables.graph import ( CurveStyle, - Edge, MermaidDrawMethod, - Node, NodeStyles, ) +if TYPE_CHECKING: + from langchain_core.runnables.graph import Edge, Node + + +try: + import requests + + _HAS_REQUESTS = True +except ImportError: + _HAS_REQUESTS = False + +try: + from pyppeteer import launch # type: ignore[import-not-found] + + _HAS_PYPPETEER = True +except ImportError: + _HAS_PYPPETEER = False + MARKDOWN_SPECIAL_CHARS = "*_`" @@ -283,8 +301,6 @@ def draw_mermaid_png( ValueError: If an invalid draw method is provided. """ if draw_method == MermaidDrawMethod.PYPPETEER: - import asyncio - img_bytes = asyncio.run( _render_mermaid_using_pyppeteer( mermaid_syntax, output_file_path, background_color, padding @@ -317,11 +333,9 @@ async def _render_mermaid_using_pyppeteer( device_scale_factor: int = 3, ) -> bytes: """Renders Mermaid graph using Pyppeteer.""" - try: - from pyppeteer import launch # type: ignore[import-not-found] - except ImportError as e: + if not _HAS_PYPPETEER: msg = "Install Pyppeteer to use the Pyppeteer method: `pip install pyppeteer`." - raise ImportError(msg) from e + raise ImportError(msg) browser = await launch() page = await browser.newPage() @@ -392,14 +406,12 @@ def _render_mermaid_using_api( retry_delay: float = 1.0, ) -> bytes: """Renders Mermaid graph using the Mermaid.INK API.""" - try: - import requests - except ImportError as e: + if not _HAS_REQUESTS: msg = ( "Install the `requests` module to use the Mermaid.INK API: " "`pip install requests`." ) - raise ImportError(msg) from e + raise ImportError(msg) # Use Mermaid API to render the image mermaid_syntax_encoded = base64.b64encode(mermaid_syntax.encode("utf8")).decode( diff --git a/libs/core/langchain_core/runnables/graph_png.py b/libs/core/langchain_core/runnables/graph_png.py index 27162907843..154f8e3ab44 100644 --- a/libs/core/langchain_core/runnables/graph_png.py +++ b/libs/core/langchain_core/runnables/graph_png.py @@ -4,6 +4,13 @@ from typing import Any, Optional from langchain_core.runnables.graph import Graph, LabelsDict +try: + import pygraphviz as pgv # type: ignore[import-not-found] + + _HAS_PYGRAPHVIZ = True +except ImportError: + _HAS_PYGRAPHVIZ = False + class PngDrawer: """Helper class to draw a state graph into a PNG file. @@ -125,11 +132,9 @@ class PngDrawer: Returns: The PNG bytes if ``output_path`` is None, else None. """ - try: - import pygraphviz as pgv # type: ignore[import-not-found] - except ImportError as exc: + if not _HAS_PYGRAPHVIZ: msg = "Install pygraphviz to draw graphs: `pip install pygraphviz`." - raise ImportError(msg) from exc + raise ImportError(msg) # Create a directed graph viz = pgv.AGraph(directed=True, nodesep=0.9, ranksep=1.0) diff --git a/libs/core/langchain_core/runnables/history.py b/libs/core/langchain_core/runnables/history.py index 24bfe22df0e..19158607bad 100644 --- a/libs/core/langchain_core/runnables/history.py +++ b/libs/core/langchain_core/runnables/history.py @@ -18,6 +18,7 @@ from typing_extensions import override from langchain_core.chat_history import BaseChatMessageHistory from langchain_core.load.load import load +from langchain_core.messages import AIMessage, BaseMessage, HumanMessage from langchain_core.runnables.base import Runnable, RunnableBindingBase, RunnableLambda from langchain_core.runnables.passthrough import RunnablePassthrough from langchain_core.runnables.utils import ( @@ -29,7 +30,6 @@ from langchain_core.utils.pydantic import create_model_v2 if TYPE_CHECKING: from langchain_core.language_models.base import LanguageModelLike - from langchain_core.messages.base import BaseMessage from langchain_core.runnables.config import RunnableConfig from langchain_core.tracers.schemas import Run @@ -384,8 +384,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] def get_input_schema( self, config: Optional[RunnableConfig] = None ) -> type[BaseModel]: - from langchain_core.messages import BaseMessage - fields: dict = {} if self.input_messages_key and self.history_messages_key: fields[self.input_messages_key] = ( @@ -447,8 +445,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] def _get_input_messages( self, input_val: Union[str, BaseMessage, Sequence[BaseMessage], dict] ) -> list[BaseMessage]: - from langchain_core.messages import BaseMessage - # If dictionary, try to pluck the single key representing messages if isinstance(input_val, dict): if self.input_messages_key: @@ -461,8 +457,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] # If value is a string, convert to a human message if isinstance(input_val, str): - from langchain_core.messages import HumanMessage - return [HumanMessage(content=input_val)] # If value is a single message, convert to a list if isinstance(input_val, BaseMessage): @@ -489,8 +483,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] def _get_output_messages( self, output_val: Union[str, BaseMessage, Sequence[BaseMessage], dict] ) -> list[BaseMessage]: - from langchain_core.messages import BaseMessage - # If dictionary, try to pluck the single key representing messages if isinstance(output_val, dict): if self.output_messages_key: @@ -507,8 +499,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] output_val = output_val[key] if isinstance(output_val, str): - from langchain_core.messages import AIMessage - return [AIMessage(content=output_val)] # If value is a single message, convert to a list if isinstance(output_val, BaseMessage): diff --git a/libs/core/langchain_core/sys_info.py b/libs/core/langchain_core/sys_info.py index b7073ffb9cd..dcd0a178bf3 100644 --- a/libs/core/langchain_core/sys_info.py +++ b/libs/core/langchain_core/sys_info.py @@ -4,13 +4,15 @@ sys_info prints information about the system and langchain packages for debugging purposes. """ +import pkgutil +import platform +import sys from collections.abc import Sequence +from importlib import metadata, util def _get_sub_deps(packages: Sequence[str]) -> list[str]: """Get any specified sub-dependencies.""" - from importlib import metadata - sub_deps = set() underscored_packages = {pkg.replace("-", "_") for pkg in packages} @@ -37,11 +39,6 @@ def print_sys_info(*, additional_pkgs: Sequence[str] = ()) -> None: Args: additional_pkgs: Additional packages to include in the output. """ - import pkgutil - import platform - import sys - from importlib import metadata, util - # Packages that do not start with "langchain" prefix. other_langchain_packages = [ "langserve", diff --git a/libs/core/langchain_core/tracers/event_stream.py b/libs/core/langchain_core/tracers/event_stream.py index 5b150604516..61c3549cfb7 100644 --- a/libs/core/langchain_core/tracers/event_stream.py +++ b/libs/core/langchain_core/tracers/event_stream.py @@ -18,13 +18,14 @@ from uuid import UUID, uuid4 from typing_extensions import NotRequired, override -from langchain_core.callbacks.base import AsyncCallbackHandler +from langchain_core.callbacks.base import AsyncCallbackHandler, BaseCallbackManager from langchain_core.messages import AIMessageChunk, BaseMessage, BaseMessageChunk from langchain_core.outputs import ( ChatGenerationChunk, GenerationChunk, LLMResult, ) +from langchain_core.runnables import ensure_config from langchain_core.runnables.schema import ( CustomStreamEvent, EventData, @@ -37,6 +38,11 @@ from langchain_core.runnables.utils import ( _RootEventFilter, ) from langchain_core.tracers._streaming import _StreamingCallbackHandler +from langchain_core.tracers.log_stream import ( + LogStreamCallbackHandler, + RunLog, + _astream_log_implementation, +) from langchain_core.tracers.memory_stream import _MemoryStream from langchain_core.utils.aiter import aclosing, py_anext @@ -769,14 +775,6 @@ async def _astream_events_implementation_v1( exclude_tags: Optional[Sequence[str]] = None, **kwargs: Any, ) -> AsyncIterator[StandardStreamEvent]: - from langchain_core.runnables import ensure_config - from langchain_core.runnables.utils import _RootEventFilter - from langchain_core.tracers.log_stream import ( - LogStreamCallbackHandler, - RunLog, - _astream_log_implementation, - ) - stream = LogStreamCallbackHandler( auto_close=False, include_names=include_names, @@ -954,9 +952,6 @@ async def _astream_events_implementation_v2( **kwargs: Any, ) -> AsyncIterator[StandardStreamEvent]: """Implementation of the astream events API for V2 runnables.""" - from langchain_core.callbacks.base import BaseCallbackManager - from langchain_core.runnables import ensure_config - event_streamer = _AstreamEventsCallbackHandler( include_names=include_names, include_types=include_types, diff --git a/libs/core/langchain_core/tracers/log_stream.py b/libs/core/langchain_core/tracers/log_stream.py index 2821ade0dc5..923f0275683 100644 --- a/libs/core/langchain_core/tracers/log_stream.py +++ b/libs/core/langchain_core/tracers/log_stream.py @@ -7,6 +7,7 @@ import contextlib import copy import threading from collections import defaultdict +from pprint import pformat from typing import ( TYPE_CHECKING, Any, @@ -20,10 +21,11 @@ from typing import ( import jsonpatch # type: ignore[import-untyped] from typing_extensions import NotRequired, TypedDict, override +from langchain_core.callbacks.base import BaseCallbackManager from langchain_core.load import dumps from langchain_core.load.load import load from langchain_core.outputs import ChatGenerationChunk, GenerationChunk -from langchain_core.runnables import Runnable, RunnableConfig, ensure_config +from langchain_core.runnables import RunnableConfig, ensure_config from langchain_core.tracers._streaming import _StreamingCallbackHandler from langchain_core.tracers.base import BaseTracer from langchain_core.tracers.memory_stream import _MemoryStream @@ -32,6 +34,7 @@ if TYPE_CHECKING: from collections.abc import AsyncIterator, Iterator, Sequence from uuid import UUID + from langchain_core.runnables import Runnable from langchain_core.runnables.utils import Input, Output from langchain_core.tracers.schemas import Run @@ -131,8 +134,6 @@ class RunLogPatch: @override def __repr__(self) -> str: - from pprint import pformat - # 1:-1 to get rid of the [] around the list return f"RunLogPatch({pformat(self.ops)[1:-1]})" @@ -181,8 +182,6 @@ class RunLog(RunLogPatch): @override def __repr__(self) -> str: - from pprint import pformat - return f"RunLog({pformat(self.state)})" @override @@ -672,14 +671,6 @@ async def _astream_log_implementation( Yields: The run log patches or states, depending on the value of ``diff``. """ - import jsonpatch - - from langchain_core.callbacks.base import BaseCallbackManager - from langchain_core.tracers.log_stream import ( - RunLog, - RunLogPatch, - ) - # Assign the stream handler to the config config = ensure_config(config) callbacks = config.get("callbacks") diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index fff700651ea..801aacc727a 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -21,8 +21,10 @@ from typing import ( from pydantic import BaseModel from pydantic.v1 import BaseModel as BaseModelV1 +from pydantic.v1 import Field, create_model from typing_extensions import TypedDict, get_args, get_origin, is_typeddict +import langchain_core from langchain_core._api import beta, deprecated from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, ToolMessage from langchain_core.utils.json_schema import dereference_refs @@ -220,10 +222,8 @@ def _convert_python_function_to_openai_function( Returns: The OpenAI function description. """ - from langchain_core.tools.base import create_schema_from_function - func_name = _get_python_function_name(function) - model = create_schema_from_function( + model = langchain_core.tools.base.create_schema_from_function( func_name, function, filter_args=(), @@ -264,9 +264,6 @@ def _convert_any_typed_dicts_to_pydantic( visited: dict, depth: int = 0, ) -> type: - from pydantic.v1 import Field as Field_v1 - from pydantic.v1 import create_model as create_model_v1 - if type_ in visited: return visited[type_] if depth >= _MAX_TYPED_DICT_RECURSION: @@ -297,7 +294,7 @@ def _convert_any_typed_dicts_to_pydantic( raise ValueError(msg) if arg_desc := arg_descriptions.get(arg): field_kwargs["description"] = arg_desc - fields[arg] = (new_arg_type, Field_v1(**field_kwargs)) + fields[arg] = (new_arg_type, Field(**field_kwargs)) else: new_arg_type = _convert_any_typed_dicts_to_pydantic( arg_type, depth=depth + 1, visited=visited @@ -305,8 +302,8 @@ def _convert_any_typed_dicts_to_pydantic( field_kwargs = {"default": ...} if arg_desc := arg_descriptions.get(arg): field_kwargs["description"] = arg_desc - fields[arg] = (new_arg_type, Field_v1(**field_kwargs)) - model = create_model_v1(typed_dict.__name__, **fields) + fields[arg] = (new_arg_type, Field(**field_kwargs)) + model = create_model(typed_dict.__name__, **fields) model.__doc__ = description visited[typed_dict] = model return model @@ -332,9 +329,9 @@ def _format_tool_to_openai_function(tool: BaseTool) -> FunctionDescription: Returns: The function description. """ - from langchain_core.tools import simple - - is_simple_oai_tool = isinstance(tool, simple.Tool) and not tool.args_schema + is_simple_oai_tool = ( + isinstance(tool, langchain_core.tools.simple.Tool) and not tool.args_schema + ) if tool.tool_call_schema and not is_simple_oai_tool: if isinstance(tool.tool_call_schema, dict): return _convert_json_schema_to_openai_function( @@ -435,8 +432,6 @@ def convert_to_openai_function( 'description' and 'parameters' keys are now optional. Only 'name' is required and guaranteed to be part of the output. """ - from langchain_core.tools import BaseTool - # an Anthropic format tool if isinstance(function, dict) and all( k in function for k in ("name", "input_schema") @@ -476,7 +471,7 @@ def convert_to_openai_function( oai_function = cast( "dict", _convert_typed_dict_to_openai_function(cast("type", function)) ) - elif isinstance(function, BaseTool): + elif isinstance(function, langchain_core.tools.base.BaseTool): oai_function = cast("dict", _format_tool_to_openai_function(function)) elif callable(function): oai_function = cast( @@ -582,7 +577,8 @@ def convert_to_openai_tool( Added support for OpenAI's image generation built-in tool. """ - from langchain_core.tools import Tool + # Import locally to prevent circular import + from langchain_core.tools import Tool # noqa: PLC0415 if isinstance(tool, dict): if tool.get("type") in _WellKnownOpenAITools: diff --git a/libs/core/langchain_core/utils/interactive_env.py b/libs/core/langchain_core/utils/interactive_env.py index b974b3091eb..305b8edc146 100644 --- a/libs/core/langchain_core/utils/interactive_env.py +++ b/libs/core/langchain_core/utils/interactive_env.py @@ -1,5 +1,7 @@ """Utilities for working with interactive environments.""" +import sys + def is_interactive_env() -> bool: """Determine if running within IPython or Jupyter. @@ -7,6 +9,4 @@ def is_interactive_env() -> bool: Returns: True if running in an interactive environment, False otherwise. """ - import sys - return hasattr(sys, "ps2") diff --git a/libs/core/langchain_core/vectorstores/base.py b/libs/core/langchain_core/vectorstores/base.py index 888136b8929..9c06612b2ee 100644 --- a/libs/core/langchain_core/vectorstores/base.py +++ b/libs/core/langchain_core/vectorstores/base.py @@ -38,6 +38,7 @@ from typing import ( from pydantic import ConfigDict, Field, model_validator from typing_extensions import Self, override +from langchain_core.documents import Document from langchain_core.embeddings import Embeddings from langchain_core.retrievers import BaseRetriever, LangSmithRetrieverParams from langchain_core.runnables.config import run_in_executor @@ -49,7 +50,6 @@ if TYPE_CHECKING: AsyncCallbackManagerForRetrieverRun, CallbackManagerForRetrieverRun, ) - from langchain_core.documents import Document logger = logging.getLogger(__name__) @@ -85,9 +85,6 @@ class VectorStore(ABC): ValueError: If the number of ids does not match the number of texts. """ if type(self).add_documents != VectorStore.add_documents: - # Import document in local scope to avoid circular imports - from langchain_core.documents import Document - # This condition is triggered if the subclass has provided # an implementation of the upsert method. # The existing add_texts @@ -234,9 +231,6 @@ class VectorStore(ABC): # For backward compatibility kwargs["ids"] = ids if type(self).aadd_documents != VectorStore.aadd_documents: - # Import document in local scope to avoid circular imports - from langchain_core.documents import Document - # This condition is triggered if the subclass has provided # an implementation of the upsert method. # The existing add_texts diff --git a/libs/core/langchain_core/vectorstores/in_memory.py b/libs/core/langchain_core/vectorstores/in_memory.py index 0395478dfe9..d08a68c8fc2 100644 --- a/libs/core/langchain_core/vectorstores/in_memory.py +++ b/libs/core/langchain_core/vectorstores/in_memory.py @@ -27,6 +27,13 @@ if TYPE_CHECKING: from langchain_core.embeddings import Embeddings from langchain_core.indexing import UpsertResponse +try: + import numpy as np + + _HAS_NUMPY = True +except ImportError: + _HAS_NUMPY = False + class InMemoryVectorStore(VectorStore): """In-memory vector store implementation. @@ -496,14 +503,12 @@ class InMemoryVectorStore(VectorStore): filter=filter, ) - try: - import numpy as np - except ImportError as e: + if not _HAS_NUMPY: msg = ( "numpy must be installed to use max_marginal_relevance_search " "pip install numpy" ) - raise ImportError(msg) from e + raise ImportError(msg) mmr_chosen_indices = maximal_marginal_relevance( np.array(embedding, dtype=np.float32), diff --git a/libs/core/langchain_core/vectorstores/utils.py b/libs/core/langchain_core/vectorstores/utils.py index 645306bccde..1f68269915a 100644 --- a/libs/core/langchain_core/vectorstores/utils.py +++ b/libs/core/langchain_core/vectorstores/utils.py @@ -10,9 +10,21 @@ import logging import warnings from typing import TYPE_CHECKING, Union -if TYPE_CHECKING: +try: import numpy as np + _HAS_NUMPY = True +except ImportError: + _HAS_NUMPY = False + +try: + import simsimd as simd # type: ignore[import-not-found] + + _HAS_SIMSIMD = True +except ImportError: + _HAS_SIMSIMD = False + +if TYPE_CHECKING: Matrix = Union[list[list[float]], list[np.ndarray], np.ndarray] logger = logging.getLogger(__name__) @@ -33,14 +45,12 @@ def _cosine_similarity(x: Matrix, y: Matrix) -> np.ndarray: ValueError: If the number of columns in X and Y are not the same. ImportError: If numpy is not installed. """ - try: - import numpy as np - except ImportError as e: + if not _HAS_NUMPY: msg = ( "cosine_similarity requires numpy to be installed. " "Please install numpy with `pip install numpy`." ) - raise ImportError(msg) from e + raise ImportError(msg) if len(x) == 0 or len(y) == 0: return np.array([[]]) @@ -70,9 +80,7 @@ def _cosine_similarity(x: Matrix, y: Matrix) -> np.ndarray: f"and Y has shape {y.shape}." ) raise ValueError(msg) - try: - import simsimd as simd # type: ignore[import-not-found] - except ImportError: + if not _HAS_SIMSIMD: logger.debug( "Unable to import simsimd, defaulting to NumPy implementation. If you want " "to use simsimd please install with `pip install simsimd`." @@ -113,14 +121,12 @@ def maximal_marginal_relevance( Raises: ImportError: If numpy is not installed. """ - try: - import numpy as np - except ImportError as e: + if not _HAS_NUMPY: msg = ( "maximal_marginal_relevance requires numpy to be installed. " "Please install numpy with `pip install numpy`." ) - raise ImportError(msg) from e + raise ImportError(msg) if min(k, len(embedding_list)) <= 0: return [] diff --git a/libs/core/pyproject.toml b/libs/core/pyproject.toml index 8f48ba5d5e8..50140edb77b 100644 --- a/libs/core/pyproject.toml +++ b/libs/core/pyproject.toml @@ -114,7 +114,6 @@ ignore = [ "BLE", # Blind exceptions "DOC", # Docstrings (preview) "ERA", # No commented-out code - "PLC0415", # Imports outside top level "PLR2004", # Comparison to magic number ] unfixable = ["PLW1510",] diff --git a/libs/core/tests/unit_tests/language_models/chat_models/test_cache.py b/libs/core/tests/unit_tests/language_models/chat_models/test_cache.py index 39e4babc782..b8816fa1898 100644 --- a/libs/core/tests/unit_tests/language_models/chat_models/test_cache.py +++ b/libs/core/tests/unit_tests/language_models/chat_models/test_cache.py @@ -12,6 +12,7 @@ from langchain_core.language_models.fake_chat_models import ( FakeListChatModel, GenericFakeChatModel, ) +from langchain_core.load import dumps from langchain_core.messages import AIMessage from langchain_core.outputs import ChatGeneration, Generation from langchain_core.outputs.chat_result import ChatResult @@ -318,8 +319,6 @@ def test_cache_with_generation_objects() -> None: cache = InMemoryCache() # Create a simple fake chat model that we can control - from langchain_core.messages import AIMessage - class SimpleFakeChat: """Simple fake chat model for testing.""" @@ -332,8 +331,6 @@ def test_cache_with_generation_objects() -> None: def generate_response(self, prompt: str) -> ChatResult: """Simulate the cache lookup and generation logic.""" - from langchain_core.load import dumps - llm_string = self._get_llm_string() prompt_str = dumps([prompt]) diff --git a/libs/core/tests/unit_tests/language_models/chat_models/test_rate_limiting.py b/libs/core/tests/unit_tests/language_models/chat_models/test_rate_limiting.py index c4d6a50f6be..2cbc0001c3a 100644 --- a/libs/core/tests/unit_tests/language_models/chat_models/test_rate_limiting.py +++ b/libs/core/tests/unit_tests/language_models/chat_models/test_rate_limiting.py @@ -5,6 +5,7 @@ from blockbuster import BlockBuster from langchain_core.caches import InMemoryCache from langchain_core.language_models import GenericFakeChatModel +from langchain_core.load import dumps from langchain_core.rate_limiters import InMemoryRateLimiter @@ -229,8 +230,6 @@ class SerializableModel(GenericFakeChatModel): def test_serialization_with_rate_limiter() -> None: """Test model serialization with rate limiter.""" - from langchain_core.load import dumps - model = SerializableModel( messages=iter(["hello", "world", "!"]), rate_limiter=InMemoryRateLimiter( diff --git a/libs/core/tests/unit_tests/load/test_serializable.py b/libs/core/tests/unit_tests/load/test_serializable.py index e782709fd41..8630df1b47e 100644 --- a/libs/core/tests/unit_tests/load/test_serializable.py +++ b/libs/core/tests/unit_tests/load/test_serializable.py @@ -1,7 +1,7 @@ import json import pytest -from pydantic import BaseModel, ConfigDict, Field +from pydantic import BaseModel, ConfigDict, Field, SecretStr from langchain_core.load import Serializable, dumpd, dumps, load from langchain_core.load.serializable import _is_field_useful @@ -62,9 +62,6 @@ def test_simple_serialization_is_serializable() -> None: def test_simple_serialization_secret() -> None: """Test handling of secrets.""" - from pydantic import SecretStr - - from langchain_core.load import Serializable class Foo(Serializable): bar: int diff --git a/libs/core/tests/unit_tests/output_parsers/test_openai_tools.py b/libs/core/tests/unit_tests/output_parsers/test_openai_tools.py index 7258f5bd20f..edcf72e4f0f 100644 --- a/libs/core/tests/unit_tests/output_parsers/test_openai_tools.py +++ b/libs/core/tests/unit_tests/output_parsers/test_openai_tools.py @@ -1,6 +1,7 @@ from collections.abc import AsyncIterator, Iterator from typing import Any +import pydantic import pytest from pydantic import BaseModel, Field, ValidationError @@ -802,7 +803,6 @@ async def test_partial_pydantic_output_parser_async() -> None: def test_parse_with_different_pydantic_2_v1() -> None: """Test with pydantic.v1.BaseModel from pydantic 2.""" - import pydantic class Forecast(pydantic.v1.BaseModel): temperature: int @@ -836,9 +836,8 @@ def test_parse_with_different_pydantic_2_v1() -> None: def test_parse_with_different_pydantic_2_proper() -> None: """Test with pydantic.BaseModel from pydantic 2.""" - import pydantic - class Forecast(pydantic.BaseModel): + class Forecast(BaseModel): temperature: int forecast: str diff --git a/libs/core/tests/unit_tests/output_parsers/test_pydantic_parser.py b/libs/core/tests/unit_tests/output_parsers/test_pydantic_parser.py index a72aa926780..07acf94d7c2 100644 --- a/libs/core/tests/unit_tests/output_parsers/test_pydantic_parser.py +++ b/libs/core/tests/unit_tests/output_parsers/test_pydantic_parser.py @@ -189,8 +189,6 @@ def test_pydantic_output_parser_type_inference() -> None: def test_format_instructions_preserves_language() -> None: """Test format instructions does not attempt to encode into ascii.""" - from pydantic import BaseModel, Field - description = ( "你好, こんにちは, नमस्ते, Bonjour, Hola, " "Olá, 안녕하세요, Jambo, Merhaba, Γειά σου" # noqa: RUF001 diff --git a/libs/core/tests/unit_tests/prompts/test_prompt.py b/libs/core/tests/unit_tests/prompts/test_prompt.py index 09d26438cd4..6c3e052089a 100644 --- a/libs/core/tests/unit_tests/prompts/test_prompt.py +++ b/libs/core/tests/unit_tests/prompts/test_prompt.py @@ -1,6 +1,7 @@ """Test functionality related to prompts.""" import re +from tempfile import NamedTemporaryFile from typing import Any, Union from unittest import mock @@ -32,8 +33,6 @@ def test_from_file_encoding() -> None: input_variables = ["foo"] # First write to a file using CP-1252 encoding. - from tempfile import NamedTemporaryFile - with NamedTemporaryFile(delete=True, mode="w", encoding="cp1252") as f: f.write(template) f.flush() @@ -434,11 +433,9 @@ Will it get confused{ }? assert prompt == expected_prompt -@pytest.mark.requires("jinja2") def test_basic_sandboxing_with_jinja2() -> None: """Test basic sandboxing with jinja2.""" - import jinja2 - + jinja2 = pytest.importorskip("jinja2") template = " {{''.__class__.__bases__[0] }} " # malicious code prompt = PromptTemplate.from_template(template, template_format="jinja2") with pytest.raises(jinja2.exceptions.SecurityError): diff --git a/libs/core/tests/unit_tests/runnables/test_concurrency.py b/libs/core/tests/unit_tests/runnables/test_concurrency.py index 24d4fad5d23..60022b803d7 100644 --- a/libs/core/tests/unit_tests/runnables/test_concurrency.py +++ b/libs/core/tests/unit_tests/runnables/test_concurrency.py @@ -2,6 +2,7 @@ import asyncio import time +from threading import Lock from typing import Any import pytest @@ -80,7 +81,6 @@ def test_batch_concurrency() -> None: """Test that batch respects max_concurrency.""" running_tasks = 0 max_running_tasks = 0 - from threading import Lock lock = Lock() @@ -112,7 +112,6 @@ def test_batch_as_completed_concurrency() -> None: """Test that batch_as_completed respects max_concurrency.""" running_tasks = 0 max_running_tasks = 0 - from threading import Lock lock = Lock() diff --git a/libs/core/tests/unit_tests/runnables/test_history.py b/libs/core/tests/unit_tests/runnables/test_history.py index 0a4b5326ff3..249b4d6e45e 100644 --- a/libs/core/tests/unit_tests/runnables/test_history.py +++ b/libs/core/tests/unit_tests/runnables/test_history.py @@ -4,7 +4,7 @@ from typing import Any, Callable, Optional, Union import pytest from packaging import version -from pydantic import BaseModel +from pydantic import BaseModel, RootModel from typing_extensions import override from langchain_core.callbacks import ( @@ -20,6 +20,11 @@ from langchain_core.runnables.config import RunnableConfig from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_core.runnables.utils import ConfigurableFieldSpec, Input, Output from langchain_core.tracers import Run +from langchain_core.tracers.root_listeners import ( + AsyncListener, + AsyncRootListenersTracer, + RootListenersTracer, +) from langchain_core.utils.pydantic import PYDANTIC_VERSION from tests.unit_tests.pydantic_utils import _schema @@ -499,8 +504,6 @@ def test_get_output_schema() -> None: def test_get_input_schema_input_messages() -> None: - from pydantic import RootModel - runnable_with_message_history_input = RootModel[Sequence[BaseMessage]] runnable = RunnableLambda( @@ -776,8 +779,6 @@ def test_ignore_session_id() -> None: class _RunnableLambdaWithRaiseError(RunnableLambda[Input, Output]): - from langchain_core.tracers.root_listeners import AsyncListener - def with_listeners( self, *, @@ -791,8 +792,6 @@ class _RunnableLambdaWithRaiseError(RunnableLambda[Input, Output]): Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]] ] = None, ) -> Runnable[Input, Output]: - from langchain_core.tracers.root_listeners import RootListenersTracer - def create_tracer(config: RunnableConfig) -> RunnableConfig: tracer = RootListenersTracer( config=config, @@ -817,8 +816,6 @@ class _RunnableLambdaWithRaiseError(RunnableLambda[Input, Output]): on_end: Optional[AsyncListener] = None, on_error: Optional[AsyncListener] = None, ) -> Runnable[Input, Output]: - from langchain_core.tracers.root_listeners import AsyncRootListenersTracer - def create_tracer(config: RunnableConfig) -> RunnableConfig: tracer = AsyncRootListenersTracer( config=config, diff --git a/libs/core/tests/unit_tests/runnables/test_imports.py b/libs/core/tests/unit_tests/runnables/test_imports.py index f0ebf48c446..e40ffc1fa71 100644 --- a/libs/core/tests/unit_tests/runnables/test_imports.py +++ b/libs/core/tests/unit_tests/runnables/test_imports.py @@ -40,6 +40,6 @@ def test_all_imports() -> None: def test_imports_for_specific_funcs() -> None: """Test that a few specific imports in more internal namespaces.""" # create_model implementation has been moved to langchain_core.utils.pydantic - from langchain_core.runnables.utils import ( # type: ignore[attr-defined] # noqa: F401 + from langchain_core.runnables.utils import ( # type: ignore[attr-defined] # noqa: F401,PLC0415 create_model, ) diff --git a/libs/core/tests/unit_tests/runnables/test_runnable.py b/libs/core/tests/unit_tests/runnables/test_runnable.py index 14a5334a844..36ef2f80834 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable.py @@ -1,6 +1,7 @@ import asyncio import re import sys +import time import uuid import warnings from collections.abc import AsyncIterator, Awaitable, Iterator, Sequence @@ -17,6 +18,7 @@ from pytest_mock import MockerFixture from syrupy.assertion import SnapshotAssertion from typing_extensions import TypedDict, override +from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks.manager import ( AsyncCallbackManagerForRetrieverRun, CallbackManagerForRetrieverRun, @@ -29,6 +31,7 @@ from langchain_core.language_models import ( FakeListLLM, FakeStreamingListLLM, ) +from langchain_core.language_models.fake_chat_models import GenericFakeChatModel from langchain_core.load import dumpd, dumps from langchain_core.load.load import loads from langchain_core.messages import AIMessageChunk, HumanMessage, SystemMessage @@ -5516,9 +5519,6 @@ async def test_passthrough_atransform_with_dicts() -> None: def test_listeners() -> None: - from langchain_core.runnables import RunnableLambda - from langchain_core.tracers.schemas import Run - def fake_chain(inputs: dict) -> dict: return {**inputs, "key": "extra"} @@ -5546,9 +5546,6 @@ def test_listeners() -> None: async def test_listeners_async() -> None: - from langchain_core.runnables import RunnableLambda - from langchain_core.tracers.schemas import Run - def fake_chain(inputs: dict) -> dict: return {**inputs, "key": "extra"} @@ -5578,12 +5575,6 @@ async def test_listeners_async() -> None: def test_closing_iterator_doesnt_raise_error() -> None: """Test that closing an iterator calls on_chain_end rather than on_chain_error.""" - import time - - from langchain_core.callbacks import BaseCallbackHandler - from langchain_core.language_models.fake_chat_models import GenericFakeChatModel - from langchain_core.output_parsers import StrOutputParser - on_chain_error_triggered = False on_chain_end_triggered = False diff --git a/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py b/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py index a7731053032..ec6451aeac8 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py @@ -20,6 +20,7 @@ from pydantic import BaseModel from typing_extensions import override from langchain_core.callbacks import CallbackManagerForRetrieverRun, Callbacks +from langchain_core.callbacks.manager import adispatch_custom_event from langchain_core.chat_history import BaseChatMessageHistory from langchain_core.documents import Document from langchain_core.language_models import FakeStreamingListLLM, GenericFakeChatModel @@ -2548,7 +2549,6 @@ async def test_cancel_astream_events() -> None: async def test_custom_event() -> None: """Test adhoc event.""" - from langchain_core.callbacks.manager import adispatch_custom_event # Ignoring type due to RunnableLamdba being dynamic when it comes to being # applied as a decorator to async functions. @@ -2625,7 +2625,6 @@ async def test_custom_event() -> None: async def test_custom_event_nested() -> None: """Test adhoc event in a nested chain.""" - from langchain_core.callbacks.manager import adispatch_custom_event # Ignoring type due to RunnableLamdba being dynamic when it comes to being # applied as a decorator to async functions. @@ -2736,7 +2735,6 @@ async def test_custom_event_root_dispatch() -> None: # This just tests that nothing breaks on the path. # It shouldn't do anything at the moment, since the tracer isn't configured # to handle adhoc events. - from langchain_core.callbacks.manager import adispatch_custom_event # Expected behavior is that the event cannot be dispatched with pytest.raises(RuntimeError): @@ -2750,8 +2748,6 @@ IS_GTE_3_11 = sys.version_info >= (3, 11) @pytest.mark.skipif(not IS_GTE_3_11, reason="Requires Python >=3.11") async def test_custom_event_root_dispatch_with_in_tool() -> None: """Test adhoc event in a nested chain.""" - from langchain_core.callbacks.manager import adispatch_custom_event - from langchain_core.tools import tool @tool async def foo(x: int) -> int: diff --git a/libs/core/tests/unit_tests/test_globals.py b/libs/core/tests/unit_tests/test_globals.py index a0b2457bb48..58d6ad38ab8 100644 --- a/libs/core/tests/unit_tests/test_globals.py +++ b/libs/core/tests/unit_tests/test_globals.py @@ -1,18 +1,17 @@ +import langchain_core +from langchain_core.callbacks.manager import _get_debug from langchain_core.globals import get_debug, set_debug def test_debug_is_settable_via_setter() -> None: - from langchain_core import globals as globals_ - from langchain_core.callbacks.manager import _get_debug - - previous_value = globals_._debug + previous_value = langchain_core.globals._debug previous_fn_reading = _get_debug() assert previous_value == previous_fn_reading # Flip the value of the flag. set_debug(not previous_value) - new_value = globals_._debug + new_value = langchain_core.globals._debug new_fn_reading = _get_debug() try: diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index 63107361224..aabc7e35ff4 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -21,7 +21,7 @@ from typing import ( ) import pytest -from pydantic import BaseModel, Field, ValidationError +from pydantic import BaseModel, ConfigDict, Field, ValidationError from pydantic.v1 import BaseModel as BaseModelV1 from pydantic.v1 import ValidationError as ValidationErrorV1 from typing_extensions import TypedDict, override @@ -1852,7 +1852,6 @@ def generate_models() -> list[Any]: def generate_backwards_compatible_v1() -> list[Any]: """Generate a model with pydantic 2 from the v1 namespace.""" - from pydantic.v1 import BaseModel as BaseModelV1 class FooV1Namespace(BaseModelV1): a: int @@ -1920,8 +1919,6 @@ def test_args_schema_explicitly_typed() -> None: is a pydantic 1 model! """ - # Check with whatever pydantic model is passed in and not via v1 namespace - from pydantic import BaseModel class Foo(BaseModel): a: int @@ -1964,7 +1961,6 @@ def test_args_schema_explicitly_typed() -> None: @pytest.mark.parametrize("pydantic_model", TEST_MODELS) def test_structured_tool_with_different_pydantic_versions(pydantic_model: Any) -> None: """This should test that one can type the args schema as a pydantic model.""" - from langchain_core.tools import StructuredTool def foo(a: int, b: str) -> str: """Hahaha.""" @@ -2063,16 +2059,13 @@ def test__get_all_basemodel_annotations_v2(*, use_v1_namespace: bool) -> None: A = TypeVar("A") if use_v1_namespace: - from pydantic.v1 import BaseModel as BaseModel1 - class ModelA(BaseModel1, Generic[A], extra="allow"): + class ModelA(BaseModelV1, Generic[A], extra="allow"): a: A else: - from pydantic import BaseModel as BaseModel2 - from pydantic import ConfigDict - class ModelA(BaseModel2, Generic[A]): # type: ignore[no-redef] + class ModelA(BaseModel, Generic[A]): # type: ignore[no-redef] a: A model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow") @@ -2208,12 +2201,8 @@ def test_create_retriever_tool() -> None: def test_tool_args_schema_pydantic_v2_with_metadata() -> None: - from pydantic import BaseModel as BaseModelV2 - from pydantic import Field as FieldV2 - from pydantic import ValidationError as ValidationErrorV2 - - class Foo(BaseModelV2): - x: list[int] = FieldV2( + class Foo(BaseModel): + x: list[int] = Field( description="List of integers", min_length=10, max_length=15 ) @@ -2240,7 +2229,7 @@ def test_tool_args_schema_pydantic_v2_with_metadata() -> None: } assert foo.invoke({"x": [0] * 10}) - with pytest.raises(ValidationErrorV2): + with pytest.raises(ValidationError): foo.invoke({"x": [0] * 9}) @@ -2576,8 +2565,6 @@ def test_title_property_preserved() -> None: https://github.com/langchain-ai/langchain/issues/30456 """ - from langchain_core.tools import tool - schema_to_be_extracted = { "type": "object", "required": [], diff --git a/libs/core/tests/unit_tests/utils/test_pydantic.py b/libs/core/tests/unit_tests/utils/test_pydantic.py index dadce0e3f7e..3afeca68c73 100644 --- a/libs/core/tests/unit_tests/utils/test_pydantic.py +++ b/libs/core/tests/unit_tests/utils/test_pydantic.py @@ -3,7 +3,8 @@ import warnings from typing import Any, Optional -from pydantic import ConfigDict +from pydantic import BaseModel, ConfigDict, Field +from pydantic.v1 import BaseModel as BaseModelV1 from langchain_core.utils.pydantic import ( _create_subset_model_v2, @@ -16,8 +17,6 @@ from langchain_core.utils.pydantic import ( def test_pre_init_decorator() -> None: - from pydantic import BaseModel - class Foo(BaseModel): x: int = 5 y: int @@ -35,8 +34,6 @@ def test_pre_init_decorator() -> None: def test_pre_init_decorator_with_more_defaults() -> None: - from pydantic import BaseModel, Field - class Foo(BaseModel): a: int = 1 b: Optional[int] = None @@ -56,8 +53,6 @@ def test_pre_init_decorator_with_more_defaults() -> None: def test_with_aliases() -> None: - from pydantic import BaseModel, Field - class Foo(BaseModel): x: int = Field(default=1, alias="y") z: int @@ -92,19 +87,14 @@ def test_with_aliases() -> None: def test_is_basemodel_subclass() -> None: """Test pydantic.""" - from pydantic import BaseModel as BaseModelV2 - from pydantic.v1 import BaseModel as BaseModelV1 - - assert is_basemodel_subclass(BaseModelV2) + assert is_basemodel_subclass(BaseModel) assert is_basemodel_subclass(BaseModelV1) def test_is_basemodel_instance() -> None: """Test pydantic.""" - from pydantic import BaseModel as BaseModelV2 - from pydantic.v1 import BaseModel as BaseModelV1 - class Foo(BaseModelV2): + class Foo(BaseModel): x: int assert is_basemodel_instance(Foo(x=5)) @@ -117,11 +107,9 @@ def test_is_basemodel_instance() -> None: def test_with_field_metadata() -> None: """Test pydantic with field metadata.""" - from pydantic import BaseModel as BaseModelV2 - from pydantic import Field as FieldV2 - class Foo(BaseModelV2): - x: list[int] = FieldV2( + class Foo(BaseModel): + x: list[int] = Field( description="List of integers", min_length=10, max_length=15 ) @@ -144,8 +132,6 @@ def test_with_field_metadata() -> None: def test_fields_pydantic_v2_proper() -> None: - from pydantic import BaseModel - class Foo(BaseModel): x: int @@ -154,9 +140,7 @@ def test_fields_pydantic_v2_proper() -> None: def test_fields_pydantic_v1_from_2() -> None: - from pydantic.v1 import BaseModel - - class Foo(BaseModel): + class Foo(BaseModelV1): x: int fields = get_fields(Foo) diff --git a/libs/core/tests/unit_tests/utils/test_utils.py b/libs/core/tests/unit_tests/utils/test_utils.py index 51967b82a19..1e6a88b6375 100644 --- a/libs/core/tests/unit_tests/utils/test_utils.py +++ b/libs/core/tests/unit_tests/utils/test_utils.py @@ -6,7 +6,9 @@ from typing import Any, Callable, Optional, Union from unittest.mock import patch import pytest -from pydantic import SecretStr +from pydantic import BaseModel, Field, SecretStr +from pydantic.v1 import BaseModel as PydanticV1BaseModel +from pydantic.v1 import Field as PydanticV1Field from langchain_core import utils from langchain_core.outputs import GenerationChunk @@ -212,13 +214,10 @@ def test_guard_import_failure( def test_get_pydantic_field_names_v1_in_2() -> None: - from pydantic.v1 import BaseModel as PydanticV1BaseModel - from pydantic.v1 import Field - class PydanticV1Model(PydanticV1BaseModel): field1: str field2: int - alias_field: int = Field(alias="aliased_field") + alias_field: int = PydanticV1Field(alias="aliased_field") result = get_pydantic_field_names(PydanticV1Model) expected = {"field1", "field2", "aliased_field", "alias_field"} @@ -226,8 +225,6 @@ def test_get_pydantic_field_names_v1_in_2() -> None: def test_get_pydantic_field_names_v2_in_2() -> None: - from pydantic import BaseModel, Field - class PydanticModel(BaseModel): field1: str field2: int @@ -341,8 +338,6 @@ def test_secret_from_env_with_custom_error_message( def test_using_secret_from_env_as_default_factory( monkeypatch: pytest.MonkeyPatch, ) -> None: - from pydantic import BaseModel, Field - class Foo(BaseModel): secret: SecretStr = Field(default_factory=secret_from_env("TEST_KEY"))