From 0c50c629d2e118d52bf21abc8fdaca387f0bacd0 Mon Sep 17 00:00:00 2001 From: Stanislav Khrapov Date: Tue, 20 Jan 2026 17:05:34 +0100 Subject: [PATCH 1/4] Add ty to type checking --- .github/workflows/workflow.yaml | 2 ++ .gitignore | 1 + pyproject.toml | 4 ++++ src/order_matching/executed_trades.py | 18 +++++++++------ src/order_matching/orders.py | 33 +++++++++++++++------------ uv.lock | 31 ++++++++++++++++++++++++- 6 files changed, 66 insertions(+), 23 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index b6ffeba..3c1771f 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -87,6 +87,8 @@ jobs: run: uv sync --group dev - name: Run pre-commit run: uv run prek run -v --show-diff-on-failure + - name: Run ty + run: uv run ty check docs: name: Documentation diff --git a/.gitignore b/.gitignore index 01e29c4..e66a28a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ benchmark.json benchmark_history.svg __pycache__/ venv/ +.venv/ site/ docs/reference/ *.egg-info diff --git a/pyproject.toml b/pyproject.toml index d65b55c..09830d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ test = [ ] dev = [ "prek>=0.2.30", + "ty>=0.0.12", ] [project.optional-dependencies] doc = [ @@ -84,6 +85,9 @@ disallow_untyped_calls = true disallow_untyped_defs = true disallow_incomplete_defs = true +[tool.ty.rules] +no-matching-overload = "ignore" # spark issue + [tool.commitizen] version_scheme = "semver" version_provider = "uv" diff --git a/src/order_matching/executed_trades.py b/src/order_matching/executed_trades.py index b7d887d..1f0be48 100644 --- a/src/order_matching/executed_trades.py +++ b/src/order_matching/executed_trades.py @@ -3,9 +3,10 @@ from collections import defaultdict from dataclasses import asdict from datetime import datetime +from typing import cast import pandas as pd -from pandera.typing import DataFrame +from pandera.typing.pandas import DataFrame from order_matching.schemas import TradeDataSchema from order_matching.trade import Trade @@ -66,13 +67,16 @@ def to_frame(self) -> DataFrame[TradeDataSchema]: """ trades = self.trades if len(trades) == 0: - return pd.DataFrame() + return cast(DataFrame[TradeDataSchema], pd.DataFrame()) else: - return pd.DataFrame.from_records([asdict(trade) for trade in trades]).assign( - **{ - TradeDataSchema.side: lambda df: df[TradeDataSchema.side].astype(str), - TradeDataSchema.execution: lambda df: df[TradeDataSchema.execution].astype(str), - } + return cast( + DataFrame[TradeDataSchema], + pd.DataFrame.from_records([asdict(trade) for trade in trades]).assign( + **{ + TradeDataSchema.side: lambda df: df[TradeDataSchema.side].astype(str), + TradeDataSchema.execution: lambda df: df[TradeDataSchema.execution].astype(str), + } + ), ) def __add__(self, other: ExecutedTrades) -> ExecutedTrades: diff --git a/src/order_matching/orders.py b/src/order_matching/orders.py index 96d7043..d37eb53 100644 --- a/src/order_matching/orders.py +++ b/src/order_matching/orders.py @@ -1,10 +1,10 @@ from __future__ import annotations from dataclasses import asdict -from typing import Generator, Iterator, Sequence +from typing import Generator, Iterator, Sequence, cast import pandas as pd -from pandera.typing import DataFrame +from pandera.typing.pandas import DataFrame from order_matching.order import Order from order_matching.schemas import OrderDataSchema @@ -63,20 +63,23 @@ def to_frame(self) -> DataFrame[OrderDataSchema]: DataFrame[OrderDataSchema] """ if len(self.orders) == 0: - return pd.DataFrame() + return cast(DataFrame[OrderDataSchema], pd.DataFrame()) else: - return pd.DataFrame.from_records([asdict(order) for order in self.orders]).assign( - **{ - OrderDataSchema.side: lambda df: df[OrderDataSchema.side].astype(str), - OrderDataSchema.execution: lambda df: df[OrderDataSchema.execution].astype(str), - OrderDataSchema.status: lambda df: df[OrderDataSchema.status].astype(str), - OrderDataSchema.timestamp: lambda df: pd.to_datetime( - df[OrderDataSchema.timestamp], errors="coerce" - ), - OrderDataSchema.expiration: lambda df: pd.to_datetime( - df[OrderDataSchema.expiration], errors="coerce" - ), - } + return cast( + DataFrame[OrderDataSchema], + pd.DataFrame.from_records([asdict(order) for order in self.orders]).assign( + **{ + OrderDataSchema.side: lambda df: df[OrderDataSchema.side].astype(str), + OrderDataSchema.execution: lambda df: df[OrderDataSchema.execution].astype(str), + OrderDataSchema.status: lambda df: df[OrderDataSchema.status].astype(str), + OrderDataSchema.timestamp: lambda df: pd.to_datetime( + df[OrderDataSchema.timestamp], errors="coerce" + ), + OrderDataSchema.expiration: lambda df: pd.to_datetime( + df[OrderDataSchema.expiration], errors="coerce" + ), + } + ), ) @property diff --git a/uv.lock b/uv.lock index f2e6e37..fdf3713 100644 --- a/uv.lock +++ b/uv.lock @@ -818,6 +818,7 @@ doc = [ [package.dev-dependencies] dev = [ { name = "prek" }, + { name = "ty" }, ] test = [ { name = "pytest" }, @@ -841,7 +842,10 @@ requires-dist = [ provides-extras = ["doc"] [package.metadata.requires-dev] -dev = [{ name = "prek", specifier = ">=0.2.30" }] +dev = [ + { name = "prek", specifier = ">=0.2.30" }, + { name = "ty", specifier = ">=0.0.12" }, +] test = [ { name = "pytest", specifier = ">=8.3.3" }, { name = "pytest-benchmark", extras = ["histogram"], specifier = ">=5.1.0" }, @@ -1451,6 +1455,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, ] +[[package]] +name = "ty" +version = "0.0.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/78/ba1a4ad403c748fbba8be63b7e774a90e80b67192f6443d624c64fe4aaab/ty-0.0.12.tar.gz", hash = "sha256:cd01810e106c3b652a01b8f784dd21741de9fdc47bd595d02c122a7d5cefeee7", size = 4981303, upload-time = "2026-01-14T22:30:48.537Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/8f/c21314d074dda5fb13d3300fa6733fd0d8ff23ea83a721818740665b6314/ty-0.0.12-py3-none-linux_armv6l.whl", hash = "sha256:eb9da1e2c68bd754e090eab39ed65edf95168d36cbeb43ff2bd9f86b4edd56d1", size = 9614164, upload-time = "2026-01-14T22:30:44.016Z" }, + { url = "https://files.pythonhosted.org/packages/09/28/f8a4d944d13519d70c486e8f96d6fa95647ac2aa94432e97d5cfec1f42f6/ty-0.0.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c181f42aa19b0ed7f1b0c2d559980b1f1d77cc09419f51c8321c7ddf67758853", size = 9542337, upload-time = "2026-01-14T22:30:05.687Z" }, + { url = "https://files.pythonhosted.org/packages/e1/9c/f576e360441de7a8201daa6dc4ebc362853bc5305e059cceeb02ebdd9a48/ty-0.0.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1f829e1eecd39c3e1b032149db7ae6a3284f72fc36b42436e65243a9ed1173db", size = 8909582, upload-time = "2026-01-14T22:30:46.089Z" }, + { url = "https://files.pythonhosted.org/packages/d6/13/0898e494032a5d8af3060733d12929e3e7716db6c75eac63fa125730a3e7/ty-0.0.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45162e7826e1789cf3374627883cdeb0d56b82473a0771923e4572928e90be3", size = 9384932, upload-time = "2026-01-14T22:30:13.769Z" }, + { url = "https://files.pythonhosted.org/packages/e4/1a/b35b6c697008a11d4cedfd34d9672db2f0a0621ec80ece109e13fca4dfef/ty-0.0.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d11fec40b269bec01e751b2337d1c7ffa959a2c2090a950d7e21c2792442cccd", size = 9453140, upload-time = "2026-01-14T22:30:11.131Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/71c9edbc79a3c88a0711324458f29c7dbf6c23452c6e760dc25725483064/ty-0.0.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09d99e37e761a4d2651ad9d5a610d11235fbcbf35dc6d4bc04abf54e7cf894f1", size = 9960680, upload-time = "2026-01-14T22:30:33.621Z" }, + { url = "https://files.pythonhosted.org/packages/0e/75/39375129f62dd22f6ad5a99cd2a42fd27d8b91b235ce2db86875cdad397d/ty-0.0.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d9ca0cdb17bd37397da7b16a7cd23423fc65c3f9691e453ad46c723d121225a1", size = 10904518, upload-time = "2026-01-14T22:30:08.464Z" }, + { url = "https://files.pythonhosted.org/packages/32/5e/26c6d88fafa11a9d31ca9f4d12989f57782ec61e7291d4802d685b5be118/ty-0.0.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcf2757b905e7eddb7e456140066335b18eb68b634a9f72d6f54a427ab042c64", size = 10525001, upload-time = "2026-01-14T22:30:16.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a5/2f0b91894af13187110f9ad7ee926d86e4e6efa755c9c88a820ed7f84c85/ty-0.0.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00cf34c1ebe1147efeda3021a1064baa222c18cdac114b7b050bbe42deb4ca80", size = 10307103, upload-time = "2026-01-14T22:30:41.221Z" }, + { url = "https://files.pythonhosted.org/packages/4b/77/13d0410827e4bc713ebb7fdaf6b3590b37dcb1b82e0a81717b65548f2442/ty-0.0.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb3a655bd869352e9a22938d707631ac9fbca1016242b1f6d132d78f347c851", size = 10072737, upload-time = "2026-01-14T22:30:51.783Z" }, + { url = "https://files.pythonhosted.org/packages/e1/dd/fc36d8bac806c74cf04b4ca735bca14d19967ca84d88f31e121767880df1/ty-0.0.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4658e282c7cb82be304052f8f64f9925f23c3c4f90eeeb32663c74c4b095d7ba", size = 9368726, upload-time = "2026-01-14T22:30:18.683Z" }, + { url = "https://files.pythonhosted.org/packages/54/70/9e8e461647550f83e2fe54bc632ccbdc17a4909644783cdbdd17f7296059/ty-0.0.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c167d838eaaa06e03bb66a517f75296b643d950fbd93c1d1686a187e5a8dbd1f", size = 9454704, upload-time = "2026-01-14T22:30:22.759Z" }, + { url = "https://files.pythonhosted.org/packages/04/9b/6292cf7c14a0efeca0539cf7d78f453beff0475cb039fbea0eb5d07d343d/ty-0.0.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2956e0c9ab7023533b461d8a0e6b2ea7b78e01a8dde0688e8234d0fce10c4c1c", size = 9649829, upload-time = "2026-01-14T22:30:31.234Z" }, + { url = "https://files.pythonhosted.org/packages/49/bd/472a5d2013371e4870886cff791c94abdf0b92d43d305dd0f8e06b6ff719/ty-0.0.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c6a3fd7479580009f21002f3828320621d8a82d53b7ba36993234e3ccad58c8", size = 10162814, upload-time = "2026-01-14T22:30:36.174Z" }, + { url = "https://files.pythonhosted.org/packages/31/e9/2ecbe56826759845a7c21d80aa28187865ea62bc9757b056f6cbc06f78ed/ty-0.0.12-py3-none-win32.whl", hash = "sha256:a91c24fd75c0f1796d8ede9083e2c0ec96f106dbda73a09fe3135e075d31f742", size = 9140115, upload-time = "2026-01-14T22:30:38.903Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6d/d9531eff35a5c0ec9dbc10231fac21f9dd6504814048e81d6ce1c84dc566/ty-0.0.12-py3-none-win_amd64.whl", hash = "sha256:df151894be55c22d47068b0f3b484aff9e638761e2267e115d515fcc9c5b4a4b", size = 9884532, upload-time = "2026-01-14T22:30:25.112Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f3/20b49e75967023b123a221134548ad7000f9429f13fdcdda115b4c26305f/ty-0.0.12-py3-none-win_arm64.whl", hash = "sha256:cea99d334b05629de937ce52f43278acf155d3a316ad6a35356635f886be20ea", size = 9313974, upload-time = "2026-01-14T22:30:27.44Z" }, +] + [[package]] name = "typeguard" version = "4.4.4" From 56a90436a1efd88350475f84cea375feed777a27 Mon Sep 17 00:00:00 2001 From: Stanislav Khrapov Date: Tue, 20 Jan 2026 17:08:46 +0100 Subject: [PATCH 2/4] clean up --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 09830d2..806ea51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -86,7 +86,7 @@ disallow_untyped_defs = true disallow_incomplete_defs = true [tool.ty.rules] -no-matching-overload = "ignore" # spark issue +no-matching-overload = "ignore" [tool.commitizen] version_scheme = "semver" From f035fead98295008ea8010ce2b42abb43fc43180 Mon Sep 17 00:00:00 2001 From: Stanislav Khrapov Date: Tue, 20 Jan 2026 17:11:41 +0100 Subject: [PATCH 3/4] sync all groups --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 3c1771f..cb756b1 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -84,7 +84,7 @@ jobs: with: python-version: "3.13" - name: Install dependencies - run: uv sync --group dev + run: uv sync --all-groups - name: Run pre-commit run: uv run prek run -v --show-diff-on-failure - name: Run ty From c845c13d1686c852ef632ffa43f0380a3796ae49 Mon Sep 17 00:00:00 2001 From: Stanislav Khrapov Date: Tue, 20 Jan 2026 17:12:38 +0100 Subject: [PATCH 4/4] sync all extras --- .github/workflows/workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index cb756b1..f0f1363 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -84,7 +84,7 @@ jobs: with: python-version: "3.13" - name: Install dependencies - run: uv sync --all-groups + run: uv sync --all-groups --all-extras - name: Run pre-commit run: uv run prek run -v --show-diff-on-failure - name: Run ty