From 14d0343da5880f5d6153249d6f3022f0f6093d21 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 00:30:50 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20deps:=20Update=20Pytho?= =?UTF-8?q?n=20dev=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 +-- uv.lock | 80 +++++++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c81a94b..a136b58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,8 +35,8 @@ watchfs = "watchfs.__main__:main" [dependency-groups] dev = [ - "ty>=0.0.51", - "ruff>=0.15.18", + "ty>=0.0.55", + "ruff>=0.15.20", "pytest>=9.1.1", "pytest-rerunfailures>=16.3", "tomli>=2.4.1", diff --git a/uv.lock b/uv.lock index 1567acc..251f9e8 100644 --- a/uv.lock +++ b/uv.lock @@ -118,27 +118,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.18" +version = "0.15.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/98/1295ad5a5aa9bc85bdcdfa5d82fe7b49c61af5657df4f227637ff9de0da6/ruff-0.15.18.tar.gz", hash = "sha256:2698a964c70e8bf402dcb99c8810472d270d141e7aa8c4e13599fd52033a2f33", size = 4761437, upload-time = "2026-06-18T18:25:39.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/d0/686e984941269621e2be72612d5c1e461f8f7b38415a2a7d7a81c8ae6715/ruff-0.15.18-py3-none-linux_armv6l.whl", hash = "sha256:8b6850172348c8381b8b3084c5915a4393c2373b9b54cd5b5e1ea15812bc10df", size = 10887308, upload-time = "2026-06-18T18:25:03.062Z" }, - { url = "https://files.pythonhosted.org/packages/ed/21/bc4123e3f5515ee99f8ce1eb93a14a0628fe4d1678663cd08f933ac16931/ruff-0.15.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3fccc153a85417dcd976883160cacce486997b0a0058dd18f54b8aaaac7d1ce2", size = 11281305, upload-time = "2026-06-18T18:25:30.026Z" }, - { url = "https://files.pythonhosted.org/packages/51/93/4769464c25cf7ab2acb3c7dda9cad3d867eb41c59565b3e2a9d17249c90c/ruff-0.15.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08d4c86a68f2c3ec2c9d56380a71fb4a4f65373055cbb8caabd645e9102f38d4", size = 10641215, upload-time = "2026-06-18T18:25:15.802Z" }, - { url = "https://files.pythonhosted.org/packages/6c/42/56926d17120db2c208d76bf60a1a019644dd9e91dc27f0f95c9caddb1366/ruff-0.15.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37e5108745c2c0705da916d7d4de533ddf547051ef45f62888c31bae73f66318", size = 10957224, upload-time = "2026-06-18T18:25:36.955Z" }, - { url = "https://files.pythonhosted.org/packages/22/4f/d43fab8d8189afde803103022d000a8ef9f230616d436d52a8b2b8d63b50/ruff-0.15.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56949a6ce8b3abde54c0bcb22cebfe57e8771cadc84b407ae8b8eaf67ebdcd43", size = 10699024, upload-time = "2026-06-18T18:25:05.707Z" }, - { url = "https://files.pythonhosted.org/packages/63/42/1e3e4c68bd408b9768cf3e439acbe2c78245225faef253f7028a0cdb63e0/ruff-0.15.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a754cd6a1b630d3f97e33eb452cf7a98040482318e870f8bc52a5a30e62657", size = 11491458, upload-time = "2026-06-18T18:25:20.275Z" }, - { url = "https://files.pythonhosted.org/packages/20/77/47a3484bea8521e14a203d98c389c5c97846675e4f02734672da4a69b52a/ruff-0.15.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba7a07e03a44dbf10bb086ee06705b173625014ec99f73a7e6836a5e5590a0c", size = 12383752, upload-time = "2026-06-18T18:25:22.535Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ca/054159590787023d83b658a1a1819c4c8910114e7015069340b71c0961cb/ruff-0.15.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a2c40a41a4cadbcf5897b548ab29dfe248b20c540961c0247d98a3973c70403", size = 11577923, upload-time = "2026-06-18T18:25:10.702Z" }, - { url = "https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d", size = 11583925, upload-time = "2026-06-18T18:25:32.391Z" }, - { url = "https://files.pythonhosted.org/packages/c1/4a/891f89b9c296ed3e5f3ece1a5629badc989d9a8fdaa30431aaf4774bc1c2/ruff-0.15.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2330215f1f393fa8733f55edce04fcf94c36a2c460fcde31f78cc84e4951e9b1", size = 11582834, upload-time = "2026-06-18T18:25:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/32/a3/ed9e370154bf85de360b93c03026157f02d4943b2d01ff4945f4429f8e8a/ruff-0.15.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a6aa6a3d979e48ae617578183674bf264fbe7d0114a796a26bd678d67963c7ff", size = 10927328, upload-time = "2026-06-18T18:25:34.676Z" }, - { url = "https://files.pythonhosted.org/packages/f5/d1/5cf5909329fedb5d39d555ee818ba5cf4638e1a301b89785d34f2905bfcb/ruff-0.15.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a81beadbbff2c9c245561ae3f77b16709d87f35eec650d0501679239d3449b22", size = 10693187, upload-time = "2026-06-18T18:25:08.245Z" }, - { url = "https://files.pythonhosted.org/packages/fd/44/ff6c635cf2c4f4e7b618b6640da057376baa36014695487d88aed4794268/ruff-0.15.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2186d9e940ae332ab293623a75b5f4fe49565f449954d50a72a046683aa6b809", size = 11208721, upload-time = "2026-06-18T18:25:41.327Z" }, - { url = "https://files.pythonhosted.org/packages/88/d9/5baa2a30861adfb7022cf33c1e35b2fc18085b08c16f83eff4c7b99a5f48/ruff-0.15.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c2abf140438032bc77b2284a6c9944ecd8a19e5f1c7b52b1b8e4a0a80d19a7a", size = 11678599, upload-time = "2026-06-18T18:25:13.607Z" }, - { url = "https://files.pythonhosted.org/packages/c3/1a/0725a7cfdc32ff769efb96ee782bec882e16448c5d9e3be947ec4c04ce27/ruff-0.15.18-py3-none-win32.whl", hash = "sha256:02299e6e9fa5b297a3f6d5d10d7bcd655c925b028bb8b9d4588214549c6b9ec4", size = 10901903, upload-time = "2026-06-18T18:25:24.755Z" }, - { url = "https://files.pythonhosted.org/packages/f3/51/805d9f6fb7970505c3504794a5ec350f605361b807fef4dcf214ebd35e72/ruff-0.15.18-py3-none-win_amd64.whl", hash = "sha256:dac80dc8d26b2257dbefabed62f5d255c3937b4ccb122da1fc634794fa3578b3", size = 12041189, upload-time = "2026-06-18T18:25:17.915Z" }, - { url = "https://files.pythonhosted.org/packages/29/4c/67bb45e41609eb4726f1bfeb59e083cf91d14c696d4bd14c234a980be93d/ruff-0.15.18-py3-none-win_arm64.whl", hash = "sha256:b2c9257fcbd4a3e5b977a1904e6facca016bafe2edc17df24db67cfaee03b4e4", size = 11329958, upload-time = "2026-06-18T18:25:43.686Z" }, + { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" }, + { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" }, + { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" }, + { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" }, + { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" }, + { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" }, + { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, ] [[package]] @@ -197,27 +197,27 @@ wheels = [ [[package]] name = "ty" -version = "0.0.51" +version = "0.0.55" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/ce/352fcdba5c72ea20e5d2e46e28809cdb617575b71209d971eff2ace8e6c4/ty-0.0.51.tar.gz", hash = "sha256:b90172d46365bb9d51a7011cbb5c60cc4f514f42c86635df6c092b717f85e1ac", size = 5953151, upload-time = "2026-06-19T01:48:58.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/48/f687c8d268e3581f2f104d1f2ac5944d5b5e841b3695c613b3f263e5bbf7/ty-0.0.55.tar.gz", hash = "sha256:88ca87073825a79a8327c550efcc86cec94344890244c5946f84c9e44a969f31", size = 6040230, upload-time = "2026-06-27T00:27:29.385Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/8f/8fe7cab79a45320b2cdcd602f16d44c8108d2f418ff7ec316c6212f1f0cc/ty-0.0.51-py3-none-linux_armv6l.whl", hash = "sha256:947986bd82d324b3a5c58ce03f1dad160cdf36443d3e8f64b3484b861ba9bc64", size = 11884805, upload-time = "2026-06-19T01:48:20.184Z" }, - { url = "https://files.pythonhosted.org/packages/fa/b4/56fdc39a3f44c0564fd157e1e59e1f9c3fc5ba57ae4472ded85c67c63d74/ty-0.0.51-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25a5b31e6f23fd5dc63ad29087ded09932409e4154e2fe07bbaed015035990bb", size = 11633593, upload-time = "2026-06-19T01:48:22.998Z" }, - { url = "https://files.pythonhosted.org/packages/33/57/136e83f24fc04f5afdcabff42f40fa27eae5ac3f0e3f12627d072a55f679/ty-0.0.51-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2faed19a8f1505370de071c008df52a994fc03a204f3267c3a33a32ca26f854f", size = 11063076, upload-time = "2026-06-19T01:48:25.223Z" }, - { url = "https://files.pythonhosted.org/packages/32/f8/5d32f0df5692446440ab781b9b119aa3e0c0dbfa78c583fe9be8417d54fa/ty-0.0.51-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08adbe53fb8bc9e7f00e89bf1d3c875a02cda76d83f109d2e6ab1ff35a7bfa8c", size = 11579542, upload-time = "2026-06-19T01:48:27.302Z" }, - { url = "https://files.pythonhosted.org/packages/7f/0c/4f54ef338e9623886809ecd508931b0cd5b3aba1e591586a2f6aeaa8bd11/ty-0.0.51-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc5e93695ab5dcbf1eef663aee60ec23a413547cc9cb06adcb0d842e9166bd0f", size = 11676189, upload-time = "2026-06-19T01:48:29.518Z" }, - { url = "https://files.pythonhosted.org/packages/56/27/31729066f9b9d3596941edaf267894eefc0b30df4518f003dba5f7276258/ty-0.0.51-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd92913bc90d1705ef9391ff8c6822b61e2e827fa295eb30bf0dfabcf815645", size = 12188154, upload-time = "2026-06-19T01:48:31.68Z" }, - { url = "https://files.pythonhosted.org/packages/2f/38/d4301aa12d2283c7130908baf1417a37dfe3e10f5669cb4ce2853c2540b4/ty-0.0.51-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:429a997394dac73870d71b87cc90efc54da3efaf319e72ca18aeef35a78aef90", size = 12780597, upload-time = "2026-06-19T01:48:33.839Z" }, - { url = "https://files.pythonhosted.org/packages/c1/52/4b2e67e53f126d39abe201bd2299e467e27463a284e965ad195cbc217fa0/ty-0.0.51-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62d94f06e8c317e89b6884f2bde443040e596b88c7c79bd944c84c105b06257a", size = 12491115, upload-time = "2026-06-19T01:48:36.169Z" }, - { url = "https://files.pythonhosted.org/packages/74/50/aabfe55c132ebe72b4d639cbf772d931e11b0990d29c1f691922b6ccabc1/ty-0.0.51-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8f52952cff665bc52a36147e610c10f5699d30007d7a14ab7f345cff93476ff", size = 12230135, upload-time = "2026-06-19T01:48:38.445Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1b/9aa428052dbed91c50919cd080426a313cf20ce14c6bfe2b71345e548671/ty-0.0.51-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c1bd1355aee86af01e4e21b0bc16fc460fb05905761f0d8b8d70841de0feade8", size = 12468123, upload-time = "2026-06-19T01:48:40.47Z" }, - { url = "https://files.pythonhosted.org/packages/0b/5a/f6ce69f2575259386c950c40e02578d0902760cb61f95045e9971182c24e/ty-0.0.51-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:79d1877e93460f936bc10ed1a31525702b7ce51075763ccba993be17f0b9e905", size = 11541672, upload-time = "2026-06-19T01:48:42.635Z" }, - { url = "https://files.pythonhosted.org/packages/35/3a/2af48924a683e959e95e5cc4dc88e5a8595206a0812b869032b95196f2b0/ty-0.0.51-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:cc233a6235fb23e2a44b14731a10043e37ba2f30f2c361cf49ad3633c5b9da9c", size = 11694015, upload-time = "2026-06-19T01:48:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/a4/12/899875d8a60b198c8121cb92ce18e18cc072d23ca2130fcdaa176383ef72/ty-0.0.51-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bc7459348a253247bbfb2669a021e614281b86bbea24c36112b8a6e1a2499a16", size = 11832856, upload-time = "2026-06-19T01:48:47.028Z" }, - { url = "https://files.pythonhosted.org/packages/e6/a2/88f681d826d97cc96ef9f6cadd4935f775758944cee07340aa46113bce28/ty-0.0.51-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:49a21237f6fd1de56beaff0a3e85fe022a09a3401e67e3abec41ce838a5d4d2e", size = 12333449, upload-time = "2026-06-19T01:48:49.091Z" }, - { url = "https://files.pythonhosted.org/packages/f8/61/535a4163b4452c6978c31fedfd7b5803cf3a2253e9455cde350f86638d6a/ty-0.0.51-py3-none-win32.whl", hash = "sha256:61b4b6a003c3ebe53a63a1125c9b6542aa01bc1b6c9a235d01ee328d000d61a9", size = 11177338, upload-time = "2026-06-19T01:48:51.433Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4d/2334fbb74291a20129fa7aaa8f789619ec9b6883b27f997b8baa27e4674f/ty-0.0.51-py3-none-win_amd64.whl", hash = "sha256:608d417cd1eaf79bcbd713d9830d5e3db9d57ec225c3af3e4ac9a9ff66b45d70", size = 12325675, upload-time = "2026-06-19T01:48:53.774Z" }, - { url = "https://files.pythonhosted.org/packages/50/b5/d49096cd5f3694becb86a5a6ccd0f229ead695fc7430d6bc4dd0a104c6fe/ty-0.0.51-py3-none-win_arm64.whl", hash = "sha256:62ced5e380284f12b2dc4802a3e4ed3dac39913fc6719afde7978814a4c7f169", size = 11657350, upload-time = "2026-06-19T01:48:55.904Z" }, + { url = "https://files.pythonhosted.org/packages/87/a3/1a90ba7e5a61c6d09adb92346ddba97668095fc257b577af433e5ac4f404/ty-0.0.55-py3-none-linux_armv6l.whl", hash = "sha256:31e83eef512d066542fe990fe1a3b814423abd1616376c54e48af7045b3e1749", size = 11677249, upload-time = "2026-06-27T00:26:52.18Z" }, + { url = "https://files.pythonhosted.org/packages/82/3a/669f9aa478c38243e213a2684db1502086026cfadc15bb1b29b7cbde030d/ty-0.0.55-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab4bca857950608fea73e269e2da369d43e6467131de85160d68e2fa466fa248", size = 11444180, upload-time = "2026-06-27T00:26:54.576Z" }, + { url = "https://files.pythonhosted.org/packages/15/a4/6a4b2507a53ce6530c66c5b4fe0d58551eb1748ffa9e0696c32fdd55bbd4/ty-0.0.55-py3-none-macosx_11_0_arm64.whl", hash = "sha256:55032bfd31bf2c5355ee81bdc6407b144a1cc7ee41e5681dd1368e4cef2ba327", size = 10963134, upload-time = "2026-06-27T00:26:57.348Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ae/a3b1a0f1cc83b7d258662cb98aa80a720c2e671d0e8fa0d17a4d5d057a7a/ty-0.0.55-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef1e049f69ce65b3c269af67624607f435e1c32319786c1e453ef9611502f295", size = 11493517, upload-time = "2026-06-27T00:26:59.26Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9f/311ce39065a979ef40a9b847f685c8e02464e53adf1671e081eea90640ca/ty-0.0.55-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:631409975c681d5a280fc5a99b7b32e9e801f33be7567c6b42ec331362f59d7d", size = 11460590, upload-time = "2026-06-27T00:27:01.425Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8f/3bf29aa77bd78aae48275153135a2052fa7d3ccdf1ecabeb99c8773abd66/ty-0.0.55-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e08cb0436e68b9351555ae8f2697138c9009b4d5b4ae4272232988b2a431a98f", size = 12098430, upload-time = "2026-06-27T00:27:03.596Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6e/e88411a88240b94640bba06fb6d0d92b247fbeef47ee2bc71f39e58c2558/ty-0.0.55-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16c215ad9f823829409b94ee188cfaa4563f6e1384f6ce3fecb1db75f6c7cf7c", size = 12673086, upload-time = "2026-06-27T00:27:05.589Z" }, + { url = "https://files.pythonhosted.org/packages/6c/7e/8f1762fb7f9245a68ba5ae338d73c59403ce57554e5d311b8bb55027b0ec/ty-0.0.55-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b510eb8f4032baf11b7aee2f1d53babc3b4ca03939b9cdcf6a9d15761d575188", size = 12242559, upload-time = "2026-06-27T00:27:07.714Z" }, + { url = "https://files.pythonhosted.org/packages/72/1f/143657daf2670d977dac83435f1fe03d4843efb798d8e1e75950e541aadd/ty-0.0.55-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ddc05e7959709c3b9b83aa627128a80446865e3c1a4882638dcff6d776dc34a", size = 12021409, upload-time = "2026-06-27T00:27:09.881Z" }, + { url = "https://files.pythonhosted.org/packages/6d/30/69487c439dd1fad3a4a3d96f0a472193de297eaba6fc4b8ea687ce434ac2/ty-0.0.55-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:636e8e5078787b8c6916c94e1406719f10189a4ca6b37b813a5922ce5857a8c7", size = 12303807, upload-time = "2026-06-27T00:27:11.986Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ca/cd88b6493dafc7db077f5e17c0438eb3af6e2d6d08f616dbb52a8ddfd567/ty-0.0.55-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ef7d6deaacb73fec603666b5471f1dc5a5699aa84e11a6d4d644dd07ca72121e", size = 11441263, upload-time = "2026-06-27T00:27:14.087Z" }, + { url = "https://files.pythonhosted.org/packages/aa/fe/66b6915671653ab739f71e4f1b0528e69da64429b7ebf3840c625b6e43f2/ty-0.0.55-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9aeea0fe5875d3cf37faf0e44d0fdf9669335467749741b8fc0103916fb5cd32", size = 11484584, upload-time = "2026-06-27T00:27:16.311Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4f/7a9c0bbac8b899e9f6c0ec110c6612f52e4db35f6bb17ddc0ef60384fa3e/ty-0.0.55-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0b699c01310dbd2705a07c97c5f4aaeedef61bd9adeea2e7c46aed32401d3576", size = 11759309, upload-time = "2026-06-27T00:27:18.471Z" }, + { url = "https://files.pythonhosted.org/packages/ca/de/b6f8b1b69aa631b5716ef3f985c3b56de0e46c2499cc00d30c402b41f714/ty-0.0.55-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:32cbeba543e46de2a983ec6d525d8b56514f7422bd1e1b57c44ccf7bfa72c38a", size = 12128755, upload-time = "2026-06-27T00:27:20.55Z" }, + { url = "https://files.pythonhosted.org/packages/7d/90/a912531e51ee7e076b42972479290fa687c0f5e747b7e773f3033164acaa/ty-0.0.55-py3-none-win32.whl", hash = "sha256:52b968e24eb4f7a5c3bd251db1f99f60dd385890356d38fc619d84f1b423446a", size = 11117501, upload-time = "2026-06-27T00:27:22.714Z" }, + { url = "https://files.pythonhosted.org/packages/4c/7a/99d59843bf8908a7f9f4d13fda107dbad07b7faa28ecd7860eacf363fb1c/ty-0.0.55-py3-none-win_amd64.whl", hash = "sha256:bf39cbfdc0add44d94bd3fff1f53c351418d134b6a66b87efdb7876d7b7a2224", size = 12150106, upload-time = "2026-06-27T00:27:24.881Z" }, + { url = "https://files.pythonhosted.org/packages/b3/44/20987505cedf2a865b08482f0eabc181fd9599b062964057ec8a128a4296/ty-0.0.55-py3-none-win_arm64.whl", hash = "sha256:f7f3700a9a060e8f1af11e4fb63fafcaf272b041781f4ccdfda2b3b5c6c1e439", size = 11560157, upload-time = "2026-06-27T00:27:27.332Z" }, ] [[package]] @@ -328,7 +328,7 @@ requires-dist = [ dev = [ { name = "pytest", specifier = ">=9.1.1" }, { name = "pytest-rerunfailures", specifier = ">=16.3" }, - { name = "ruff", specifier = ">=0.15.18" }, + { name = "ruff", specifier = ">=0.15.20" }, { name = "tomli", specifier = ">=2.4.1" }, - { name = "ty", specifier = ">=0.0.51" }, + { name = "ty", specifier = ">=0.0.55" }, ] From 250f18a1933fa3f875de8ad9e2911474a18013af Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 16:58:19 +0000 Subject: [PATCH 2/4] fix: satisfy stricter ty result narrowing --- src/watchfs/__main__.py | 26 ++--- src/watchfs/mappings.py | 61 ++++++------ tests/test_watchfs.py | 206 +++++++++++++++++++--------------------- 3 files changed, 141 insertions(+), 152 deletions(-) diff --git a/src/watchfs/__main__.py b/src/watchfs/__main__.py index ba71481..d24ba23 100644 --- a/src/watchfs/__main__.py +++ b/src/watchfs/__main__.py @@ -5,7 +5,7 @@ import sys from dataclasses import dataclass from pathlib import Path -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, cast from colored import Back, Fore from watchfiles import Change, awatch @@ -127,17 +127,19 @@ async def main(): args = parser.parse_args() parsed_sync_mapping: list[SyncMapping] = [] for sync_src_with_dst in args.sync_mapping: - match parse_sync_mapping(sync_src_with_dst): - case Ok((mapping, bidirectional)): - parsed_sync_mapping.append(mapping) - if bidirectional: - match parse_sync_mapping(f"{mapping.target.display()}->{mapping.source}"): - case Ok((reverse_mapping, _)): - parsed_sync_mapping.append(reverse_mapping) - case Err(err): - raise err - case Err(err): - raise err + parsed_mapping = parse_sync_mapping(sync_src_with_dst) + if isinstance(parsed_mapping, Err): + raise cast("Err[Exception]", parsed_mapping).err() + + mapping, bidirectional = cast("Ok[tuple[SyncMapping, bool]]", parsed_mapping).ok() + parsed_sync_mapping.append(mapping) + if bidirectional: + reverse_mapping_result = parse_sync_mapping(f"{mapping.target.display()}->{mapping.source}") + if isinstance(reverse_mapping_result, Err): + raise cast("Err[Exception]", reverse_mapping_result).err() + + reverse_mapping, _ = cast("Ok[tuple[SyncMapping, bool]]", reverse_mapping_result).ok() + parsed_sync_mapping.append(reverse_mapping) jobs = [ SyncJob( diff --git a/src/watchfs/mappings.py b/src/watchfs/mappings.py index 96e568e..47e4f38 100644 --- a/src/watchfs/mappings.py +++ b/src/watchfs/mappings.py @@ -3,6 +3,7 @@ import re from dataclasses import dataclass from pathlib import Path, PurePosixPath +from typing import cast from urllib.parse import urlparse from watchfs.exceptions import ParseError @@ -77,37 +78,35 @@ def parse_target_spec(spec: str) -> Result[TargetSpec, ParseError]: def parse_sync_mapping(sync_mapping: str) -> Result[tuple[SyncMapping, bool], ParseError]: - match _split_sync_mapping(sync_mapping): - case Err(err): - return Err(err) - case Ok((src_dir, dst_dir, bidirectional)): - match parse_target_spec(src_dir): - case Err(err): - return Err(err) - case Ok(src_spec): - if isinstance(src_spec, SshTargetSpec): - return Err(ParseError("Remote source is not supported yet. Source must be a local path.")) - - match parse_target_spec(dst_dir): - case Err(err): - return Err(err) - case Ok(dst_spec): - if isinstance(dst_spec, SshTargetSpec) and bidirectional: - return Err( - ParseError("Bidirectional sync is not supported when the destination is an SSH target.") - ) - - if isinstance(dst_spec, LocalTargetSpec): - abs_src_dir = src_spec.path.resolve() - abs_dst_dir = dst_spec.path.resolve() - if abs_src_dir in abs_dst_dir.parents: - return Err( - ParseError(f"dst_dir({abs_dst_dir}) is a subdirectory of src_dir({abs_src_dir}).") - ) - - return Ok((SyncMapping(source=src_spec.path, target=dst_spec), bidirectional)) - - raise AssertionError("unreachable") + split_result = _split_sync_mapping(sync_mapping) + if isinstance(split_result, Err): + return cast("Err[ParseError]", split_result) + + src_dir, dst_dir, bidirectional = cast("Ok[tuple[str, str, bool]]", split_result).ok() + + src_result = parse_target_spec(src_dir) + if isinstance(src_result, Err): + return cast("Err[ParseError]", src_result) + + src_spec = cast("Ok[TargetSpec]", src_result).ok() + if isinstance(src_spec, SshTargetSpec): + return Err(ParseError("Remote source is not supported yet. Source must be a local path.")) + + dst_result = parse_target_spec(dst_dir) + if isinstance(dst_result, Err): + return cast("Err[ParseError]", dst_result) + + dst_spec = cast("Ok[TargetSpec]", dst_result).ok() + if isinstance(dst_spec, SshTargetSpec) and bidirectional: + return Err(ParseError("Bidirectional sync is not supported when the destination is an SSH target.")) + + if isinstance(dst_spec, LocalTargetSpec): + abs_src_dir = src_spec.path.resolve() + abs_dst_dir = dst_spec.path.resolve() + if abs_src_dir in abs_dst_dir.parents: + return Err(ParseError(f"dst_dir({abs_dst_dir}) is a subdirectory of src_dir({abs_src_dir}).")) + + return Ok((SyncMapping(source=src_spec.path, target=dst_spec), bidirectional)) def _parse_ssh_url(spec: str) -> Result[SshTargetSpec, ParseError]: diff --git a/tests/test_watchfs.py b/tests/test_watchfs.py index 81df648..d8bf8e8 100644 --- a/tests/test_watchfs.py +++ b/tests/test_watchfs.py @@ -2,11 +2,13 @@ import tomllib from pathlib import Path, PurePosixPath +from typing import cast from watchfs import __version__ from watchfs.__main__ import build_queue_key +from watchfs.exceptions import ParseError from watchfs.mappings import LocalTargetSpec, SshTargetSpec, parse_sync_mapping, parse_target_spec -from watchfs.rusty import Err, Ok +from watchfs.rusty import Err, Ok, Result with Path("pyproject.toml").open("rb") as f: project_info = tomllib.load(f) @@ -16,155 +18,141 @@ def test_version(): assert __version__ == project_info["project"]["version"] +def expect_ok[T](result: Result[T, Exception], message: str) -> T: + assert isinstance(result, Ok), message + return cast("Ok[T]", result).ok() + + +def expect_err[E: Exception](result: Result[object, E], message: str) -> E: + assert isinstance(result, Err), message + return cast("Err[E]", result).err() + + def test_parse_local_mapping_with_arrow(): - match parse_sync_mapping("src->dst"): - case Ok((mapping, bidirectional)): - assert mapping.source == Path("src") - assert mapping.target == LocalTargetSpec(Path("dst")) - assert bidirectional is False - case _: - raise AssertionError("expected local mapping to parse") + mapping, bidirectional = expect_ok(parse_sync_mapping("src->dst"), "expected local mapping to parse") + assert mapping.source == Path("src") + assert mapping.target == LocalTargetSpec(Path("dst")) + assert bidirectional is False def test_parse_local_mapping_with_legacy_colon(): - match parse_sync_mapping("src:dst"): - case Ok((mapping, bidirectional)): - assert mapping.source == Path("src") - assert mapping.target == LocalTargetSpec(Path("dst")) - assert bidirectional is False - case _: - raise AssertionError("expected local legacy mapping to parse") + mapping, bidirectional = expect_ok(parse_sync_mapping("src:dst"), "expected local legacy mapping to parse") + assert mapping.source == Path("src") + assert mapping.target == LocalTargetSpec(Path("dst")) + assert bidirectional is False def test_parse_windows_drive_paths_as_local_targets(): - match parse_target_spec("C:/src"): - case Ok(LocalTargetSpec(path)): - assert path == Path("C:/src") - case _: - raise AssertionError("expected Windows drive path to parse as local") + target = expect_ok(parse_target_spec("C:/src"), "expected Windows drive path to parse as local") + assert isinstance(target, LocalTargetSpec) + assert target.path == Path("C:/src") def test_parse_windows_local_mapping_with_arrow(): - match parse_sync_mapping("C:/src->D:/dst"): - case Ok((mapping, bidirectional)): - assert mapping.source == Path("C:/src") - assert mapping.target == LocalTargetSpec(Path("D:/dst")) - assert bidirectional is False - case _: - raise AssertionError("expected Windows arrow mapping to parse") + mapping, bidirectional = expect_ok(parse_sync_mapping("C:/src->D:/dst"), "expected Windows arrow mapping to parse") + assert mapping.source == Path("C:/src") + assert mapping.target == LocalTargetSpec(Path("D:/dst")) + assert bidirectional is False def test_parse_windows_local_mapping_with_legacy_colon(): - match parse_sync_mapping("C:/src:D:/dst"): - case Ok((mapping, bidirectional)): - assert mapping.source == Path("C:/src") - assert mapping.target == LocalTargetSpec(Path("D:/dst")) - assert bidirectional is False - case _: - raise AssertionError("expected Windows legacy mapping to parse") + mapping, bidirectional = expect_ok( + parse_sync_mapping("C:/src:D:/dst"), "expected Windows legacy mapping to parse" + ) + assert mapping.source == Path("C:/src") + assert mapping.target == LocalTargetSpec(Path("D:/dst")) + assert bidirectional is False def test_parse_ssh_target_mapping(): - match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs"): - case Ok((mapping, bidirectional)): - assert mapping.source == Path("src") - assert mapping.target == SshTargetSpec( - host="192.168.66.1", - path=PurePosixPath("/tmp/watchfs"), - username="meow", - ) - assert bidirectional is False - case _: - raise AssertionError("expected ssh mapping to parse") + mapping, bidirectional = expect_ok( + parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs"), "expected ssh mapping to parse" + ) + assert mapping.source == Path("src") + assert mapping.target == SshTargetSpec( + host="192.168.66.1", + path=PurePosixPath("/tmp/watchfs"), + username="meow", + ) + assert bidirectional is False def test_parse_ssh_target_mapping_with_home_path(): - match parse_sync_mapping("~/Projects/watchfs->meow@192.168.66.1:~/Projects/watchfs"): - case Ok((mapping, bidirectional)): - assert mapping.source == Path("~/Projects/watchfs").expanduser() - assert mapping.target == SshTargetSpec( - host="192.168.66.1", - path=PurePosixPath("~/Projects/watchfs"), - username="meow", - ) - assert bidirectional is False - case _: - raise AssertionError("expected ssh home mapping to parse") + mapping, bidirectional = expect_ok( + parse_sync_mapping("~/Projects/watchfs->meow@192.168.66.1:~/Projects/watchfs"), + "expected ssh home mapping to parse", + ) + assert mapping.source == Path("~/Projects/watchfs").expanduser() + assert mapping.target == SshTargetSpec( + host="192.168.66.1", + path=PurePosixPath("~/Projects/watchfs"), + username="meow", + ) + assert bidirectional is False def test_parse_ssh_url_target_mapping(): - match parse_sync_mapping("src->ssh://meow@example.com:2222/tmp/watchfs"): - case Ok((mapping, _)): - assert mapping.target == SshTargetSpec( - host="example.com", - path=PurePosixPath("/tmp/watchfs"), - username="meow", - port=2222, - ) - case _: - raise AssertionError("expected ssh url mapping to parse") + mapping, _ = expect_ok(parse_sync_mapping("src->ssh://meow@example.com:2222/tmp/watchfs"), "expected ssh url mapping to parse") + assert mapping.target == SshTargetSpec( + host="example.com", + path=PurePosixPath("/tmp/watchfs"), + username="meow", + port=2222, + ) def test_reject_remote_source(): - match parse_sync_mapping("meow@192.168.66.1:/tmp/src->dst"): - case Err(err): - assert "Remote source is not supported" in err.message - case _: - raise AssertionError("expected remote source to be rejected") + err = expect_err(parse_sync_mapping("meow@192.168.66.1:/tmp/src->dst"), "expected remote source to be rejected") + assert isinstance(err, ParseError) + assert "Remote source is not supported" in err.message def test_reject_bidirectional_remote_mapping(): - match parse_sync_mapping("src<->meow@192.168.66.1:/tmp/watchfs"): - case Err(err): - assert "Bidirectional sync is not supported" in err.message - case _: - raise AssertionError("expected bidirectional ssh mapping to be rejected") + err = expect_err( + parse_sync_mapping("src<->meow@192.168.66.1:/tmp/watchfs"), + "expected bidirectional ssh mapping to be rejected", + ) + assert isinstance(err, ParseError) + assert "Bidirectional sync is not supported" in err.message def test_reject_local_destination_nested_under_source_message(): - match parse_sync_mapping("src:src/nested"): - case Err(err): - assert "dst_dir(" in err.message - assert "is a subdirectory of src_dir(" in err.message - case _: - raise AssertionError("expected nested local destination to be rejected") + err = expect_err(parse_sync_mapping("src:src/nested"), "expected nested local destination to be rejected") + assert isinstance(err, ParseError) + assert "dst_dir(" in err.message + assert "is a subdirectory of src_dir(" in err.message def test_reject_ambiguous_remote_mapping_without_arrow(): - match parse_sync_mapping("src:meow@192.168.66.1:/tmp/watchfs"): - case Err(err): - assert "Use SRC->DST" in err.message - case _: - raise AssertionError("expected ambiguous remote mapping to be rejected") + err = expect_err( + parse_sync_mapping("src:meow@192.168.66.1:/tmp/watchfs"), + "expected ambiguous remote mapping to be rejected", + ) + assert isinstance(err, ParseError) + assert "Use SRC->DST" in err.message def test_same_ssh_machine_shares_serial_queue_key(): - match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"): - case Ok((first_mapping, _)): - pass - case _: - raise AssertionError("expected first ssh mapping to parse") - - match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-b"): - case Ok((second_mapping, _)): - pass - case _: - raise AssertionError("expected second ssh mapping to parse") + first_mapping, _ = expect_ok( + parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"), + "expected first ssh mapping to parse", + ) + second_mapping, _ = expect_ok( + parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-b"), + "expected second ssh mapping to parse", + ) assert build_queue_key(first_mapping) == build_queue_key(second_mapping) def test_different_ssh_machine_uses_different_queue_key(): - match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"): - case Ok((first_mapping, _)): - pass - case _: - raise AssertionError("expected first ssh mapping to parse") - - match parse_sync_mapping("src->meow@192.168.88.2:/tmp/watchfs-b"): - case Ok((second_mapping, _)): - pass - case _: - raise AssertionError("expected second ssh mapping to parse") + first_mapping, _ = expect_ok( + parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"), + "expected first ssh mapping to parse", + ) + second_mapping, _ = expect_ok( + parse_sync_mapping("src->meow@192.168.88.2:/tmp/watchfs-b"), + "expected second ssh mapping to parse", + ) assert build_queue_key(first_mapping) != build_queue_key(second_mapping) From 8005336d9eb67ffd0d34fc068ac96d2ae001684a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:09:56 +0000 Subject: [PATCH 3/4] fix: pin ty below 0.0.55 --- pyproject.toml | 2 +- src/watchfs/__main__.py | 26 +++-- src/watchfs/mappings.py | 61 ++++++------ tests/test_watchfs.py | 206 +++++++++++++++++++++------------------- uv.lock | 40 ++++---- 5 files changed, 173 insertions(+), 162 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a136b58..755f4eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ watchfs = "watchfs.__main__:main" [dependency-groups] dev = [ - "ty>=0.0.55", + "ty>=0.0.54,<0.0.55", "ruff>=0.15.20", "pytest>=9.1.1", "pytest-rerunfailures>=16.3", diff --git a/src/watchfs/__main__.py b/src/watchfs/__main__.py index d24ba23..ba71481 100644 --- a/src/watchfs/__main__.py +++ b/src/watchfs/__main__.py @@ -5,7 +5,7 @@ import sys from dataclasses import dataclass from pathlib import Path -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from colored import Back, Fore from watchfiles import Change, awatch @@ -127,19 +127,17 @@ async def main(): args = parser.parse_args() parsed_sync_mapping: list[SyncMapping] = [] for sync_src_with_dst in args.sync_mapping: - parsed_mapping = parse_sync_mapping(sync_src_with_dst) - if isinstance(parsed_mapping, Err): - raise cast("Err[Exception]", parsed_mapping).err() - - mapping, bidirectional = cast("Ok[tuple[SyncMapping, bool]]", parsed_mapping).ok() - parsed_sync_mapping.append(mapping) - if bidirectional: - reverse_mapping_result = parse_sync_mapping(f"{mapping.target.display()}->{mapping.source}") - if isinstance(reverse_mapping_result, Err): - raise cast("Err[Exception]", reverse_mapping_result).err() - - reverse_mapping, _ = cast("Ok[tuple[SyncMapping, bool]]", reverse_mapping_result).ok() - parsed_sync_mapping.append(reverse_mapping) + match parse_sync_mapping(sync_src_with_dst): + case Ok((mapping, bidirectional)): + parsed_sync_mapping.append(mapping) + if bidirectional: + match parse_sync_mapping(f"{mapping.target.display()}->{mapping.source}"): + case Ok((reverse_mapping, _)): + parsed_sync_mapping.append(reverse_mapping) + case Err(err): + raise err + case Err(err): + raise err jobs = [ SyncJob( diff --git a/src/watchfs/mappings.py b/src/watchfs/mappings.py index 47e4f38..96e568e 100644 --- a/src/watchfs/mappings.py +++ b/src/watchfs/mappings.py @@ -3,7 +3,6 @@ import re from dataclasses import dataclass from pathlib import Path, PurePosixPath -from typing import cast from urllib.parse import urlparse from watchfs.exceptions import ParseError @@ -78,35 +77,37 @@ def parse_target_spec(spec: str) -> Result[TargetSpec, ParseError]: def parse_sync_mapping(sync_mapping: str) -> Result[tuple[SyncMapping, bool], ParseError]: - split_result = _split_sync_mapping(sync_mapping) - if isinstance(split_result, Err): - return cast("Err[ParseError]", split_result) - - src_dir, dst_dir, bidirectional = cast("Ok[tuple[str, str, bool]]", split_result).ok() - - src_result = parse_target_spec(src_dir) - if isinstance(src_result, Err): - return cast("Err[ParseError]", src_result) - - src_spec = cast("Ok[TargetSpec]", src_result).ok() - if isinstance(src_spec, SshTargetSpec): - return Err(ParseError("Remote source is not supported yet. Source must be a local path.")) - - dst_result = parse_target_spec(dst_dir) - if isinstance(dst_result, Err): - return cast("Err[ParseError]", dst_result) - - dst_spec = cast("Ok[TargetSpec]", dst_result).ok() - if isinstance(dst_spec, SshTargetSpec) and bidirectional: - return Err(ParseError("Bidirectional sync is not supported when the destination is an SSH target.")) - - if isinstance(dst_spec, LocalTargetSpec): - abs_src_dir = src_spec.path.resolve() - abs_dst_dir = dst_spec.path.resolve() - if abs_src_dir in abs_dst_dir.parents: - return Err(ParseError(f"dst_dir({abs_dst_dir}) is a subdirectory of src_dir({abs_src_dir}).")) - - return Ok((SyncMapping(source=src_spec.path, target=dst_spec), bidirectional)) + match _split_sync_mapping(sync_mapping): + case Err(err): + return Err(err) + case Ok((src_dir, dst_dir, bidirectional)): + match parse_target_spec(src_dir): + case Err(err): + return Err(err) + case Ok(src_spec): + if isinstance(src_spec, SshTargetSpec): + return Err(ParseError("Remote source is not supported yet. Source must be a local path.")) + + match parse_target_spec(dst_dir): + case Err(err): + return Err(err) + case Ok(dst_spec): + if isinstance(dst_spec, SshTargetSpec) and bidirectional: + return Err( + ParseError("Bidirectional sync is not supported when the destination is an SSH target.") + ) + + if isinstance(dst_spec, LocalTargetSpec): + abs_src_dir = src_spec.path.resolve() + abs_dst_dir = dst_spec.path.resolve() + if abs_src_dir in abs_dst_dir.parents: + return Err( + ParseError(f"dst_dir({abs_dst_dir}) is a subdirectory of src_dir({abs_src_dir}).") + ) + + return Ok((SyncMapping(source=src_spec.path, target=dst_spec), bidirectional)) + + raise AssertionError("unreachable") def _parse_ssh_url(spec: str) -> Result[SshTargetSpec, ParseError]: diff --git a/tests/test_watchfs.py b/tests/test_watchfs.py index d8bf8e8..81df648 100644 --- a/tests/test_watchfs.py +++ b/tests/test_watchfs.py @@ -2,13 +2,11 @@ import tomllib from pathlib import Path, PurePosixPath -from typing import cast from watchfs import __version__ from watchfs.__main__ import build_queue_key -from watchfs.exceptions import ParseError from watchfs.mappings import LocalTargetSpec, SshTargetSpec, parse_sync_mapping, parse_target_spec -from watchfs.rusty import Err, Ok, Result +from watchfs.rusty import Err, Ok with Path("pyproject.toml").open("rb") as f: project_info = tomllib.load(f) @@ -18,141 +16,155 @@ def test_version(): assert __version__ == project_info["project"]["version"] -def expect_ok[T](result: Result[T, Exception], message: str) -> T: - assert isinstance(result, Ok), message - return cast("Ok[T]", result).ok() - - -def expect_err[E: Exception](result: Result[object, E], message: str) -> E: - assert isinstance(result, Err), message - return cast("Err[E]", result).err() - - def test_parse_local_mapping_with_arrow(): - mapping, bidirectional = expect_ok(parse_sync_mapping("src->dst"), "expected local mapping to parse") - assert mapping.source == Path("src") - assert mapping.target == LocalTargetSpec(Path("dst")) - assert bidirectional is False + match parse_sync_mapping("src->dst"): + case Ok((mapping, bidirectional)): + assert mapping.source == Path("src") + assert mapping.target == LocalTargetSpec(Path("dst")) + assert bidirectional is False + case _: + raise AssertionError("expected local mapping to parse") def test_parse_local_mapping_with_legacy_colon(): - mapping, bidirectional = expect_ok(parse_sync_mapping("src:dst"), "expected local legacy mapping to parse") - assert mapping.source == Path("src") - assert mapping.target == LocalTargetSpec(Path("dst")) - assert bidirectional is False + match parse_sync_mapping("src:dst"): + case Ok((mapping, bidirectional)): + assert mapping.source == Path("src") + assert mapping.target == LocalTargetSpec(Path("dst")) + assert bidirectional is False + case _: + raise AssertionError("expected local legacy mapping to parse") def test_parse_windows_drive_paths_as_local_targets(): - target = expect_ok(parse_target_spec("C:/src"), "expected Windows drive path to parse as local") - assert isinstance(target, LocalTargetSpec) - assert target.path == Path("C:/src") + match parse_target_spec("C:/src"): + case Ok(LocalTargetSpec(path)): + assert path == Path("C:/src") + case _: + raise AssertionError("expected Windows drive path to parse as local") def test_parse_windows_local_mapping_with_arrow(): - mapping, bidirectional = expect_ok(parse_sync_mapping("C:/src->D:/dst"), "expected Windows arrow mapping to parse") - assert mapping.source == Path("C:/src") - assert mapping.target == LocalTargetSpec(Path("D:/dst")) - assert bidirectional is False + match parse_sync_mapping("C:/src->D:/dst"): + case Ok((mapping, bidirectional)): + assert mapping.source == Path("C:/src") + assert mapping.target == LocalTargetSpec(Path("D:/dst")) + assert bidirectional is False + case _: + raise AssertionError("expected Windows arrow mapping to parse") def test_parse_windows_local_mapping_with_legacy_colon(): - mapping, bidirectional = expect_ok( - parse_sync_mapping("C:/src:D:/dst"), "expected Windows legacy mapping to parse" - ) - assert mapping.source == Path("C:/src") - assert mapping.target == LocalTargetSpec(Path("D:/dst")) - assert bidirectional is False + match parse_sync_mapping("C:/src:D:/dst"): + case Ok((mapping, bidirectional)): + assert mapping.source == Path("C:/src") + assert mapping.target == LocalTargetSpec(Path("D:/dst")) + assert bidirectional is False + case _: + raise AssertionError("expected Windows legacy mapping to parse") def test_parse_ssh_target_mapping(): - mapping, bidirectional = expect_ok( - parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs"), "expected ssh mapping to parse" - ) - assert mapping.source == Path("src") - assert mapping.target == SshTargetSpec( - host="192.168.66.1", - path=PurePosixPath("/tmp/watchfs"), - username="meow", - ) - assert bidirectional is False + match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs"): + case Ok((mapping, bidirectional)): + assert mapping.source == Path("src") + assert mapping.target == SshTargetSpec( + host="192.168.66.1", + path=PurePosixPath("/tmp/watchfs"), + username="meow", + ) + assert bidirectional is False + case _: + raise AssertionError("expected ssh mapping to parse") def test_parse_ssh_target_mapping_with_home_path(): - mapping, bidirectional = expect_ok( - parse_sync_mapping("~/Projects/watchfs->meow@192.168.66.1:~/Projects/watchfs"), - "expected ssh home mapping to parse", - ) - assert mapping.source == Path("~/Projects/watchfs").expanduser() - assert mapping.target == SshTargetSpec( - host="192.168.66.1", - path=PurePosixPath("~/Projects/watchfs"), - username="meow", - ) - assert bidirectional is False + match parse_sync_mapping("~/Projects/watchfs->meow@192.168.66.1:~/Projects/watchfs"): + case Ok((mapping, bidirectional)): + assert mapping.source == Path("~/Projects/watchfs").expanduser() + assert mapping.target == SshTargetSpec( + host="192.168.66.1", + path=PurePosixPath("~/Projects/watchfs"), + username="meow", + ) + assert bidirectional is False + case _: + raise AssertionError("expected ssh home mapping to parse") def test_parse_ssh_url_target_mapping(): - mapping, _ = expect_ok(parse_sync_mapping("src->ssh://meow@example.com:2222/tmp/watchfs"), "expected ssh url mapping to parse") - assert mapping.target == SshTargetSpec( - host="example.com", - path=PurePosixPath("/tmp/watchfs"), - username="meow", - port=2222, - ) + match parse_sync_mapping("src->ssh://meow@example.com:2222/tmp/watchfs"): + case Ok((mapping, _)): + assert mapping.target == SshTargetSpec( + host="example.com", + path=PurePosixPath("/tmp/watchfs"), + username="meow", + port=2222, + ) + case _: + raise AssertionError("expected ssh url mapping to parse") def test_reject_remote_source(): - err = expect_err(parse_sync_mapping("meow@192.168.66.1:/tmp/src->dst"), "expected remote source to be rejected") - assert isinstance(err, ParseError) - assert "Remote source is not supported" in err.message + match parse_sync_mapping("meow@192.168.66.1:/tmp/src->dst"): + case Err(err): + assert "Remote source is not supported" in err.message + case _: + raise AssertionError("expected remote source to be rejected") def test_reject_bidirectional_remote_mapping(): - err = expect_err( - parse_sync_mapping("src<->meow@192.168.66.1:/tmp/watchfs"), - "expected bidirectional ssh mapping to be rejected", - ) - assert isinstance(err, ParseError) - assert "Bidirectional sync is not supported" in err.message + match parse_sync_mapping("src<->meow@192.168.66.1:/tmp/watchfs"): + case Err(err): + assert "Bidirectional sync is not supported" in err.message + case _: + raise AssertionError("expected bidirectional ssh mapping to be rejected") def test_reject_local_destination_nested_under_source_message(): - err = expect_err(parse_sync_mapping("src:src/nested"), "expected nested local destination to be rejected") - assert isinstance(err, ParseError) - assert "dst_dir(" in err.message - assert "is a subdirectory of src_dir(" in err.message + match parse_sync_mapping("src:src/nested"): + case Err(err): + assert "dst_dir(" in err.message + assert "is a subdirectory of src_dir(" in err.message + case _: + raise AssertionError("expected nested local destination to be rejected") def test_reject_ambiguous_remote_mapping_without_arrow(): - err = expect_err( - parse_sync_mapping("src:meow@192.168.66.1:/tmp/watchfs"), - "expected ambiguous remote mapping to be rejected", - ) - assert isinstance(err, ParseError) - assert "Use SRC->DST" in err.message + match parse_sync_mapping("src:meow@192.168.66.1:/tmp/watchfs"): + case Err(err): + assert "Use SRC->DST" in err.message + case _: + raise AssertionError("expected ambiguous remote mapping to be rejected") def test_same_ssh_machine_shares_serial_queue_key(): - first_mapping, _ = expect_ok( - parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"), - "expected first ssh mapping to parse", - ) - second_mapping, _ = expect_ok( - parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-b"), - "expected second ssh mapping to parse", - ) + match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"): + case Ok((first_mapping, _)): + pass + case _: + raise AssertionError("expected first ssh mapping to parse") + + match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-b"): + case Ok((second_mapping, _)): + pass + case _: + raise AssertionError("expected second ssh mapping to parse") assert build_queue_key(first_mapping) == build_queue_key(second_mapping) def test_different_ssh_machine_uses_different_queue_key(): - first_mapping, _ = expect_ok( - parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"), - "expected first ssh mapping to parse", - ) - second_mapping, _ = expect_ok( - parse_sync_mapping("src->meow@192.168.88.2:/tmp/watchfs-b"), - "expected second ssh mapping to parse", - ) + match parse_sync_mapping("src->meow@192.168.66.1:/tmp/watchfs-a"): + case Ok((first_mapping, _)): + pass + case _: + raise AssertionError("expected first ssh mapping to parse") + + match parse_sync_mapping("src->meow@192.168.88.2:/tmp/watchfs-b"): + case Ok((second_mapping, _)): + pass + case _: + raise AssertionError("expected second ssh mapping to parse") assert build_queue_key(first_mapping) != build_queue_key(second_mapping) diff --git a/uv.lock b/uv.lock index 251f9e8..72fd775 100644 --- a/uv.lock +++ b/uv.lock @@ -197,27 +197,27 @@ wheels = [ [[package]] name = "ty" -version = "0.0.55" +version = "0.0.54" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/08/48/f687c8d268e3581f2f104d1f2ac5944d5b5e841b3695c613b3f263e5bbf7/ty-0.0.55.tar.gz", hash = "sha256:88ca87073825a79a8327c550efcc86cec94344890244c5946f84c9e44a969f31", size = 6040230, upload-time = "2026-06-27T00:27:29.385Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/c6/2ea90406d82cf82b0a68725130da2cc9de161bfa883c7dee4f0d94dbf3ce/ty-0.0.54.tar.gz", hash = "sha256:b6b3cfe174f27744413c898b2488ca52ea76070637095de131698e506b455055", size = 6009000, upload-time = "2026-06-25T17:53:17.098Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/a3/1a90ba7e5a61c6d09adb92346ddba97668095fc257b577af433e5ac4f404/ty-0.0.55-py3-none-linux_armv6l.whl", hash = "sha256:31e83eef512d066542fe990fe1a3b814423abd1616376c54e48af7045b3e1749", size = 11677249, upload-time = "2026-06-27T00:26:52.18Z" }, - { url = "https://files.pythonhosted.org/packages/82/3a/669f9aa478c38243e213a2684db1502086026cfadc15bb1b29b7cbde030d/ty-0.0.55-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab4bca857950608fea73e269e2da369d43e6467131de85160d68e2fa466fa248", size = 11444180, upload-time = "2026-06-27T00:26:54.576Z" }, - { url = "https://files.pythonhosted.org/packages/15/a4/6a4b2507a53ce6530c66c5b4fe0d58551eb1748ffa9e0696c32fdd55bbd4/ty-0.0.55-py3-none-macosx_11_0_arm64.whl", hash = "sha256:55032bfd31bf2c5355ee81bdc6407b144a1cc7ee41e5681dd1368e4cef2ba327", size = 10963134, upload-time = "2026-06-27T00:26:57.348Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ae/a3b1a0f1cc83b7d258662cb98aa80a720c2e671d0e8fa0d17a4d5d057a7a/ty-0.0.55-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef1e049f69ce65b3c269af67624607f435e1c32319786c1e453ef9611502f295", size = 11493517, upload-time = "2026-06-27T00:26:59.26Z" }, - { url = "https://files.pythonhosted.org/packages/0d/9f/311ce39065a979ef40a9b847f685c8e02464e53adf1671e081eea90640ca/ty-0.0.55-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:631409975c681d5a280fc5a99b7b32e9e801f33be7567c6b42ec331362f59d7d", size = 11460590, upload-time = "2026-06-27T00:27:01.425Z" }, - { url = "https://files.pythonhosted.org/packages/cd/8f/3bf29aa77bd78aae48275153135a2052fa7d3ccdf1ecabeb99c8773abd66/ty-0.0.55-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e08cb0436e68b9351555ae8f2697138c9009b4d5b4ae4272232988b2a431a98f", size = 12098430, upload-time = "2026-06-27T00:27:03.596Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6e/e88411a88240b94640bba06fb6d0d92b247fbeef47ee2bc71f39e58c2558/ty-0.0.55-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16c215ad9f823829409b94ee188cfaa4563f6e1384f6ce3fecb1db75f6c7cf7c", size = 12673086, upload-time = "2026-06-27T00:27:05.589Z" }, - { url = "https://files.pythonhosted.org/packages/6c/7e/8f1762fb7f9245a68ba5ae338d73c59403ce57554e5d311b8bb55027b0ec/ty-0.0.55-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b510eb8f4032baf11b7aee2f1d53babc3b4ca03939b9cdcf6a9d15761d575188", size = 12242559, upload-time = "2026-06-27T00:27:07.714Z" }, - { url = "https://files.pythonhosted.org/packages/72/1f/143657daf2670d977dac83435f1fe03d4843efb798d8e1e75950e541aadd/ty-0.0.55-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ddc05e7959709c3b9b83aa627128a80446865e3c1a4882638dcff6d776dc34a", size = 12021409, upload-time = "2026-06-27T00:27:09.881Z" }, - { url = "https://files.pythonhosted.org/packages/6d/30/69487c439dd1fad3a4a3d96f0a472193de297eaba6fc4b8ea687ce434ac2/ty-0.0.55-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:636e8e5078787b8c6916c94e1406719f10189a4ca6b37b813a5922ce5857a8c7", size = 12303807, upload-time = "2026-06-27T00:27:11.986Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ca/cd88b6493dafc7db077f5e17c0438eb3af6e2d6d08f616dbb52a8ddfd567/ty-0.0.55-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ef7d6deaacb73fec603666b5471f1dc5a5699aa84e11a6d4d644dd07ca72121e", size = 11441263, upload-time = "2026-06-27T00:27:14.087Z" }, - { url = "https://files.pythonhosted.org/packages/aa/fe/66b6915671653ab739f71e4f1b0528e69da64429b7ebf3840c625b6e43f2/ty-0.0.55-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9aeea0fe5875d3cf37faf0e44d0fdf9669335467749741b8fc0103916fb5cd32", size = 11484584, upload-time = "2026-06-27T00:27:16.311Z" }, - { url = "https://files.pythonhosted.org/packages/4a/4f/7a9c0bbac8b899e9f6c0ec110c6612f52e4db35f6bb17ddc0ef60384fa3e/ty-0.0.55-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0b699c01310dbd2705a07c97c5f4aaeedef61bd9adeea2e7c46aed32401d3576", size = 11759309, upload-time = "2026-06-27T00:27:18.471Z" }, - { url = "https://files.pythonhosted.org/packages/ca/de/b6f8b1b69aa631b5716ef3f985c3b56de0e46c2499cc00d30c402b41f714/ty-0.0.55-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:32cbeba543e46de2a983ec6d525d8b56514f7422bd1e1b57c44ccf7bfa72c38a", size = 12128755, upload-time = "2026-06-27T00:27:20.55Z" }, - { url = "https://files.pythonhosted.org/packages/7d/90/a912531e51ee7e076b42972479290fa687c0f5e747b7e773f3033164acaa/ty-0.0.55-py3-none-win32.whl", hash = "sha256:52b968e24eb4f7a5c3bd251db1f99f60dd385890356d38fc619d84f1b423446a", size = 11117501, upload-time = "2026-06-27T00:27:22.714Z" }, - { url = "https://files.pythonhosted.org/packages/4c/7a/99d59843bf8908a7f9f4d13fda107dbad07b7faa28ecd7860eacf363fb1c/ty-0.0.55-py3-none-win_amd64.whl", hash = "sha256:bf39cbfdc0add44d94bd3fff1f53c351418d134b6a66b87efdb7876d7b7a2224", size = 12150106, upload-time = "2026-06-27T00:27:24.881Z" }, - { url = "https://files.pythonhosted.org/packages/b3/44/20987505cedf2a865b08482f0eabc181fd9599b062964057ec8a128a4296/ty-0.0.55-py3-none-win_arm64.whl", hash = "sha256:f7f3700a9a060e8f1af11e4fb63fafcaf272b041781f4ccdfda2b3b5c6c1e439", size = 11560157, upload-time = "2026-06-27T00:27:27.332Z" }, + { url = "https://files.pythonhosted.org/packages/b8/26/a83e688e108a29a8630d7075bae47b72614cfa275c88b3166575ca0a8af0/ty-0.0.54-py3-none-linux_armv6l.whl", hash = "sha256:0365ea133d6b028952c22e6412a00da9739bc3b538df3c0a61972bf64d8558f1", size = 11616164, upload-time = "2026-06-25T17:52:29.174Z" }, + { url = "https://files.pythonhosted.org/packages/85/89/9f3374f9eef0267aed5efbd5544e47cfa6affc94236d929e878a780cf7d7/ty-0.0.54-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0de0cf48918609a3996cc2a4e18e8028fc4d2446bb82df822e9737f53bb9afee", size = 11351250, upload-time = "2026-06-25T17:52:32.181Z" }, + { url = "https://files.pythonhosted.org/packages/28/11/e0e3f542a6de0e0dd5f503215527f8d9fc141426bd52dbe98fce927ff831/ty-0.0.54-py3-none-macosx_11_0_arm64.whl", hash = "sha256:57c7c6c1fcd2aa29cd40117142c0d45a2b0e6c42817ef58ea8dcb5f59d6ea802", size = 10872162, upload-time = "2026-06-25T17:52:35.206Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b0/fa369840f1ccd391971f693a8f86c445eb1a0fad61a6e0e773f0871a7a6f/ty-0.0.54-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc179be5a070c5dc7785a5e108eece2ab216978a91f91e11661308749a6c28ee", size = 11419826, upload-time = "2026-06-25T17:52:37.942Z" }, + { url = "https://files.pythonhosted.org/packages/62/5f/8fbf9b7147cf08cc96cc9f84b9699ae7c7a0a1eb0a4c3d912261351b1cbb/ty-0.0.54-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a0a764e2261f9292adf14bbc91b9d7ef7ee7c00b8f3d9f2563f19ae3605109b", size = 11411732, upload-time = "2026-06-25T17:52:41.124Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ce/53aa78828f98ce396d5cc0f0878d990c0d70f6bf7704105232399315952f/ty-0.0.54-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2259e1a1f744a5f20f079dcc4061c1464001c75f255aaca7316e422f8f5e5e09", size = 12039318, upload-time = "2026-06-25T17:52:43.981Z" }, + { url = "https://files.pythonhosted.org/packages/9e/05/5654d4d20376a73cd2e9df8178515c466ff9b2bda15748ee5810c955a265/ty-0.0.54-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8674617617399d4fdd568b3e3a8f87a913df525c80691d732b0744b571b341c8", size = 12625562, upload-time = "2026-06-25T17:52:46.578Z" }, + { url = "https://files.pythonhosted.org/packages/37/f7/982be4abde816c821c6aeaba133dc34b5346eebbb29dadbf77b8ee46dad9/ty-0.0.54-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e949f7bbfa80a9fa00968924028aa673a505faa234b0b9d1241b7d34373eae14", size = 12175175, upload-time = "2026-06-25T17:52:49.176Z" }, + { url = "https://files.pythonhosted.org/packages/6a/8b/371fa3d121a1d9c8806a997ec5aa7b6a91912044d936594e6cf04d197471/ty-0.0.54-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a0ce5af9eefe636888377d8ab8ea817239ed96de64fede62c4e5331ae16db5c", size = 11945921, upload-time = "2026-06-25T17:52:51.983Z" }, + { url = "https://files.pythonhosted.org/packages/dd/76/cab1ff8f6029b657b3fed59add1a2f188df6af26b6d649a6c789139dd88d/ty-0.0.54-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:ad329d1942e23ee428948e673b2a50249f27e164220075b0a2ef8169029c8423", size = 12269965, upload-time = "2026-06-25T17:52:54.697Z" }, + { url = "https://files.pythonhosted.org/packages/31/2f/c14b36cacacf7cc5ae40c862c34c07fadeba85cb93fd8f328cdac2029270/ty-0.0.54-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6e43124e6ac4cb9702d99facb28c6b2f2574c8a4b8f59eae2632eef4962e3439", size = 11370742, upload-time = "2026-06-25T17:52:57.233Z" }, + { url = "https://files.pythonhosted.org/packages/db/1b/9e55bb273d3ea8efe165a73e34ae92220593e4dbfe665b8283be9d3eadea/ty-0.0.54-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:994ede70fc1b6f0efc29d0f1fc0d819630bed1d2610eac2e9dabb2840f3f3bf9", size = 11432346, upload-time = "2026-06-25T17:52:59.898Z" }, + { url = "https://files.pythonhosted.org/packages/db/16/402e8d2b1ab1020a25774f22ec0ba4378617758197278c1ddbc093b64854/ty-0.0.54-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b1d048df26abb433acc5b3bcef214167c7dc9e3341f8f200a3c59702516a0ed0", size = 11707341, upload-time = "2026-06-25T17:53:02.678Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ca/220599403e1dc864109402c88e22e8793108ec3be41576cd044772023d94/ty-0.0.54-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:651e90094d41c4add3d616e0f2c1c881c6700a2ae3ac191c023c665050ff2cdc", size = 12053427, upload-time = "2026-06-25T17:53:05.983Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a9/f08df843e3d4422184a847829eb103c49a6118eed7024969a1a706de1c5e/ty-0.0.54-py3-none-win32.whl", hash = "sha256:7e876c9b5130afc6b6e46035a2eecca9b563b78249030296e1089922428d5415", size = 11044018, upload-time = "2026-06-25T17:53:09.582Z" }, + { url = "https://files.pythonhosted.org/packages/4c/26/230719333d79fae599e3c2da5ac35e36786cdd6c4b4f2a5d5450ce171dc7/ty-0.0.54-py3-none-win_amd64.whl", hash = "sha256:f478476f3222807b4d92f15c5298a8c242f2ed17c724da75f4a8c6b522b4f29a", size = 12107765, upload-time = "2026-06-25T17:53:12.2Z" }, + { url = "https://files.pythonhosted.org/packages/28/68/b5fcb35ceebffab3e8898bd25e51d0bb77a0c43c50b7a8e3fae56125e4f5/ty-0.0.54-py3-none-win_arm64.whl", hash = "sha256:01ab9eb8c0802d35ae73fa08e4e037963250ee5ee6aa7ed8c8b994e5495db5ef", size = 11498510, upload-time = "2026-06-25T17:53:14.693Z" }, ] [[package]] @@ -330,5 +330,5 @@ dev = [ { name = "pytest-rerunfailures", specifier = ">=16.3" }, { name = "ruff", specifier = ">=0.15.20" }, { name = "tomli", specifier = ">=2.4.1" }, - { name = "ty", specifier = ">=0.0.55" }, + { name = "ty", specifier = ">=0.0.54,<0.0.55" }, ] From e32bdf85fb411c8d3b3cd5370788c5517c59fe9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 17:21:52 +0000 Subject: [PATCH 4/4] fix: exclude only ty 0.0.55 --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 755f4eb..22887f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ watchfs = "watchfs.__main__:main" [dependency-groups] dev = [ - "ty>=0.0.54,<0.0.55", + "ty>=0.0.54,!=0.0.55", "ruff>=0.15.20", "pytest>=9.1.1", "pytest-rerunfailures>=16.3", diff --git a/uv.lock b/uv.lock index 72fd775..9589137 100644 --- a/uv.lock +++ b/uv.lock @@ -330,5 +330,5 @@ dev = [ { name = "pytest-rerunfailures", specifier = ">=16.3" }, { name = "ruff", specifier = ">=0.15.20" }, { name = "tomli", specifier = ">=2.4.1" }, - { name = "ty", specifier = ">=0.0.54,<0.0.55" }, + { name = "ty", specifier = ">=0.0.54,!=0.0.55" }, ]