From ebfad9681a1a4c869173b6e05b82b045a07804d5 Mon Sep 17 00:00:00 2001 From: Hector Ventura Date: Tue, 6 Oct 2026 17:31:31 -0500 Subject: [PATCH 1/3] chore: add pytest-timeout and refresh uv.lock The CI integration job runs pytest -m integration --timeout=120, but pytest-timeout was never a dependency, so pytest exited with "unrecognized arguments: --timeout=120" before collecting a test. The integration suite has not actually run in CI on any recent main build. uv.lock also pinned testcontainers 4.14.2, which mypy treats as untyped, so `uv sync --extra dev && uv run mypy floci` failed under strict mode while CI (pip, testcontainers 4.15.0) passed. The lock now resolves testcontainers 4.15.0 on Python 3.10 and later, matching CI. Lockfile changes: pytest-timeout 2.4.0 added, testcontainers 4.14.2 to 4.15.0 (Python 3.10+). Everything else is the newer uv lockfile revision (3 to 5) dropping redundant markers; no other version changes. Signed-off-by: Hector Ventura --- pyproject.toml | 1 + uv.lock | 155 +++++++++++++++++++++++++++---------------------- 2 files changed, 86 insertions(+), 70 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6fb1656..1f9be7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dev = [ "mypy>=1.0", "pytest>=7.0", "pytest-cov>=4.0", + "pytest-timeout>=2.3", "ruff>=0.4", ] diff --git a/uv.lock b/uv.lock index 04c4f67..6b860c9 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.9" resolution-markers = [ "python_full_version >= '3.15'", @@ -55,9 +55,9 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "botocore", version = "1.42.97", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "jmespath", marker = "python_full_version < '3.10'" }, - { name = "s3transfer", version = "0.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "botocore", version = "1.42.97", source = { registry = "https://pypi.org/simple" } }, + { name = "jmespath" }, + { name = "s3transfer", version = "0.16.1", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/55/7d/5c6fa0bb9fd5caf865b9356411793900304328bcd0bc1eda96a32a1368a6/boto3-1.42.97.tar.gz", hash = "sha256:2833dbeda3670ea610ad48dff7d27cdc829dbbfcdfbc6b750b673948e949b6f0", size = 113217, upload-time = "2026-04-27T20:39:17.646Z" } wheels = [ @@ -73,9 +73,9 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "botocore", version = "1.43.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "jmespath", marker = "python_full_version >= '3.10'" }, - { name = "s3transfer", version = "0.17.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "botocore", version = "1.43.7", source = { registry = "https://pypi.org/simple" } }, + { name = "jmespath" }, + { name = "s3transfer", version = "0.17.0", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/6b/0d/67ebf496fe061397f7eb907504e950fe6d2fa5945fd05891f3033376e471/boto3-1.43.7.tar.gz", hash = "sha256:b1e4b40f4a828c67291b12ebefd17d87a57321101e4a0c969b2f593a0310f343", size = 113170, upload-time = "2026-05-13T19:35:48.556Z" } wheels = [ @@ -91,9 +91,9 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "jmespath", marker = "python_full_version < '3.10'" }, - { name = "python-dateutil", marker = "python_full_version < '3.10'" }, - { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/c6/95/c37edb602948fad2253ffd1bb3dba5b938645bd1845ee4160350136a0f41/botocore-1.42.97.tar.gz", hash = "sha256:5c0bb00e32d16ff6d278cc8c9e10dc3672d9c1d569031635ac3c908a60de8310", size = 15269348, upload-time = "2026-04-27T20:39:05.625Z" } wheels = [ @@ -109,9 +109,9 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "jmespath", marker = "python_full_version >= '3.10'" }, - { name = "python-dateutil", marker = "python_full_version >= '3.10'" }, - { name = "urllib3", version = "2.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3", version = "2.7.0", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/ed/be/59144884fa71908e2ac389cfe0fd2ebe8e8adb47bcc994188eb59967406a/botocore-1.43.7.tar.gz", hash = "sha256:abbbc623c52dce86ea9d4534d35e2d6ce447d98edfdaced1695ee0278d6063e3", size = 15350131, upload-time = "2026-05-13T19:35:33.106Z" } wheels = [ @@ -374,7 +374,7 @@ wheels = [ [package.optional-dependencies] toml = [ - { name = "tomli", marker = "python_full_version < '3.10'" }, + { name = "tomli" }, ] [[package]] @@ -496,7 +496,7 @@ wheels = [ [package.optional-dependencies] toml = [ - { name = "tomli", marker = "python_full_version >= '3.10' and python_full_version <= '3.11'" }, + { name = "tomli", marker = "python_full_version <= '3.11'" }, ] [[package]] @@ -520,7 +520,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -677,11 +677,11 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "librt", marker = "python_full_version < '3.10' and platform_python_implementation != 'PyPy'" }, - { name = "mypy-extensions", marker = "python_full_version < '3.10'" }, - { name = "pathspec", marker = "python_full_version < '3.10'" }, - { name = "tomli", marker = "python_full_version < '3.10'" }, - { name = "typing-extensions", marker = "python_full_version < '3.10'" }, + { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "tomli" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" } wheels = [ @@ -733,12 +733,12 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "ast-serialize", marker = "python_full_version >= '3.10'" }, - { name = "librt", marker = "python_full_version >= '3.10' and platform_python_implementation != 'PyPy'" }, - { name = "mypy-extensions", marker = "python_full_version >= '3.10'" }, - { name = "pathspec", marker = "python_full_version >= '3.10'" }, - { name = "tomli", marker = "python_full_version == '3.10.*'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.10'" }, + { name = "ast-serialize" }, + { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/82/15/cca9d88503549ed6fedeaa1d448cdddd542ee8a490232d732e278036fbf2/mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633", size = 3898359, upload-time = "2026-05-11T18:37:36.237Z" } wheels = [ @@ -841,13 +841,13 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.10'" }, - { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "packaging", marker = "python_full_version < '3.10'" }, - { name = "pluggy", marker = "python_full_version < '3.10'" }, - { name = "pygments", marker = "python_full_version < '3.10'" }, - { name = "tomli", marker = "python_full_version < '3.10'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup" }, + { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli" }, ] 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 = [ @@ -863,13 +863,13 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version == '3.10.*'" }, - { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "packaging", marker = "python_full_version >= '3.10'" }, - { name = "pluggy", marker = "python_full_version >= '3.10'" }, - { name = "pygments", marker = "python_full_version >= '3.10'" }, - { name = "tomli", marker = "python_full_version == '3.10.*'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } wheels = [ @@ -892,6 +892,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, ] +[[package]] +name = "pytest-timeout" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "pytest", version = "9.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -964,10 +977,10 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "certifi", marker = "python_full_version < '3.10'" }, - { name = "charset-normalizer", marker = "python_full_version < '3.10'" }, - { name = "idna", marker = "python_full_version < '3.10'" }, - { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ @@ -983,10 +996,10 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "certifi", marker = "python_full_version >= '3.10'" }, - { name = "charset-normalizer", marker = "python_full_version >= '3.10'" }, - { name = "idna", marker = "python_full_version >= '3.10'" }, - { name = "urllib3", version = "2.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3", version = "2.7.0", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/24/36/7180e7f077c38108945dbbdf60fe04db681c3feb6e96419f8c6dc8723741/requests-2.34.1.tar.gz", hash = "sha256:0fc5669f2b69704449fe1552360bd2a73a54512dfd03e65529157f1513322beb", size = 142783, upload-time = "2026-05-13T19:20:24.662Z" } wheels = [ @@ -1027,7 +1040,7 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "botocore", version = "1.42.97", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "botocore", version = "1.42.97", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/46/29/af14f4ef3c11a50435308660e2cc68761c9a7742475e0585cd4396b91777/s3transfer-0.16.1.tar.gz", hash = "sha256:8e424355754b9ccb32467bdc568edf55be82692ef2002d934b1311dbb3b9e524", size = 154801, upload-time = "2026-04-22T20:36:06.475Z" } wheels = [ @@ -1043,7 +1056,7 @@ resolution-markers = [ "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "botocore", version = "1.43.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "botocore", version = "1.43.7", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/9b/ec/7c692cde9125b77e84b307354d4fb705f98b8ccad59a036d5957ca75bfc3/s3transfer-0.17.0.tar.gz", hash = "sha256:9edeb6d1c3c2f89d6050348548834ad8289610d886e5bf7b7207728bd43ce33a", size = 155337, upload-time = "2026-04-29T22:07:36.33Z" } wheels = [ @@ -1067,11 +1080,11 @@ resolution-markers = [ "python_full_version < '3.9.2'", ] dependencies = [ - { name = "docker", marker = "python_full_version < '3.9.2'" }, - { name = "python-dotenv", version = "1.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9.2'" }, - { name = "typing-extensions", marker = "python_full_version < '3.9.2'" }, - { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9.2'" }, - { name = "wrapt", marker = "python_full_version < '3.9.2'" }, + { name = "docker" }, + { name = "python-dotenv", version = "1.2.1", source = { registry = "https://pypi.org/simple" } }, + { name = "typing-extensions" }, + { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" } }, + { name = "wrapt" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d7/e5/807161552b8bf7072d63a21d5fd3c7df54e29420e325d50b9001571fcbb6/testcontainers-4.13.0.tar.gz", hash = "sha256:ee2bc39324eeeeb710be779208ae070c8373fa9058861859203f536844b0f412", size = 77824, upload-time = "2025-09-09T13:23:49.976Z" } wheels = [ @@ -1086,11 +1099,11 @@ resolution-markers = [ "python_full_version >= '3.9.2' and python_full_version < '3.10'", ] dependencies = [ - { name = "docker", marker = "python_full_version >= '3.9.2' and python_full_version < '3.10'" }, - { name = "python-dotenv", version = "1.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9.2' and python_full_version < '3.10'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.9.2' and python_full_version < '3.10'" }, - { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9.2' and python_full_version < '3.10'" }, - { name = "wrapt", marker = "python_full_version >= '3.9.2' and python_full_version < '3.10'" }, + { name = "docker" }, + { name = "python-dotenv", version = "1.2.1", source = { registry = "https://pypi.org/simple" } }, + { name = "typing-extensions" }, + { name = "urllib3", version = "1.26.20", source = { registry = "https://pypi.org/simple" } }, + { name = "wrapt" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/b3/c272537f3ea2f312555efeb86398cc382cd07b740d5f3c730918c36e64e1/testcontainers-4.13.3.tar.gz", hash = "sha256:9d82a7052c9a53c58b69e1dc31da8e7a715e8b3ec1c4df5027561b47e2efe646", size = 79064, upload-time = "2025-11-14T05:08:47.584Z" } wheels = [ @@ -1099,22 +1112,22 @@ wheels = [ [[package]] name = "testcontainers" -version = "4.14.2" +version = "4.15.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15'", "python_full_version >= '3.10' and python_full_version < '3.15'", ] dependencies = [ - { name = "docker", marker = "python_full_version >= '3.10'" }, - { name = "python-dotenv", version = "1.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.10'" }, - { name = "urllib3", version = "2.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "wrapt", marker = "python_full_version >= '3.10'" }, + { name = "docker" }, + { name = "python-dotenv", version = "1.2.2", source = { registry = "https://pypi.org/simple" } }, + { name = "typing-extensions" }, + { name = "urllib3", version = "2.7.0", source = { registry = "https://pypi.org/simple" } }, + { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/ac/a597c3a0e02b26cbed6dd07df68be1e57684766fd1c381dee9b170a99690/testcontainers-4.14.2.tar.gz", hash = "sha256:1340ccf16fe3acd9389a6c9e1d9ab21d9fe99a8afdf8165f89c3e69c1967d239", size = 166841, upload-time = "2026-03-18T05:19:16.696Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/13/2cc466bddf26d0085f30a2b2bd56b7f8708b54a54db833eec97c5c69129b/testcontainers-4.15.0.tar.gz", hash = "sha256:085cde086337632e19002719460b7b80bbab2bdd51bb3ea04f77d0de96504706", size = 95340, upload-time = "2026-07-24T23:08:01.731Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/2d/26b8b30067d94339afee62c3edc9b803a6eb9332f521ba77d8aaab5de873/testcontainers-4.14.2-py3-none-any.whl", hash = "sha256:0d0522c3cd8f8d9627cda41f7a6b51b639fa57bdc492923c045117933c668d68", size = 125712, upload-time = "2026-03-18T05:19:15.29Z" }, + { url = "https://files.pythonhosted.org/packages/00/7e/424aac8b355597835deb333e757a0e94b5ccf38ad00f07fe6ed1f4e17c88/testcontainers-4.15.0-py3-none-any.whl", hash = "sha256:8796c14e76604031ad39cf0ed3b8e9806283a1fbf5270965c2b1c594caa31b74", size = 160771, upload-time = "2026-07-24T23:08:00.13Z" }, ] [[package]] @@ -1124,7 +1137,7 @@ source = { editable = "." } dependencies = [ { name = "testcontainers", version = "4.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9.2'" }, { name = "testcontainers", version = "4.13.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9.2' and python_full_version < '3.10'" }, - { name = "testcontainers", version = "4.14.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "testcontainers", version = "4.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, ] [package.optional-dependencies] @@ -1138,6 +1151,7 @@ dev = [ { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "pytest", version = "9.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "pytest-cov" }, + { name = "pytest-timeout" }, { name = "ruff" }, ] @@ -1148,6 +1162,7 @@ requires-dist = [ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.0" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.0" }, + { name = "pytest-timeout", marker = "extra == 'dev'", specifier = ">=2.3" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.4" }, { name = "testcontainers", specifier = ">=4.0.0" }, ] From 798bfcbccbcd2b6def8d1fcda238ccfed5e2e0d4 Mon Sep 17 00:00:00 2001 From: Hector Ventura Date: Tue, 6 Oct 2026 20:50:18 -0500 Subject: [PATCH 2/3] ci: install dependencies from uv.lock CI ran pip install -e ".[dev]", which ignores uv.lock and pulls the newest release of every dev tool. A ruff release that started formatting Markdown code blocks broke the format check with no change in this repo, and the CI and local toolchains had drifted apart (ruff 0.16.10 in CI against 0.15.12 in the lock). Install with uv sync --locked and run every tool through uv run, so CI uses exactly the versions in the lockfile and fails when the lock is out of date with pyproject.toml. Signed-off-by: Hector Ventura --- .github/workflows/ci.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f0c108..596702a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,21 +13,22 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: python-version: "3.12" + enable-cache: true - name: Install dev dependencies - run: pip install -e ".[dev]" + run: uv sync --locked --extra dev - name: Ruff lint - run: ruff check . + run: uv run ruff check . - name: Ruff format check - run: ruff format --check . + run: uv run ruff format --check . - name: Mypy - run: mypy floci + run: uv run mypy floci test-unit: name: Unit tests (Python ${{ matrix.python-version }}) @@ -38,15 +39,16 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: python-version: ${{ matrix.python-version }} + enable-cache: true - name: Install dependencies - run: pip install -e ".[dev]" + run: uv sync --locked --extra dev - name: Run unit tests (no Docker required) - run: pytest -m "not integration" -v + run: uv run pytest -m "not integration" -v test-integration: name: Integration tests @@ -54,15 +56,16 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: python-version: "3.12" + enable-cache: true - name: Install dependencies - run: pip install -e ".[dev]" + run: uv sync --locked --extra dev - name: Pull Floci image run: docker pull floci/floci:latest - name: Run integration tests - run: pytest -m integration -v --timeout=120 + run: uv run pytest -m integration -v --timeout=120 From 394b8d3390852222ea57c9f0a8f01655efd4f964 Mon Sep 17 00:00:00 2001 From: Hector Ventura Date: Tue, 6 Oct 2026 20:56:14 -0500 Subject: [PATCH 3/3] chore: set the mypy target to Python 3.10 mypy 2.x no longer accepts python_version = "3.9" and falls back to 3.10 with a warning. Set it explicitly. Ruff's py39 target and the 3.9 unit-test job still cover 3.9 compatibility, and requires-python is unchanged. Signed-off-by: Hector Ventura --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1f9be7c..266ad27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ target-version = "py39" select = ["E", "F", "I", "UP"] [tool.mypy] -python_version = "3.9" +python_version = "3.10" strict = true ignore_missing_imports = true