From eb22f8049f87f41f5928fd2b0572bd020fb13405 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:37:46 +0100 Subject: [PATCH 01/59] feat(client-py): Add a (empty) package for the Python client --- .gitignore | 2 ++ python-objectstore-client/.gitignore | 10 ++++++++++ python-objectstore-client/README.md | 1 + python-objectstore-client/pyproject.toml | 11 +++++++++++ .../src/objectstore-client/__init__.py | 0 .../src/objectstore-client/py.typed | 0 6 files changed, 24 insertions(+) create mode 100644 python-objectstore-client/.gitignore create mode 100644 python-objectstore-client/README.md create mode 100644 python-objectstore-client/pyproject.toml create mode 100644 python-objectstore-client/src/objectstore-client/__init__.py create mode 100644 python-objectstore-client/src/objectstore-client/py.typed diff --git a/.gitignore b/.gitignore index fa356c22..7fb7b91a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ profile.json.gz # vim swap files .*.sw* + +**/__pycache__ diff --git a/python-objectstore-client/.gitignore b/python-objectstore-client/.gitignore new file mode 100644 index 00000000..505a3b1c --- /dev/null +++ b/python-objectstore-client/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/python-objectstore-client/README.md b/python-objectstore-client/README.md new file mode 100644 index 00000000..878bb4e1 --- /dev/null +++ b/python-objectstore-client/README.md @@ -0,0 +1 @@ +# objectstore-client diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml new file mode 100644 index 00000000..469f71dd --- /dev/null +++ b/python-objectstore-client/pyproject.toml @@ -0,0 +1,11 @@ +[project] +name = "python-objectstore-client" +version = "0.1.0" +description = "Python client for the Sentry Objectstore service" +readme = "README.md" +requires-python = ">=3.11.11" +dependencies = [] + +[[tool.uv.index]] +url = "https://pypi.devinfra.sentry.io/simple" +default = true diff --git a/python-objectstore-client/src/objectstore-client/__init__.py b/python-objectstore-client/src/objectstore-client/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python-objectstore-client/src/objectstore-client/py.typed b/python-objectstore-client/src/objectstore-client/py.typed new file mode 100644 index 00000000..e69de29b From d37032c94036d91b70a8b2338cddae8d7986516e Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 21:58:58 +0100 Subject: [PATCH 02/59] use workspace, use internal PyPI for whole workspace, uv sync --- pyproject.toml | 9 ++ python-objectstore-client/pyproject.toml | 6 +- .../__init__.py | 0 .../py.typed | 0 uv.lock | 101 ++++++++---------- 5 files changed, 55 insertions(+), 61 deletions(-) rename python-objectstore-client/src/{objectstore-client => objectstore_client}/__init__.py (100%) rename python-objectstore-client/src/{objectstore-client => objectstore_client}/py.typed (100%) diff --git a/pyproject.toml b/pyproject.toml index 4338c66e..19bab596 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,5 +3,14 @@ name = "objectstore" version = "0.1.0" requires-python = ">=3.13" +[[tool.uv.index]] +url = "https://pypi.devinfra.sentry.io/simple" +default = true + +[tool.uv.workspace] +members = [ + "python-objectstore-client", +] + [dependency-groups] dev = ["devservices>=1.2.2"] diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 469f71dd..93fbefe9 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -1,11 +1,7 @@ [project] -name = "python-objectstore-client" +name = "objectstore-client" version = "0.1.0" description = "Python client for the Sentry Objectstore service" readme = "README.md" requires-python = ">=3.11.11" dependencies = [] - -[[tool.uv.index]] -url = "https://pypi.devinfra.sentry.io/simple" -default = true diff --git a/python-objectstore-client/src/objectstore-client/__init__.py b/python-objectstore-client/src/objectstore_client/__init__.py similarity index 100% rename from python-objectstore-client/src/objectstore-client/__init__.py rename to python-objectstore-client/src/objectstore_client/__init__.py diff --git a/python-objectstore-client/src/objectstore-client/py.typed b/python-objectstore-client/src/objectstore_client/py.typed similarity index 100% rename from python-objectstore-client/src/objectstore-client/py.typed rename to python-objectstore-client/src/objectstore_client/py.typed diff --git a/uv.lock b/uv.lock index 041cad95..f84e6bbc 100644 --- a/uv.lock +++ b/uv.lock @@ -2,19 +2,24 @@ version = 1 revision = 3 requires-python = ">=3.13" +[manifest] +members = [ + "objectstore", + "objectstore-client", +] + [[package]] name = "certifi" -version = "2025.10.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } +version = "2025.8.3" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" }, ] [[package]] name = "devservices" version = "1.2.2" -source = { registry = "https://pypi.org/simple" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "packaging" }, { name = "pyyaml" }, @@ -22,9 +27,8 @@ dependencies = [ { name = "sentry-sdk" }, { name = "supervisor" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/70/f72c146a562161def21f56701b690176a1cfb1c24f1e5f3e062fe1479770/devservices-1.2.2.tar.gz", hash = "sha256:9e6dc105ec6be210ab5d23f0abbd270ae1d98af73e84e4c62185f18ea40f9361", size = 89717, upload-time = "2025-09-26T20:38:46.4Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/98/769e6a3507f5d480e533aeb1f2ece970f54c6082723d0fa8403d307c4028/devservices-1.2.2-py3-none-any.whl", hash = "sha256:5d102b3fe91050dd7dea21c9677b09778a0ea120bbcddeb3800a8cbe11141bae", size = 116952, upload-time = "2025-09-26T20:38:45.333Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/devservices-1.2.2-py3-none-any.whl", hash = "sha256:5d102b3fe91050dd7dea21c9677b09778a0ea120bbcddeb3800a8cbe11141bae" }, ] [[package]] @@ -42,100 +46,85 @@ dev = [ [package.metadata.requires-dev] dev = [{ name = "devservices", specifier = ">=1.2.2" }] +[[package]] +name = "objectstore-client" +version = "0.1.0" +source = { virtual = "python-objectstore-client" } + [[package]] name = "packaging" version = "25.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484" }, ] [[package]] name = "pyyaml" version = "6.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6" }, ] [[package]] name = "sentry-devenv" version = "1.23.0" -source = { registry = "https://pypi.org/simple" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "sentry-sdk" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/fc/3235c22f5ccf6b5d82612d2db0f61b70a939e88d7582fe34b8e2f0654fd9/sentry_devenv-1.23.0.tar.gz", hash = "sha256:6bd3d0d2b918b19f012e3f51ec03c337245e40ce0386711b64ef5566482495e8", size = 49808, upload-time = "2025-09-30T22:18:18.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/3b/8bf6c9f5fc354e3e00fa44d4bfc54f7e14b7545158a668a057f97b703202/sentry_devenv-1.23.0-py3-none-any.whl", hash = "sha256:bf1d930b8672bdafd8deebdca998e3777acab8060fea1dd3fb92208631321565", size = 68471, upload-time = "2025-09-30T22:18:17.303Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/sentry_devenv-1.23.0-py3-none-any.whl", hash = "sha256:bf1d930b8672bdafd8deebdca998e3777acab8060fea1dd3fb92208631321565" }, ] [[package]] name = "sentry-sdk" version = "2.42.0" -source = { registry = "https://pypi.org/simple" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/b2/7481156cf42b7f66cffb371e504b7ace12b4f016b8872ffcf0873ae9534b/sentry_sdk-2.42.0.tar.gz", hash = "sha256:91c69c9372fb5fb4df0ac39456ccf7286f0428b3ee1cdd389f9dd36c04e0f5c9", size = 351242, upload-time = "2025-10-15T07:41:15.577Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/4a/9810a246ec5d1df2ae066efefeecfa91d3c548fa2bd5390184e016112887/sentry_sdk-2.42.0-py2.py3-none-any.whl", hash = "sha256:1a7986e638306ff158f52dd47d9480a4055e6c289388caa90628acb2563fe7bd", size = 379496, upload-time = "2025-10-15T07:41:13.802Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/sentry_sdk-2.42.0-py2.py3-none-any.whl", hash = "sha256:1a7986e638306ff158f52dd47d9480a4055e6c289388caa90628acb2563fe7bd" }, +] + +[[package]] +name = "setuptools" +version = "78.1.1" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/setuptools-78.1.1-py3-none-any.whl", hash = "sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561" }, ] [[package]] name = "supervisor" -version = "4.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/b5/37e7a3706de436a8a2d75334711dad1afb4ddffab09f25e31d89e467542f/supervisor-4.3.0.tar.gz", hash = "sha256:4a2bf149adf42997e1bb44b70c43b613275ec9852c3edacca86a9166b27e945e", size = 468912, upload-time = "2025-08-23T18:25:02.418Z" } +version = "4.2.5" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "setuptools" }, +] wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/65/5e726c372da8a5e35022a94388b12252710aad0c2351699c3d76ae8dba78/supervisor-4.3.0-py2.py3-none-any.whl", hash = "sha256:0bcb763fddafba410f35cbde226aa7f8514b9fb82eb05a0c85f6588d1c13f8db", size = 320736, upload-time = "2025-08-23T18:25:00.767Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/supervisor-4.2.5-py2.py3-none-any.whl", hash = "sha256:2ecaede32fc25af814696374b79e42644ecaba5c09494c51016ffda9602d0f08" }, ] [[package]] name = "typing-extensions" version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" }, ] [[package]] name = "urllib3" version = "2.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://pypi.devinfra.sentry.io/wheels/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" }, ] From 86c75cb993987670aa1fc7d2bd293dd358ebb0ca Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:06:51 +0100 Subject: [PATCH 03/59] specify build system, install client as editable --- python-objectstore-client/pyproject.toml | 4 ++++ uv.lock | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 93fbefe9..f384e9af 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -5,3 +5,7 @@ description = "Python client for the Sentry Objectstore service" readme = "README.md" requires-python = ">=3.11.11" dependencies = [] + +[build-system] +requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini +build-backend = "uv_build" diff --git a/uv.lock b/uv.lock index f84e6bbc..467eb60c 100644 --- a/uv.lock +++ b/uv.lock @@ -49,7 +49,7 @@ dev = [{ name = "devservices", specifier = ">=1.2.2" }] [[package]] name = "objectstore-client" version = "0.1.0" -source = { virtual = "python-objectstore-client" } +source = { editable = "python-objectstore-client" } [[package]] name = "packaging" From 8f932f28e417b6da621a89aa66265c74839bfcbf Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:30:51 +0100 Subject: [PATCH 04/59] uv sync --all-packages in envrc for unified venv --- .envrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.envrc b/.envrc index 3297e254..c3d3ea58 100644 --- a/.envrc +++ b/.envrc @@ -17,7 +17,7 @@ if ! command -v uv >/dev/null 2>&1; then return 1 fi -uv sync --all-groups +uv sync --all-packages --all-groups source .venv/bin/activate source_env_if_exists .envrc.private From 987c9c68cc2d67e4604957be11f71d4af192fce1 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:33:11 +0100 Subject: [PATCH 05/59] rebased --- .github/workflows/ci-python.yml | 65 +++++++++ python-objectstore-client/pyproject.toml | 31 +++- python-objectstore-client/setup.cfg | 2 + uv.lock | 172 +++++++++++++++++++++++ 4 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-python.yml create mode 100644 python-objectstore-client/setup.cfg diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml new file mode 100644 index 00000000..121f1aec --- /dev/null +++ b/.github/workflows/ci-python.yml @@ -0,0 +1,65 @@ +name: CI / Python + +on: + push: + branches: + - main + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +defaults: + run: + shell: bash --noprofile --norc -eo pipefail -ux {0} + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + with: + version: '0.9.3' + enable-cache: false # we just cache the venv-dir directly in action-setup-venv + + - uses: getsentry/action-setup-venv@0958463ee0e02b9e8aa8f8e031afae1f84b80881 # v3.0.0 + with: + cache-dependency-path: uv.lock + install-cmd: uv sync --frozen --active + + - name: Run black + run: uv run black --check --diff python-objectstore-client + + - name: Run isort + run: uv run isort --check-only --diff python-objectstore-client + + - name: Run flake8 + run: uv run flake8 python-objectstore-client + + - name: Run mypy + run: uv run mypy python-objectstore-client + + test: + name: Test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + with: + version: '0.9.3' + enable-cache: false # we just cache the venv-dir directly in action-setup-venv + + - uses: getsentry/action-setup-venv@0958463ee0e02b9e8aa8f8e031afae1f84b80881 # v3.0.0 + with: + cache-dependency-path: uv.lock + install-cmd: uv sync --frozen --active + + - name: Run tests + run: pytest diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index f384e9af..f277ef48 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -6,6 +6,35 @@ readme = "README.md" requires-python = ">=3.11.11" dependencies = [] -[build-system] requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini build-backend = "uv_build" + +[dependency-groups] +dev = [ + "pytest>=8.3.3", + "black>=25.1.0", + "isort>=5.13.2", + "flake8>=7.3.0", + "mypy>=1.17.1", +] + +[tool.mypy] +check_untyped_defs = true +no_implicit_reexport = true +warn_unreachable = true +warn_unused_configs = true +warn_unused_ignores = true +warn_redundant_casts = true +enable_error_code = ["ignore-without-code", "redundant-self"] +local_partial_types = true +disallow_any_generics = true +disallow_untyped_defs = true + +[tool.black] +line-length = 200 +target-version = ['py311'] + +[tool.isort] +profile = "black" +line_length = 200 +lines_between_sections = 1 diff --git a/python-objectstore-client/setup.cfg b/python-objectstore-client/setup.cfg new file mode 100644 index 00000000..a6578a30 --- /dev/null +++ b/python-objectstore-client/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +extend-ignore = E501 diff --git a/uv.lock b/uv.lock index 467eb60c..a8d2338f 100644 --- a/uv.lock +++ b/uv.lock @@ -8,6 +8,24 @@ members = [ "objectstore-client", ] +[[package]] +name = "black" +version = "25.1.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717" }, +] + [[package]] name = "certifi" version = "2025.8.3" @@ -16,6 +34,25 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" }, ] +[[package]] +name = "click" +version = "8.3.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" }, +] + [[package]] name = "devservices" version = "1.2.2" @@ -31,6 +68,67 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/devservices-1.2.2-py3-none-any.whl", hash = "sha256:5d102b3fe91050dd7dea21c9677b09778a0ea120bbcddeb3800a8cbe11141bae" }, ] +[[package]] +name = "flake8" +version = "7.3.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "mccabe" }, + { name = "pycodestyle" }, + { name = "pyflakes" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e" }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" }, +] + +[[package]] +name = "isort" +version = "6.0.1" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" }, +] + +[[package]] +name = "mypy" +version = "1.18.2" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505" }, +] + [[package]] name = "objectstore" version = "0.1.0" @@ -51,6 +149,26 @@ name = "objectstore-client" version = "0.1.0" source = { editable = "python-objectstore-client" } +[package.dev-dependencies] +dev = [ + { name = "black" }, + { name = "flake8" }, + { name = "isort" }, + { name = "mypy" }, + { name = "pytest" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [ + { name = "black", specifier = ">=25.1.0" }, + { name = "flake8", specifier = ">=7.3.0" }, + { name = "isort", specifier = ">=5.13.2" }, + { name = "mypy", specifier = ">=1.17.1" }, + { name = "pytest", specifier = ">=8.3.3" }, +] + [[package]] name = "packaging" version = "25.0" @@ -59,6 +177,60 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08" }, +] + +[[package]] +name = "platformdirs" +version = "4.3.8" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4" }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" }, +] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" }, +] + +[[package]] +name = "pyflakes" +version = "3.4.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f" }, +] + +[[package]] +name = "pytest" +version = "8.3.3" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2" }, +] + [[package]] name = "pyyaml" version = "6.0.3" From 1e9388c7e95f85a5a2e2f8f63c3e9b9ed2242e75 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:33:41 +0100 Subject: [PATCH 06/59] lockfile --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index a8d2338f..ecd1eb2c 100644 --- a/uv.lock +++ b/uv.lock @@ -147,7 +147,7 @@ dev = [{ name = "devservices", specifier = ">=1.2.2" }] [[package]] name = "objectstore-client" version = "0.1.0" -source = { editable = "python-objectstore-client" } +source = { virtual = "python-objectstore-client" } [package.dev-dependencies] dev = [ From ac5bc037622c4abf4816910ce60a7f2a0ff7d069 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:36:14 +0100 Subject: [PATCH 07/59] adjst commands --- .github/workflows/ci-python.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 121f1aec..5ad38958 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -33,16 +33,16 @@ jobs: install-cmd: uv sync --frozen --active - name: Run black - run: uv run black --check --diff python-objectstore-client + run: black --check --diff python-objectstore-client - name: Run isort - run: uv run isort --check-only --diff python-objectstore-client + run: isort --check-only --diff python-objectstore-client - name: Run flake8 - run: uv run flake8 python-objectstore-client + run: flake8 python-objectstore-client - name: Run mypy - run: uv run mypy python-objectstore-client + run: mypy python-objectstore-client test: name: Test @@ -62,4 +62,4 @@ jobs: install-cmd: uv sync --frozen --active - name: Run tests - run: pytest + run: pytest python-objectstore-client From a29e932898837099552d922de85846ca1320d033 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:48:09 +0100 Subject: [PATCH 08/59] add pre-commit --- .pre-commit-config.yaml | 41 +++++++++++++++++++++++ pyproject.toml | 5 ++- uv.lock | 74 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..56f50e23 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,41 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-merge-conflict + - id: check-symlinks + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-added-large-files + args: ["--maxkb=1024"] + - id: check-yaml + args: ["--allow-multiple-documents"] + - id: check-toml + - id: detect-private-key + - repo: local + hooks: + - id: black + name: black + entry: .venv/bin/black + language: system + types_or: [python, pyi] + require_serial: true + - id: isort + name: isort + entry: .venv/bin/isort + language: system + types: [python] + - id: flake8 + name: flake8 + entry: .venv/bin/flake8 + language: system + types: [python] + require_serial: true + - id: mypy + name: mypy + entry: .venv/bin/mypy + language: system + types: [python] + require_serial: true diff --git a/pyproject.toml b/pyproject.toml index 19bab596..0ccd9358 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,4 +13,7 @@ members = [ ] [dependency-groups] -dev = ["devservices>=1.2.2"] +dev = [ + "devservices>=1.2.2", + "pre-commit>=4.2.0", +] diff --git a/uv.lock b/uv.lock index ecd1eb2c..00562a88 100644 --- a/uv.lock +++ b/uv.lock @@ -34,6 +34,14 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" }, ] +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9" }, +] + [[package]] name = "click" version = "8.3.0" @@ -68,6 +76,22 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/devservices-1.2.2-py3-none-any.whl", hash = "sha256:5d102b3fe91050dd7dea21c9677b09778a0ea120bbcddeb3800a8cbe11141bae" }, ] +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87" }, +] + +[[package]] +name = "filelock" +version = "3.19.1" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d" }, +] + [[package]] name = "flake8" version = "7.3.0" @@ -81,6 +105,14 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e" }, ] +[[package]] +name = "identify" +version = "2.6.9" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/identify-2.6.9-py2.py3-none-any.whl", hash = "sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150" }, +] + [[package]] name = "iniconfig" version = "2.0.0" @@ -129,6 +161,14 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505" }, ] +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9" }, +] + [[package]] name = "objectstore" version = "0.1.0" @@ -137,12 +177,16 @@ source = { virtual = "." } [package.dev-dependencies] dev = [ { name = "devservices" }, + { name = "pre-commit" }, ] [package.metadata] [package.metadata.requires-dev] -dev = [{ name = "devservices", specifier = ">=1.2.2" }] +dev = [ + { name = "devservices", specifier = ">=1.2.2" }, + { name = "pre-commit", specifier = ">=4.2.0" }, +] [[package]] name = "objectstore-client" @@ -201,6 +245,21 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" }, ] +[[package]] +name = "pre-commit" +version = "4.2.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd" }, +] + [[package]] name = "pycodestyle" version = "2.14.0" @@ -300,3 +359,16 @@ source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" }, ] + +[[package]] +name = "virtualenv" +version = "20.29.3" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/virtualenv-20.29.3-py3-none-any.whl", hash = "sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170" }, +] From 58d530912718a68f2d66f260e1a2b3ea271bcc3b Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:52:45 +0100 Subject: [PATCH 09/59] disclaimer on pre-commit --- .pre-commit-config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 56f50e23..80a5f8da 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,6 @@ +# This pre-commit config is mainly aimed at formatting and linting the Python files in python-objectstore-client. +# However, pre-commit requires this file to be placed at the root of the repository. + repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 @@ -14,6 +17,7 @@ repos: args: ["--allow-multiple-documents"] - id: check-toml - id: detect-private-key + - repo: local hooks: - id: black From daca1354cf3459ff226c4aec074c3ad3344dc47d Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 23:02:37 +0100 Subject: [PATCH 10/59] readme --- python-objectstore-client/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/python-objectstore-client/README.md b/python-objectstore-client/README.md index 878bb4e1..da2ffd21 100644 --- a/python-objectstore-client/README.md +++ b/python-objectstore-client/README.md @@ -1 +1,22 @@ # objectstore-client + +## Usage + +TODO + +## Development + +### Environment Setup + +The considerations for setting up the development environment that can be found in the main [README](../README.md) apply for this package as well. + +### Pre-commit hook + +A configuration to set up a git pre-commit hook using [pre-commit](https://github.com/pre-commit/pre-commit) is available at the root of the repository. + +To install it, run +```sh +pre-commit install +``` + +The hook will automatically run some checks before every commit, including the linters and formatters we run in CI. From ca248cb29c55dc00311822c3bc666457a8e0b17b Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:42:06 +0100 Subject: [PATCH 11/59] build_system --- python-objectstore-client/pyproject.toml | 1 + uv.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index f277ef48..041f399c 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -6,6 +6,7 @@ readme = "README.md" requires-python = ">=3.11.11" dependencies = [] +[build-system] requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini build-backend = "uv_build" diff --git a/uv.lock b/uv.lock index 00562a88..75e4f884 100644 --- a/uv.lock +++ b/uv.lock @@ -191,7 +191,7 @@ dev = [ [[package]] name = "objectstore-client" version = "0.1.0" -source = { virtual = "python-objectstore-client" } +source = { editable = "python-objectstore-client" } [package.dev-dependencies] dev = [ From 1c93543a27d81c8d3f0e43e4f35f19d054e78d87 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:46:34 +0100 Subject: [PATCH 12/59] os matrix --- .github/workflows/ci-python.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 5ad38958..a15da427 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -10,14 +10,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true -defaults: - run: - shell: bash --noprofile --norc -eo pipefail -ux {0} +strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] jobs: lint: - name: Lint - runs-on: ubuntu-latest + name: Lint (${{ matrix.os }}) + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -45,8 +46,8 @@ jobs: run: mypy python-objectstore-client test: - name: Test - runs-on: ubuntu-latest + name: Test (${{ matrix.os }}) + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 From 33ff8b4aebbf759f6008fbc292a7b10d3d1c263a Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:48:40 +0100 Subject: [PATCH 13/59] os matrix --- .github/workflows/ci-python.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index a15da427..2fd0b085 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -10,13 +10,13 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true -strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - jobs: lint: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + name: Lint (${{ matrix.os }}) runs-on: ${{ matrix.os }} @@ -46,6 +46,11 @@ jobs: run: mypy python-objectstore-client test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + name: Test (${{ matrix.os }}) runs-on: ${{ matrix.os }} From 1f5d760d1be6d45c4a964d1086bb52a6e0d32cdc Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:50:34 +0100 Subject: [PATCH 14/59] improve --- .github/workflows/ci-python.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 2fd0b085..d1bc3e89 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -31,7 +31,7 @@ jobs: - uses: getsentry/action-setup-venv@0958463ee0e02b9e8aa8f8e031afae1f84b80881 # v3.0.0 with: cache-dependency-path: uv.lock - install-cmd: uv sync --frozen --active + install-cmd: uv sync --all-packages --all-groups --frozen --active - name: Run black run: black --check --diff python-objectstore-client @@ -65,7 +65,7 @@ jobs: - uses: getsentry/action-setup-venv@0958463ee0e02b9e8aa8f8e031afae1f84b80881 # v3.0.0 with: cache-dependency-path: uv.lock - install-cmd: uv sync --frozen --active + install-cmd: uv sync --all-packages --all-groups --frozen --active - name: Run tests run: pytest python-objectstore-client From 790e69afb01b998fe906bf78ab54d857da169ca7 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:53:06 +0100 Subject: [PATCH 15/59] improve --- python-objectstore-client/tests/test_smoke.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python-objectstore-client/tests/test_smoke.py diff --git a/python-objectstore-client/tests/test_smoke.py b/python-objectstore-client/tests/test_smoke.py new file mode 100644 index 00000000..973231a0 --- /dev/null +++ b/python-objectstore-client/tests/test_smoke.py @@ -0,0 +1,4 @@ +def test_imports(): + import objectstore_client + + _ = objectstore_client From e209b318a7bf2a14398d26a82d921819ceb831c3 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:54:15 +0100 Subject: [PATCH 16/59] only tests in matrix --- .github/workflows/ci-python.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index d1bc3e89..8e5bff72 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -12,13 +12,8 @@ concurrency: jobs: lint: - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - - name: Lint (${{ matrix.os }}) - runs-on: ${{ matrix.os }} + name: Lint + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From ad1a9988ec6c542e8e9ae310acd3ffb1e0a43bf6 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:58:21 +0100 Subject: [PATCH 17/59] exclude mypy on windows --- python-objectstore-client/pyproject.toml | 2 +- uv.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 041f399c..362c46e6 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -16,7 +16,7 @@ dev = [ "black>=25.1.0", "isort>=5.13.2", "flake8>=7.3.0", - "mypy>=1.17.1", + "mypy>=1.17.1; sys_platform != 'win32'", ] [tool.mypy] diff --git a/uv.lock b/uv.lock index 75e4f884..794fc6e9 100644 --- a/uv.lock +++ b/uv.lock @@ -198,7 +198,7 @@ dev = [ { name = "black" }, { name = "flake8" }, { name = "isort" }, - { name = "mypy" }, + { name = "mypy", marker = "sys_platform != 'win32'" }, { name = "pytest" }, ] @@ -209,7 +209,7 @@ dev = [ { name = "black", specifier = ">=25.1.0" }, { name = "flake8", specifier = ">=7.3.0" }, { name = "isort", specifier = ">=5.13.2" }, - { name = "mypy", specifier = ">=1.17.1" }, + { name = "mypy", marker = "sys_platform != 'win32'", specifier = ">=1.17.1" }, { name = "pytest", specifier = ">=8.3.3" }, ] From 25c4df61e39fb1ea2e5da589777fc783065ac922 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:14:13 +0100 Subject: [PATCH 18/59] exclude precommit on windows --- pyproject.toml | 2 +- uv.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0ccd9358..11cb4f28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,5 +15,5 @@ members = [ [dependency-groups] dev = [ "devservices>=1.2.2", - "pre-commit>=4.2.0", + "pre-commit>=4.2.0; sys_platform != 'win32'", ] diff --git a/uv.lock b/uv.lock index 794fc6e9..c47a7533 100644 --- a/uv.lock +++ b/uv.lock @@ -177,7 +177,7 @@ source = { virtual = "." } [package.dev-dependencies] dev = [ { name = "devservices" }, - { name = "pre-commit" }, + { name = "pre-commit", marker = "sys_platform != 'win32'" }, ] [package.metadata] @@ -185,7 +185,7 @@ dev = [ [package.metadata.requires-dev] dev = [ { name = "devservices", specifier = ">=1.2.2" }, - { name = "pre-commit", specifier = ">=4.2.0" }, + { name = "pre-commit", marker = "sys_platform != 'win32'", specifier = ">=4.2.0" }, ] [[package]] From 5296238b862705d95e10279189684b906fbafa13 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:18:59 +0100 Subject: [PATCH 19/59] make internal pypi not exclusive - packages are missing on win --- pyproject.toml | 3 +-- python-objectstore-client/pyproject.toml | 2 +- uv.lock | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 11cb4f28..7639cdf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,6 @@ requires-python = ">=3.13" [[tool.uv.index]] url = "https://pypi.devinfra.sentry.io/simple" -default = true [tool.uv.workspace] members = [ @@ -15,5 +14,5 @@ members = [ [dependency-groups] dev = [ "devservices>=1.2.2", - "pre-commit>=4.2.0; sys_platform != 'win32'", + "pre-commit>=4.2.0", ] diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 362c46e6..041f399c 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -16,7 +16,7 @@ dev = [ "black>=25.1.0", "isort>=5.13.2", "flake8>=7.3.0", - "mypy>=1.17.1; sys_platform != 'win32'", + "mypy>=1.17.1", ] [tool.mypy] diff --git a/uv.lock b/uv.lock index c47a7533..75e4f884 100644 --- a/uv.lock +++ b/uv.lock @@ -177,7 +177,7 @@ source = { virtual = "." } [package.dev-dependencies] dev = [ { name = "devservices" }, - { name = "pre-commit", marker = "sys_platform != 'win32'" }, + { name = "pre-commit" }, ] [package.metadata] @@ -185,7 +185,7 @@ dev = [ [package.metadata.requires-dev] dev = [ { name = "devservices", specifier = ">=1.2.2" }, - { name = "pre-commit", marker = "sys_platform != 'win32'", specifier = ">=4.2.0" }, + { name = "pre-commit", specifier = ">=4.2.0" }, ] [[package]] @@ -198,7 +198,7 @@ dev = [ { name = "black" }, { name = "flake8" }, { name = "isort" }, - { name = "mypy", marker = "sys_platform != 'win32'" }, + { name = "mypy" }, { name = "pytest" }, ] @@ -209,7 +209,7 @@ dev = [ { name = "black", specifier = ">=25.1.0" }, { name = "flake8", specifier = ">=7.3.0" }, { name = "isort", specifier = ">=5.13.2" }, - { name = "mypy", marker = "sys_platform != 'win32'", specifier = ">=1.17.1" }, + { name = "mypy", specifier = ">=1.17.1" }, { name = "pytest", specifier = ">=8.3.3" }, ] From 41c5edf54a2cf8b97608efed397a0af3563da64b Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:25:49 +0100 Subject: [PATCH 20/59] ci only on win and macos --- .github/workflows/ci-python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 8e5bff72..2b4deca9 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -44,7 +44,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] name: Test (${{ matrix.os }}) runs-on: ${{ matrix.os }} From 5c2305edf03fac9994a9ac80d5e94ab2fd9a17d5 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:26:25 +0100 Subject: [PATCH 21/59] default = true --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 7639cdf9..0ccd9358 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ requires-python = ">=3.13" [[tool.uv.index]] url = "https://pypi.devinfra.sentry.io/simple" +default = true [tool.uv.workspace] members = [ From 7a6d503d5d7ba81fcc030cc66521010bd42242f3 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:22:21 +0100 Subject: [PATCH 22/59] lower py version, regenerate uv.lock --- pyproject.toml | 2 +- uv.lock | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0ccd9358..62dfaba6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "objectstore" version = "0.1.0" -requires-python = ">=3.13" +requires-python = ">=3.11.11" [[tool.uv.index]] url = "https://pypi.devinfra.sentry.io/simple" diff --git a/uv.lock b/uv.lock index 75e4f884..17d200ec 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.13" +requires-python = ">=3.11.11" [manifest] members = [ @@ -20,6 +20,12 @@ dependencies = [ { name = "platformdirs" }, ] wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc" }, + { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f" }, { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f" }, { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3" }, { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171" }, @@ -147,6 +153,14 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893" }, + { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914" }, { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc" }, { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e" }, { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986" }, @@ -295,6 +309,14 @@ name = "pyyaml" version = "6.0.3" source = { registry = "https://pypi.devinfra.sentry.io/simple" } wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28" }, + { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc" }, { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8" }, { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1" }, { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c" }, From e0c1a5277389e7d9eaed9b3f2c69ea2577ca3067 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:23:07 +0100 Subject: [PATCH 23/59] lower .python-version as well for CI --- .python-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.python-version b/.python-version index c10780c6..2d4715b6 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.13.1 +3.11.11 From 1ac9c9cb61a12fa501da8004ae4ce79af2d755e5 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:25:20 +0100 Subject: [PATCH 24/59] just require 3.11 --- .python-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.python-version b/.python-version index 2d4715b6..2c073331 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.11.11 +3.11 From 5c0e09fdec7becdf7fa30e0fe226bcb3895e6a39 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:28:37 +0100 Subject: [PATCH 25/59] lower req to 3.11.9 due to GH runners availability --- pyproject.toml | 2 +- python-objectstore-client/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 62dfaba6..f179b5f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "objectstore" version = "0.1.0" -requires-python = ">=3.11.11" +requires-python = ">=3.11.9" [[tool.uv.index]] url = "https://pypi.devinfra.sentry.io/simple" diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 041f399c..a7104c96 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -3,7 +3,7 @@ name = "objectstore-client" version = "0.1.0" description = "Python client for the Sentry Objectstore service" readme = "README.md" -requires-python = ">=3.11.11" +requires-python = ">=3.11.9" dependencies = [] [build-system] From b7ebd6625c9b7c57b2d749b857811ab31a628fb9 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:31:32 +0100 Subject: [PATCH 26/59] regerate lockfile with 3.11 --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 17d200ec..51c77b32 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.11.11" +requires-python = ">=3.11.9" [manifest] members = [ From 08fd43900155ec754b29156ac6ab5f30ae063351 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 28 Oct 2025 21:48:36 +0100 Subject: [PATCH 27/59] feat(py-client): Add Python client implementation --- python-objectstore-client/pyproject.toml | 6 +- .../src/objectstore_client/client.py | 237 ++++++++++++++++++ .../src/objectstore_client/metadata.py | 101 ++++++++ .../src/objectstore_client/metrics.py | 196 +++++++++++++++ python-objectstore-client/tests/test_smoke.py | 5 +- uv.lock | 50 +++- 6 files changed, 589 insertions(+), 6 deletions(-) create mode 100644 python-objectstore-client/src/objectstore_client/client.py create mode 100644 python-objectstore-client/src/objectstore_client/metadata.py create mode 100644 python-objectstore-client/src/objectstore_client/metrics.py diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index a7104c96..b3d8e421 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -4,7 +4,11 @@ version = "0.1.0" description = "Python client for the Sentry Objectstore service" readme = "README.md" requires-python = ">=3.11.9" -dependencies = [] +dependencies = [ + "sentry-sdk>=2.42.1", + "urllib3>=2.5.0", + "zstandard>=0.18.0", +] [build-system] requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini diff --git a/python-objectstore-client/src/objectstore_client/client.py b/python-objectstore-client/src/objectstore_client/client.py new file mode 100644 index 00000000..718e42d4 --- /dev/null +++ b/python-objectstore-client/src/objectstore_client/client.py @@ -0,0 +1,237 @@ +from __future__ import annotations + +from io import BytesIO +from typing import IO, Literal, NamedTuple, NotRequired, Self, TypedDict, cast +from urllib.parse import urlencode + +import sentry_sdk +import urllib3 +import zstandard +from urllib3.connectionpool import HTTPConnectionPool + +from objectstore_client.metadata import ( + HEADER_EXPIRATION, + HEADER_META_PREFIX, + Compression, + ExpirationPolicy, + Metadata, + format_expiration, +) +from objectstore_client.metrics import ( + MetricsBackend, + NoOpMetricsBackend, + measure_storage_operation, +) + +Permission = Literal["read", "write"] + + +class Scope(TypedDict): + organization: int + project: NotRequired[int] + + +class GetResult(NamedTuple): + metadata: Metadata + payload: IO[bytes] + + +class ClientBuilder: + def __init__( + self, + objectstore_base_url: str, + usecase: str, + options: dict | None = None, + metrics_backend: MetricsBackend | None = None, + propagate_traces: bool = False, + ): + self._base_url = objectstore_base_url + self._usecase = usecase + self._default_compression: Compression = "zstd" + self._propagate_traces = propagate_traces + self._metrics_backend = metrics_backend or NoOpMetricsBackend() + _ = options + + def _make_client(self, scope: str) -> Client: + pool = urllib3.connectionpool.connection_from_url(self._base_url) + return Client( + pool, + self._default_compression, + self._usecase, + scope, + self._propagate_traces, + self._metrics_backend, + ) + + def default_compression(self, default_compression: Compression) -> Self: + self._default_compression = default_compression + return self + + def for_organization(self, organization_id: int) -> Client: + return self._make_client(f"org.{organization_id}") + + def for_project(self, organization_id: int, project_id: int) -> Client: + return self._make_client(f"org.{organization_id}/proj.{project_id}") + + +class Client: + _default_compression: Compression + + def __init__( + self, + pool: HTTPConnectionPool, + default_compression: Compression, + usecase: str, + scope: str, + propagate_traces: bool, + metrics_backend: MetricsBackend, + ): + self._pool = pool + self._default_compression = default_compression + self._usecase = usecase + self._scope = scope + self._propagate_traces = propagate_traces + self._metrics_backend = metrics_backend + + def _make_headers(self) -> dict[str, str]: + if self._propagate_traces: + return dict(sentry_sdk.get_current_scope().iter_trace_propagation_headers()) + return {} + + def _make_url(self, id: str | None, full=False) -> str: + base_path = f"/v1/{id}" if id else "/v1/" + qs = urlencode({"usecase": self._usecase, "scope": self._scope}) + if full: + return f"http://{self._pool.host}:{self._pool.port}{base_path}?{qs}" + else: + return f"{base_path}?{qs}" + + def put( + self, + contents: bytes | IO[bytes], + id: str | None = None, + compression: Compression | Literal["none"] | None = None, + metadata: dict[str, str] | None = None, + expiration_policy: ExpirationPolicy | None = None, + ) -> str: + """ + Uploads the given `contents` to blob storage. + + If no `id` is provided, one will be automatically generated and returned + from this function. + + The client will select the configured `default_compression` if none is given + explicitly. + This can be overridden by explicitly giving a `compression` argument. + Providing `"none"` as the argument will instruct the client to not apply + any compression to this upload, which is useful for uncompressible formats. + """ + headers = self._make_headers() + body = BytesIO(contents) if isinstance(contents, bytes) else contents + original_body: IO[bytes] = body + + compression = compression or self._default_compression + if compression == "zstd": + cctx = zstandard.ZstdCompressor() + body = cctx.stream_reader(original_body) + headers["Content-Encoding"] = "zstd" + + if expiration_policy: + headers[HEADER_EXPIRATION] = format_expiration(expiration_policy) + + if metadata: + for k, v in metadata.items(): + headers[f"{HEADER_META_PREFIX}{k}"] = v + + with measure_storage_operation(self._metrics_backend, "put", self._usecase) as metric_emitter: + response = self._pool.request( + "PUT", + self._make_url(id), + body=body, + headers=headers, + preload_content=True, + decode_content=True, + ) + raise_for_status(response) + res = response.json() + + # Must do this after streaming `body` as that's what is responsible + # for advancing the seek position in both streams + metric_emitter.record_uncompressed_size(original_body.tell()) + if compression and compression != "none": + metric_emitter.record_compressed_size(body.tell(), compression) + return res["key"] + + def get(self, id: str, decompress: bool = True) -> GetResult: + """ + This fetches the blob with the given `id`, returning an `IO` stream that + can be read. + + By default, content that was uploaded compressed will be automatically + decompressed, unless `decompress=True` is passed. + """ + + headers = self._make_headers() + with measure_storage_operation(self._metrics_backend, "get", self._usecase): + response = self._pool.request( + "GET", + self._make_url(id), + preload_content=False, + decode_content=False, + headers=headers, + ) + raise_for_status(response) + # OR: should I use `response.stream()`? + stream = cast(IO[bytes], response) + metadata = Metadata.from_headers(response.headers) + + if metadata.compression and decompress: + if metadata.compression != "zstd": + raise NotImplementedError("Transparent decoding of anything but `zstd` is not implemented yet") + + metadata.compression = None + dctx = zstandard.ZstdDecompressor() + stream = dctx.stream_reader(stream, read_across_frames=True) + + return GetResult(metadata, stream) + + def object_url(self, id: str) -> str: + """ + Generates a GET url to the object with the given `id`. + + This can then be used by downstream services to fetch the given object. + NOTE however that the service does not strictly follow HTTP semantics, + in particular in relation to `Accept-Encoding`. + """ + return self._make_url(id, full=True) + + def delete(self, id: str): + """ + Deletes the blob with the given `id`. + """ + + headers = self._make_headers() + with measure_storage_operation(self._metrics_backend, "delete", self._usecase): + response = self._pool.request( + "DELETE", + self._make_url(id), + headers=headers, + ) + raise_for_status(response) + + +class ClientError(Exception): + def __init__(self, message: str, status: int, response: str): + super().__init__(message) + self.status = status + self.response = response + + +def raise_for_status(response: urllib3.BaseHTTPResponse): + if response.status >= 400: + res = str(response.data or response.read()) + raise ClientError( + f"Objectstore request failed with status {response.status}", + response.status, + res, + ) diff --git a/python-objectstore-client/src/objectstore_client/metadata.py b/python-objectstore-client/src/objectstore_client/metadata.py new file mode 100644 index 00000000..f7488959 --- /dev/null +++ b/python-objectstore-client/src/objectstore_client/metadata.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import itertools +import re +from collections.abc import Mapping +from dataclasses import dataclass +from datetime import timedelta +from typing import Literal, cast + +Compression = Literal["zstd"] + +HEADER_EXPIRATION = "x-sn-expiration" +HEADER_META_PREFIX = "x-snme-" + + +@dataclass +class TimeToIdle: + delta: timedelta + + +@dataclass +class TimeToLive: + delta: timedelta + + +ExpirationPolicy = TimeToIdle | TimeToLive + + +@dataclass +class Metadata: + compression: Compression | None + expiration_policy: ExpirationPolicy | None + custom: dict[str, str] + + @classmethod + def from_headers(cls, headers: Mapping[str, str]) -> Metadata: + compression = None + expiration_policy = None + custom_metadata = {} + for k, v in headers.items(): + if k == "content-encoding": + compression = cast(Compression | None, v) + elif k == HEADER_EXPIRATION: + expiration_policy = parse_expiration(v) + elif k.startswith(HEADER_META_PREFIX): + custom_metadata[k[len(HEADER_META_PREFIX) :]] = v + return Metadata(compression, expiration_policy, custom_metadata) + + +def format_expiration(expiration_policy: ExpirationPolicy) -> str: + if isinstance(expiration_policy, TimeToIdle): + return f"tti:{format_timedelta(expiration_policy.delta)}" + elif isinstance(expiration_policy, TimeToLive): + return f"ttl:{format_timedelta(expiration_policy.delta)}" + + +def parse_expiration(value: str) -> ExpirationPolicy | None: + if value.startswith("tti:"): + return TimeToIdle(parse_timedelta(value[4:])) + elif value.startswith("ttl:"): + return TimeToLive(parse_timedelta(value[4:])) + + return None + + +def format_timedelta(delta: timedelta) -> str: + days = delta.days + output = f"{days} days" if days else "" + if seconds := delta.seconds: + if output: + output += " " + output += f"{seconds} seconds" + + return output + + +TIME_SPLIT = re.compile(r"[^\W\d_]+|\d+") + + +def parse_timedelta(delta: str) -> timedelta: + words = TIME_SPLIT.findall(delta) + seconds = 0 + + for num, unit in itertools.batched(words, n=2, strict=True): + num = int(num) + multiplier = 0 + + if unit.startswith("w"): + multiplier = 86400 * 7 + elif unit.startswith("d"): + multiplier = 86400 + elif unit.startswith("h"): + multiplier = 3600 + elif unit.startswith("m") and not unit.startswith("ms"): + multiplier = 60 + elif unit.startswith("s"): + multiplier = 1 + + seconds += num * multiplier + + return timedelta(seconds=seconds) diff --git a/python-objectstore-client/src/objectstore_client/metrics.py b/python-objectstore-client/src/objectstore_client/metrics.py new file mode 100644 index 00000000..b848f9e7 --- /dev/null +++ b/python-objectstore-client/src/objectstore_client/metrics.py @@ -0,0 +1,196 @@ +from __future__ import annotations + +import time +from abc import abstractmethod +from collections.abc import Generator +from contextlib import contextmanager +from typing import Mapping, Protocol, Union, runtime_checkable + +Tags = Mapping[str, str] + + +@runtime_checkable +class MetricsBackend(Protocol): + """ + An abstract class that defines the interface for metrics backends. + """ + + @abstractmethod + def increment( + self, + name: str, + value: Union[int, float] = 1, + tags: Tags | None = None, + ) -> None: + """ + Increments a counter metric by a given value. + """ + raise NotImplementedError + + @abstractmethod + def gauge(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: + """ + Sets a gauge metric to the given value. + """ + raise NotImplementedError + + @abstractmethod + def timing(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: + """ + Records a timing metric. + """ + raise NotImplementedError + + @abstractmethod + def distribution( + self, + name: str, + value: Union[int, float], + tags: Tags | None = None, + unit: str | None = None, + ) -> None: + """ + Records a distribution metric. + """ + raise NotImplementedError + + +class NoOpMetricsBackend(MetricsBackend): + """ + Default metrics backend that does not record anything. + """ + + def increment( + self, + name: str, + value: Union[int, float] = 1, + tags: Tags | None = None, + ) -> None: + """ + Increments a counter metric by a given value. + """ + pass + + def gauge(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: + """ + Sets a gauge metric to the given value. + """ + pass + + def timing(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: + """ + Records a timing metric. + """ + pass + + def distribution( + self, + name: str, + value: Union[int, float], + tags: Tags | None = None, + unit: str | None = None, + ) -> None: + """ + Records a distribution metric. + """ + pass + + +class StorageMetricEmitter: + def __init__(self, backend: MetricsBackend, operation: str, usecase: str): + self.backend = backend + self.operation = operation + self.usecase = usecase + + # These may be set during or after the enclosed operation + self.start: int | None = None + self.elapsed: float | None = None + self.uncompressed_size: int | None = None + self.compressed_size: int | None = None + self.compression: str = "unknown" + + def record_latency(self, elapsed: float) -> None: + tags = {"usecase": self.usecase} + self.backend.timing(f"storage.{self.operation}.latency", elapsed, tags=tags) + self.elapsed = elapsed + + def record_uncompressed_size(self, value: int) -> None: + tags = {"usecase": self.usecase, "compression": "none"} + self.backend.distribution(f"storage.{self.operation}.size", value, tags=tags, unit="byte") + self.uncompressed_size = value + + def record_compressed_size(self, value: int, compression: str = "unknown") -> None: + tags = {"usecase": self.usecase, "compression": compression} + self.backend.distribution(f"storage.{self.operation}.size", value, tags=tags, unit="byte") + self.compressed_size = value + self.compression = compression + + def maybe_record_compression_ratio(self) -> None: + if not self.uncompressed_size or not self.compressed_size: + return None + + tags = {"usecase": self.usecase, "compression": self.compression} + self.backend.distribution( + f"storage.{self.operation}.compression_ratio", + self.compressed_size / self.uncompressed_size, + tags=tags, + ) + + def maybe_record_throughputs(self) -> None: + if not self.elapsed or self.elapsed <= 0: + return None + + sizes = [] + if self.uncompressed_size: + sizes.append((self.uncompressed_size, "none")) + if self.compressed_size: + sizes.append((self.compressed_size, self.compression)) + + for size, compression in sizes: + tags = {"usecase": self.usecase, "compression": compression} + self.backend.distribution(f"storage.{self.operation}.throughput", size / self.elapsed, tags=tags) + self.backend.distribution( + f"storage.{self.operation}.inverse_throughput", + self.elapsed / size, + tags=tags, + ) + + +@contextmanager +def measure_storage_operation( + backend: MetricsBackend, + operation: str, + usecase: str, + uncompressed_size: int | None = None, + compressed_size: int | None = None, + compression: str = "unknown", +) -> Generator[StorageMetricEmitter]: + """ + Context manager which records the latency of the enclosed storage operation. + Can also record the compressed or uncompressed size of an object, the + compression ratio, the throughput, and the inverse throughput. + + Yields a `StorageMetricEmitter` because for some operations (GET) the size + is not known until the inside of the enclosed block. + """ + emitter = StorageMetricEmitter(backend, operation, usecase) + + if uncompressed_size: + emitter.record_uncompressed_size(uncompressed_size) + if compressed_size: + emitter.record_compressed_size(compressed_size, compression) + + start = time.monotonic() + + # Yield an emitter in case the size becomes known inside the enclosed block + try: + yield emitter + + finally: + elapsed = time.monotonic() - start + emitter.record_latency(elapsed) + + # If `uncompressed_size` and/or `compressed_size` have been set, we have + # extra metrics we can send. + emitter.maybe_record_compression_ratio() + emitter.maybe_record_throughputs() diff --git a/python-objectstore-client/tests/test_smoke.py b/python-objectstore-client/tests/test_smoke.py index 973231a0..757f410d 100644 --- a/python-objectstore-client/tests/test_smoke.py +++ b/python-objectstore-client/tests/test_smoke.py @@ -1,4 +1,3 @@ def test_imports(): - import objectstore_client - - _ = objectstore_client + import objectstore_client # noqa: F401 + from objectstore_client import client, metadata, metrics # noqa: F401 diff --git a/uv.lock b/uv.lock index 51c77b32..ad41a87c 100644 --- a/uv.lock +++ b/uv.lock @@ -40,6 +40,20 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" }, ] +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26" }, +] + [[package]] name = "cfgv" version = "3.4.0" @@ -206,6 +220,11 @@ dev = [ name = "objectstore-client" version = "0.1.0" source = { editable = "python-objectstore-client" } +dependencies = [ + { name = "sentry-sdk" }, + { name = "urllib3" }, + { name = "zstandard" }, +] [package.dev-dependencies] dev = [ @@ -217,6 +236,11 @@ dev = [ ] [package.metadata] +requires-dist = [ + { name = "sentry-sdk", specifier = ">=2.42.1" }, + { name = "urllib3", specifier = ">=2.5.0" }, + { name = "zstandard", specifier = ">=0.18.0" }, +] [package.metadata.requires-dev] dev = [ @@ -282,6 +306,14 @@ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" }, ] +[[package]] +name = "pycparser" +version = "2.23" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934" }, +] + [[package]] name = "pyflakes" version = "3.4.0" @@ -337,14 +369,14 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.42.0" +version = "2.42.1" source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/sentry_sdk-2.42.0-py2.py3-none-any.whl", hash = "sha256:1a7986e638306ff158f52dd47d9480a4055e6c289388caa90628acb2563fe7bd" }, + { url = "https://pypi.devinfra.sentry.io/wheels/sentry_sdk-2.42.1-py2.py3-none-any.whl", hash = "sha256:f8716b50c927d3beb41bc88439dc6bcd872237b596df5b14613e2ade104aee02" }, ] [[package]] @@ -394,3 +426,17 @@ dependencies = [ wheels = [ { url = "https://pypi.devinfra.sentry.io/wheels/virtualenv-20.29.3-py3-none-any.whl", hash = "sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170" }, ] + +[[package]] +name = "zstandard" +version = "0.18.0" +source = { registry = "https://pypi.devinfra.sentry.io/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation == 'PyPy'" }, +] +wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:032ddaf24458986a31ff49d2fa86a4003e1e1c34c38976bedd06805350eaeddc" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d68ff7c3a4c35400d807efbfa793767c2d4866a7017770b424e65749a70e958e" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1ef5b96f0e90855ea13d06b7213a75a77a23946d8bb186ff38578dd1ff5efd4" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:754256fb4080a36f8992983b2f65f23719d275c9a350bcf18d76344ed64efa19" }, +] From 984888cbc1b45ee0d4b20af2533a711db453e2fb Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:54:44 +0100 Subject: [PATCH 28/59] improve --- .../src/objectstore_client/metrics.py | 12 ------------ python-objectstore-client/setup.cfg => setup.cfg | 0 2 files changed, 12 deletions(-) rename python-objectstore-client/setup.cfg => setup.cfg (100%) diff --git a/python-objectstore-client/src/objectstore_client/metrics.py b/python-objectstore-client/src/objectstore_client/metrics.py index b848f9e7..6e26d395 100644 --- a/python-objectstore-client/src/objectstore_client/metrics.py +++ b/python-objectstore-client/src/objectstore_client/metrics.py @@ -66,21 +66,12 @@ def increment( value: Union[int, float] = 1, tags: Tags | None = None, ) -> None: - """ - Increments a counter metric by a given value. - """ pass def gauge(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: - """ - Sets a gauge metric to the given value. - """ pass def timing(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: - """ - Records a timing metric. - """ pass def distribution( @@ -90,9 +81,6 @@ def distribution( tags: Tags | None = None, unit: str | None = None, ) -> None: - """ - Records a distribution metric. - """ pass diff --git a/python-objectstore-client/setup.cfg b/setup.cfg similarity index 100% rename from python-objectstore-client/setup.cfg rename to setup.cfg From d24bf591078e0275c6946d61914bafac8e1b5034 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:04:26 +0100 Subject: [PATCH 29/59] improve --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index a6578a30..c0cafb89 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,2 @@ [flake8] -extend-ignore = E501 +extend-ignore = E501,E203 From f62f75495e17dff799862b3d7b8f64fa0b968329 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:35:53 +0100 Subject: [PATCH 30/59] regerate lockfile for 3.11 --- uv.lock | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/uv.lock b/uv.lock index ad41a87c..76a10f9c 100644 --- a/uv.lock +++ b/uv.lock @@ -48,6 +48,14 @@ dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062" }, + { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba" }, { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb" }, { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca" }, { url = "https://pypi.devinfra.sentry.io/wheels/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b" }, @@ -435,6 +443,14 @@ dependencies = [ { name = "cffi", marker = "platform_python_implementation == 'PyPy'" }, ] wheels = [ + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f9d32f509b84b7158d46ba673f1c5123a80062652517e9e56240ded7df3d744e" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:ed3937c3d703c7f74f341fb530c9523b012923897e7979565ac0f3cb4f808d98" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05552e29b1b580543cc22ae7ca9fb833e136a1843ef660a96679d246e666bbeb" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbe2bd4cab395a157c61f059f60ec4e099ef207cd970d66f0ba184f9c2e25d37" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2eab9516bc4352fc9763d96047c815879f3efb1dfb5dfe2f775b2e22c0289cb6" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e1f98ffd138d172efd202cd078e746af80492c6942004b080bf627c5f826da5" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:07a72264613c75fe6eb64f07ab553d3cfab7a421c8733e067a8718ef69c642a7" }, + { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee14cc6b8b40733a707b467ddc192592cab941babf82b3e6f700673e050b4bda" }, { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:032ddaf24458986a31ff49d2fa86a4003e1e1c34c38976bedd06805350eaeddc" }, { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d68ff7c3a4c35400d807efbfa793767c2d4866a7017770b424e65749a70e958e" }, { url = "https://pypi.devinfra.sentry.io/wheels/zstandard-0.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1ef5b96f0e90855ea13d06b7213a75a77a23946d8bb186ff38578dd1ff5efd4" }, From 53d7f41de316f5eaaa8c6e93db970c01fb38a93c Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:59:29 +0100 Subject: [PATCH 31/59] vendor in itertools.batched --- .../src/objectstore_client/metadata.py | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/python-objectstore-client/src/objectstore_client/metadata.py b/python-objectstore-client/src/objectstore_client/metadata.py index f7488959..b718b98f 100644 --- a/python-objectstore-client/src/objectstore_client/metadata.py +++ b/python-objectstore-client/src/objectstore_client/metadata.py @@ -5,7 +5,9 @@ from collections.abc import Mapping from dataclasses import dataclass from datetime import timedelta -from typing import Literal, cast +from typing import Iterable, Iterator, Literal, TypeVar, cast + +T = TypeVar("T") Compression = Literal["zstd"] @@ -77,11 +79,30 @@ def format_timedelta(delta: timedelta) -> str: TIME_SPLIT = re.compile(r"[^\W\d_]+|\d+") +def itertools_batched(iterable: Iterable[T], n: int, strict: bool = False) -> Iterator[tuple[T, ...]]: + """ + Vendored version of `itertools.batched`, not available in Python 3.11. + + Batch data from the iterable into tuples of length n. The last batch may be shorter than n. + + If strict is true, will raise a ValueError if the final batch is shorter than n. + + Loops over the input iterable and accumulates data into tuples up to size n. The input is consumed lazily, just enough to fill a batch. The result is yielded as soon as the batch is full or when the input iterable is exhausted: + """ + if n < 1: + raise ValueError("n must be at least one") + iterator = iter(iterable) + while batch := tuple(itertools.islice(iterator, n)): + if strict and len(batch) < n: + raise ValueError("final batch is shorter than n") + yield batch + + def parse_timedelta(delta: str) -> timedelta: words = TIME_SPLIT.findall(delta) seconds = 0 - for num, unit in itertools.batched(words, n=2, strict=True): + for num, unit in itertools_batched(words, n=2, strict=True): num = int(num) multiplier = 0 From ce3dcb67e57dd42c17f1fb5d3caba57fe5aa0e91 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 12:00:40 +0100 Subject: [PATCH 32/59] improve --- .../src/objectstore_client/metadata.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python-objectstore-client/src/objectstore_client/metadata.py b/python-objectstore-client/src/objectstore_client/metadata.py index b718b98f..10f4e26d 100644 --- a/python-objectstore-client/src/objectstore_client/metadata.py +++ b/python-objectstore-client/src/objectstore_client/metadata.py @@ -7,8 +7,6 @@ from datetime import timedelta from typing import Iterable, Iterator, Literal, TypeVar, cast -T = TypeVar("T") - Compression = Literal["zstd"] HEADER_EXPIRATION = "x-sn-expiration" @@ -76,7 +74,7 @@ def format_timedelta(delta: timedelta) -> str: return output -TIME_SPLIT = re.compile(r"[^\W\d_]+|\d+") +T = TypeVar("T") def itertools_batched(iterable: Iterable[T], n: int, strict: bool = False) -> Iterator[tuple[T, ...]]: @@ -98,6 +96,9 @@ def itertools_batched(iterable: Iterable[T], n: int, strict: bool = False) -> It yield batch +TIME_SPLIT = re.compile(r"[^\W\d_]+|\d+") + + def parse_timedelta(delta: str) -> timedelta: words = TIME_SPLIT.findall(delta) seconds = 0 From db5229d7e74ec011bbaa0d25f836b015ffa4cf5d Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 14:07:27 +0100 Subject: [PATCH 33/59] move flake8 config to pyproject.toml --- python-objectstore-client/pyproject.toml | 3 +++ setup.cfg | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 setup.cfg diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index b3d8e421..f93755e5 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -35,6 +35,9 @@ local_partial_types = true disallow_any_generics = true disallow_untyped_defs = true +[tool.flake8] +extend-ignore = ["E501", "E203"] + [tool.black] line-length = 200 target-version = ['py311'] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index c0cafb89..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -extend-ignore = E501,E203 From 5cffe3feec27462104bbc3c8648cd140efeb3060 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 14:08:48 +0100 Subject: [PATCH 34/59] improve --- pyproject.toml | 3 +++ python-objectstore-client/pyproject.toml | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f179b5f5..dfff1910 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,3 +17,6 @@ dev = [ "devservices>=1.2.2", "pre-commit>=4.2.0", ] + +[tool.flake8] +extend-ignore = ["E501", "E203"] diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index f93755e5..b3d8e421 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -35,9 +35,6 @@ local_partial_types = true disallow_any_generics = true disallow_untyped_defs = true -[tool.flake8] -extend-ignore = ["E501", "E203"] - [tool.black] line-length = 200 target-version = ['py311'] From 8ab54672ffcfb5e0c3d3d5ae7be3940b2373d16d Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 14:15:39 +0100 Subject: [PATCH 35/59] readd back setup.cfg --- pyproject.toml | 3 --- setup.cfg | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 setup.cfg diff --git a/pyproject.toml b/pyproject.toml index dfff1910..f179b5f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,3 @@ dev = [ "devservices>=1.2.2", "pre-commit>=4.2.0", ] - -[tool.flake8] -extend-ignore = ["E501", "E203"] diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..c0cafb89 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +extend-ignore = E501,E203 From 75c60659d8018399aef7ee35cf6bb9111db352c9 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:11:31 +0100 Subject: [PATCH 36/59] use public PyPI for now --- pyproject.toml | 4 - uv.lock | 331 +++++++++++++++++++++++++++++++------------------ 2 files changed, 211 insertions(+), 124 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f179b5f5..441495ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,10 +3,6 @@ name = "objectstore" version = "0.1.0" requires-python = ">=3.11.9" -[[tool.uv.index]] -url = "https://pypi.devinfra.sentry.io/simple" -default = true - [tool.uv.workspace] members = [ "python-objectstore-client", diff --git a/uv.lock b/uv.lock index 51c77b32..57a7e0f7 100644 --- a/uv.lock +++ b/uv.lock @@ -10,67 +10,76 @@ members = [ [[package]] name = "black" -version = "25.1.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "25.9.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "mypy-extensions" }, { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, + { name = "pytokens" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171" }, - { url = "https://pypi.devinfra.sentry.io/wheels/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717" }, + { url = "https://files.pythonhosted.org/packages/b7/f4/7531d4a336d2d4ac6cc101662184c8e7d068b548d35d874415ed9f4116ef/black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa", size = 1698727, upload-time = "2025-09-19T00:31:14.264Z" }, + { url = "https://files.pythonhosted.org/packages/28/f9/66f26bfbbf84b949cc77a41a43e138d83b109502cd9c52dfc94070ca51f2/black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d", size = 1555679, upload-time = "2025-09-19T00:31:29.265Z" }, + { url = "https://files.pythonhosted.org/packages/bf/59/61475115906052f415f518a648a9ac679d7afbc8da1c16f8fdf68a8cebed/black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608", size = 1617453, upload-time = "2025-09-19T00:30:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5b/20fd5c884d14550c911e4fb1b0dae00d4abb60a4f3876b449c4d3a9141d5/black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f", size = 1333655, upload-time = "2025-09-19T00:30:56.715Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8e/319cfe6c82f7e2d5bfb4d3353c6cc85b523d677ff59edc61fdb9ee275234/black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0", size = 1742012, upload-time = "2025-09-19T00:33:08.678Z" }, + { url = "https://files.pythonhosted.org/packages/94/cc/f562fe5d0a40cd2a4e6ae3f685e4c36e365b1f7e494af99c26ff7f28117f/black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4", size = 1581421, upload-time = "2025-09-19T00:35:25.937Z" }, + { url = "https://files.pythonhosted.org/packages/84/67/6db6dff1ebc8965fd7661498aea0da5d7301074b85bba8606a28f47ede4d/black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e", size = 1655619, upload-time = "2025-09-19T00:30:49.241Z" }, + { url = "https://files.pythonhosted.org/packages/10/10/3faef9aa2a730306cf469d76f7f155a8cc1f66e74781298df0ba31f8b4c8/black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a", size = 1342481, upload-time = "2025-09-19T00:31:29.625Z" }, + { url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" }, + { url = "https://files.pythonhosted.org/packages/21/17/5c253aa80a0639ccc427a5c7144534b661505ae2b5a10b77ebe13fa25334/black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", size = 1343428, upload-time = "2025-09-19T00:32:13.839Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" }, ] [[package]] name = "certifi" -version = "2025.8.3" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "2025.10.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] name = "cfgv" version = "3.4.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9" }, + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] [[package]] name = "click" version = "8.3.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc" }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] [[package]] name = "colorama" version = "0.4.6" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "devservices" version = "1.2.2" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "pyyaml" }, @@ -78,109 +87,133 @@ dependencies = [ { name = "sentry-sdk" }, { name = "supervisor" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/97/70/f72c146a562161def21f56701b690176a1cfb1c24f1e5f3e062fe1479770/devservices-1.2.2.tar.gz", hash = "sha256:9e6dc105ec6be210ab5d23f0abbd270ae1d98af73e84e4c62185f18ea40f9361", size = 89717, upload-time = "2025-09-26T20:38:46.4Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/devservices-1.2.2-py3-none-any.whl", hash = "sha256:5d102b3fe91050dd7dea21c9677b09778a0ea120bbcddeb3800a8cbe11141bae" }, + { url = "https://files.pythonhosted.org/packages/3e/98/769e6a3507f5d480e533aeb1f2ece970f54c6082723d0fa8403d307c4028/devservices-1.2.2-py3-none-any.whl", hash = "sha256:5d102b3fe91050dd7dea21c9677b09778a0ea120bbcddeb3800a8cbe11141bae", size = 116952, upload-time = "2025-09-26T20:38:45.333Z" }, ] [[package]] name = "distlib" -version = "0.3.9" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87" }, + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] [[package]] name = "filelock" -version = "3.19.1" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d" }, + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, ] [[package]] name = "flake8" version = "7.3.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mccabe" }, { name = "pycodestyle" }, { name = "pyflakes" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/9b/af/fbfe3c4b5a657d79e5c47a2827a362f9e1b763336a52f926126aa6dc7123/flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872", size = 48326, upload-time = "2025-06-20T19:31:35.838Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e" }, + { url = "https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", size = 57922, upload-time = "2025-06-20T19:31:34.425Z" }, ] [[package]] name = "identify" -version = "2.6.9" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "2.6.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/identify-2.6.9-py2.py3-none-any.whl", hash = "sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150" }, + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, ] [[package]] name = "iniconfig" -version = "2.0.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "isort" -version = "6.0.1" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615" }, + { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, ] [[package]] name = "mccabe" version = "0.7.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" }, + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, ] [[package]] name = "mypy" version = "1.18.2" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "pathspec" }, { name = "typing-extensions" }, ] -wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986" }, - { url = "https://pypi.devinfra.sentry.io/wheels/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d" }, +sdist = { url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b", size = 3448846, upload-time = "2025-09-19T00:11:10.519Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f", size = 12731198, upload-time = "2025-09-19T00:09:44.857Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341", size = 11817879, upload-time = "2025-09-19T00:09:47.131Z" }, + { url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d", size = 12427292, upload-time = "2025-09-19T00:10:22.472Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86", size = 13163750, upload-time = "2025-09-19T00:09:51.472Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37", size = 13351827, upload-time = "2025-09-19T00:09:58.311Z" }, + { url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8", size = 9757983, upload-time = "2025-09-19T00:10:09.071Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34", size = 12908273, upload-time = "2025-09-19T00:10:58.321Z" }, + { url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764", size = 11920910, upload-time = "2025-09-19T00:10:20.043Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893", size = 12465585, upload-time = "2025-09-19T00:10:33.005Z" }, + { url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914", size = 13348562, upload-time = "2025-09-19T00:10:11.51Z" }, + { url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8", size = 13533296, upload-time = "2025-09-19T00:10:06.568Z" }, + { url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074", size = 9828828, upload-time = "2025-09-19T00:10:28.203Z" }, + { url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc", size = 12898728, upload-time = "2025-09-19T00:10:01.33Z" }, + { url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e", size = 11910758, upload-time = "2025-09-19T00:10:42.607Z" }, + { url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986", size = 12475342, upload-time = "2025-09-19T00:11:00.371Z" }, + { url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d", size = 13338709, upload-time = "2025-09-19T00:11:03.358Z" }, + { url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba", size = 13529806, upload-time = "2025-09-19T00:10:26.073Z" }, + { url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544", size = 9833262, upload-time = "2025-09-19T00:10:40.035Z" }, + { url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce", size = 12893775, upload-time = "2025-09-19T00:10:03.814Z" }, + { url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d", size = 11936852, upload-time = "2025-09-19T00:10:51.631Z" }, + { url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c", size = 12480242, upload-time = "2025-09-19T00:11:07.955Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" }, + { url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" }, + { url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" }, ] [[package]] name = "mypy-extensions" version = "1.1.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505" }, + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9" }, + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] @@ -230,39 +263,43 @@ dev = [ [[package]] name = "packaging" version = "25.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pathspec" version = "0.12.1" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08" }, + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "platformdirs" -version = "4.3.8" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4" }, + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, ] [[package]] name = "pluggy" -version = "1.5.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "pre-commit" -version = "4.2.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cfgv" }, { name = "identify" }, @@ -270,127 +307,181 @@ dependencies = [ { name = "pyyaml" }, { name = "virtualenv" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/ff/29/7cf5bbc236333876e4b41f56e06857a87937ce4bf91e117a6991a2dbb02a/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16", size = 193792, upload-time = "2025-08-09T18:56:14.651Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd" }, + { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, ] [[package]] name = "pycodestyle" version = "2.14.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" }, + { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, ] [[package]] name = "pyflakes" version = "3.4.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/dc/fd034dc20b4b264b3d015808458391acbf9df40b1e54750ef175d39180b1/pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", size = 64669, upload-time = "2025-06-20T18:45:27.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload-time = "2025-06-20T18:45:26.937Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f" }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pytest" -version = "8.3.3" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] + +[[package]] +name = "pytokens" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/c2/dbadcdddb412a267585459142bfd7cc241e6276db69339353ae6e241ab2b/pytokens-0.2.0.tar.gz", hash = "sha256:532d6421364e5869ea57a9523bf385f02586d4662acbcc0342afd69511b4dd43", size = 15368, upload-time = "2025-10-15T08:02:42.738Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2" }, + { url = "https://files.pythonhosted.org/packages/89/5a/c269ea6b348b6f2c32686635df89f32dbe05df1088dd4579302a6f8f99af/pytokens-0.2.0-py3-none-any.whl", hash = "sha256:74d4b318c67f4295c13782ddd9abcb7e297ec5630ad060eb90abf7ebbefe59f8", size = 12038, upload-time = "2025-10-15T08:02:41.694Z" }, ] [[package]] name = "pyyaml" version = "6.0.3" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } -wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c" }, - { url = "https://pypi.devinfra.sentry.io/wheels/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6" }, +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "sentry-devenv" version = "1.23.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sentry-sdk" }, { name = "typing-extensions" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/d8/fc/3235c22f5ccf6b5d82612d2db0f61b70a939e88d7582fe34b8e2f0654fd9/sentry_devenv-1.23.0.tar.gz", hash = "sha256:6bd3d0d2b918b19f012e3f51ec03c337245e40ce0386711b64ef5566482495e8", size = 49808, upload-time = "2025-09-30T22:18:18.277Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/sentry_devenv-1.23.0-py3-none-any.whl", hash = "sha256:bf1d930b8672bdafd8deebdca998e3777acab8060fea1dd3fb92208631321565" }, + { url = "https://files.pythonhosted.org/packages/42/3b/8bf6c9f5fc354e3e00fa44d4bfc54f7e14b7545158a668a057f97b703202/sentry_devenv-1.23.0-py3-none-any.whl", hash = "sha256:bf1d930b8672bdafd8deebdca998e3777acab8060fea1dd3fb92208631321565", size = 68471, upload-time = "2025-09-30T22:18:17.303Z" }, ] [[package]] name = "sentry-sdk" -version = "2.42.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "2.43.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953, upload-time = "2025-10-29T11:26:08.156Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/sentry_sdk-2.42.0-py2.py3-none-any.whl", hash = "sha256:1a7986e638306ff158f52dd47d9480a4055e6c289388caa90628acb2563fe7bd" }, -] - -[[package]] -name = "setuptools" -version = "78.1.1" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } -wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/setuptools-78.1.1-py3-none-any.whl", hash = "sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561" }, + { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997, upload-time = "2025-10-29T11:26:05.77Z" }, ] [[package]] name = "supervisor" -version = "4.2.5" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } -dependencies = [ - { name = "setuptools" }, -] +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/b5/37e7a3706de436a8a2d75334711dad1afb4ddffab09f25e31d89e467542f/supervisor-4.3.0.tar.gz", hash = "sha256:4a2bf149adf42997e1bb44b70c43b613275ec9852c3edacca86a9166b27e945e", size = 468912, upload-time = "2025-08-23T18:25:02.418Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/supervisor-4.2.5-py2.py3-none-any.whl", hash = "sha256:2ecaede32fc25af814696374b79e42644ecaba5c09494c51016ffda9602d0f08" }, + { url = "https://files.pythonhosted.org/packages/0e/65/5e726c372da8a5e35022a94388b12252710aad0c2351699c3d76ae8dba78/supervisor-4.3.0-py2.py3-none-any.whl", hash = "sha256:0bcb763fddafba410f35cbde226aa7f8514b9fb82eb05a0c85f6588d1c13f8db", size = 320736, upload-time = "2025-08-23T18:25:00.767Z" }, ] [[package]] name = "typing-extensions" version = "4.15.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] name = "urllib3" version = "2.5.0" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "virtualenv" -version = "20.29.3" -source = { registry = "https://pypi.devinfra.sentry.io/simple" } +version = "20.35.4" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" } wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/virtualenv-20.29.3-py3-none-any.whl", hash = "sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170" }, + { url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" }, ] From 074da702ed0240b566a44913286f16bd0c188091 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:19:42 +0100 Subject: [PATCH 37/59] back to python 3.13 --- .python-version | 2 +- pyproject.toml | 2 +- python-objectstore-client/pyproject.toml | 4 +-- uv.lock | 41 +----------------------- 4 files changed, 5 insertions(+), 44 deletions(-) diff --git a/.python-version b/.python-version index 2c073331..24ee5b1b 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.11 +3.13 diff --git a/pyproject.toml b/pyproject.toml index 441495ab..484b3f8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "objectstore" version = "0.1.0" -requires-python = ">=3.11.9" +requires-python = ">=3.13" [tool.uv.workspace] members = [ diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index a7104c96..54792703 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -3,7 +3,7 @@ name = "objectstore-client" version = "0.1.0" description = "Python client for the Sentry Objectstore service" readme = "README.md" -requires-python = ">=3.11.9" +requires-python = ">=3.13" dependencies = [] [build-system] @@ -33,7 +33,7 @@ disallow_untyped_defs = true [tool.black] line-length = 200 -target-version = ['py311'] +target-version = ['py313'] [tool.isort] profile = "black" diff --git a/uv.lock b/uv.lock index 57a7e0f7..f4c9adad 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.11.9" +requires-python = ">=3.13" [manifest] members = [ @@ -22,14 +22,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/f4/7531d4a336d2d4ac6cc101662184c8e7d068b548d35d874415ed9f4116ef/black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa", size = 1698727, upload-time = "2025-09-19T00:31:14.264Z" }, - { url = "https://files.pythonhosted.org/packages/28/f9/66f26bfbbf84b949cc77a41a43e138d83b109502cd9c52dfc94070ca51f2/black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d", size = 1555679, upload-time = "2025-09-19T00:31:29.265Z" }, - { url = "https://files.pythonhosted.org/packages/bf/59/61475115906052f415f518a648a9ac679d7afbc8da1c16f8fdf68a8cebed/black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608", size = 1617453, upload-time = "2025-09-19T00:30:42.24Z" }, - { url = "https://files.pythonhosted.org/packages/7f/5b/20fd5c884d14550c911e4fb1b0dae00d4abb60a4f3876b449c4d3a9141d5/black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f", size = 1333655, upload-time = "2025-09-19T00:30:56.715Z" }, - { url = "https://files.pythonhosted.org/packages/fb/8e/319cfe6c82f7e2d5bfb4d3353c6cc85b523d677ff59edc61fdb9ee275234/black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0", size = 1742012, upload-time = "2025-09-19T00:33:08.678Z" }, - { url = "https://files.pythonhosted.org/packages/94/cc/f562fe5d0a40cd2a4e6ae3f685e4c36e365b1f7e494af99c26ff7f28117f/black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4", size = 1581421, upload-time = "2025-09-19T00:35:25.937Z" }, - { url = "https://files.pythonhosted.org/packages/84/67/6db6dff1ebc8965fd7661498aea0da5d7301074b85bba8606a28f47ede4d/black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e", size = 1655619, upload-time = "2025-09-19T00:30:49.241Z" }, - { url = "https://files.pythonhosted.org/packages/10/10/3faef9aa2a730306cf469d76f7f155a8cc1f66e74781298df0ba31f8b4c8/black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a", size = 1342481, upload-time = "2025-09-19T00:31:29.625Z" }, { url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" }, { url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" }, { url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" }, @@ -171,18 +163,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b", size = 3448846, upload-time = "2025-09-19T00:11:10.519Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f", size = 12731198, upload-time = "2025-09-19T00:09:44.857Z" }, - { url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341", size = 11817879, upload-time = "2025-09-19T00:09:47.131Z" }, - { url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d", size = 12427292, upload-time = "2025-09-19T00:10:22.472Z" }, - { url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86", size = 13163750, upload-time = "2025-09-19T00:09:51.472Z" }, - { url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37", size = 13351827, upload-time = "2025-09-19T00:09:58.311Z" }, - { url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8", size = 9757983, upload-time = "2025-09-19T00:10:09.071Z" }, - { url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34", size = 12908273, upload-time = "2025-09-19T00:10:58.321Z" }, - { url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764", size = 11920910, upload-time = "2025-09-19T00:10:20.043Z" }, - { url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893", size = 12465585, upload-time = "2025-09-19T00:10:33.005Z" }, - { url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914", size = 13348562, upload-time = "2025-09-19T00:10:11.51Z" }, - { url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8", size = 13533296, upload-time = "2025-09-19T00:10:06.568Z" }, - { url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074", size = 9828828, upload-time = "2025-09-19T00:10:28.203Z" }, { url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc", size = 12898728, upload-time = "2025-09-19T00:10:01.33Z" }, { url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e", size = 11910758, upload-time = "2025-09-19T00:10:42.607Z" }, { url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986", size = 12475342, upload-time = "2025-09-19T00:11:00.371Z" }, @@ -370,25 +350,6 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, - { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, - { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, - { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, - { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, - { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, - { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, - { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, - { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, From e1b78e9ebf88a6ec9795324bbc7992fedcabc87b Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:48:45 +0100 Subject: [PATCH 38/59] use ruff; less pre-commit hooks; less overriding things --- .github/workflows/ci-python.yml | 23 +--- .pre-commit-config.yaml | 35 ++---- pyproject.toml | 17 +++ python-objectstore-client/pyproject.toml | 27 +---- python-objectstore-client/setup.cfg | 2 - uv.lock | 134 ++++++----------------- 6 files changed, 63 insertions(+), 175 deletions(-) delete mode 100644 python-objectstore-client/setup.cfg diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 2b4deca9..33bf3438 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -19,26 +19,13 @@ jobs: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - with: - version: '0.9.3' - enable-cache: false # we just cache the venv-dir directly in action-setup-venv - - - uses: getsentry/action-setup-venv@0958463ee0e02b9e8aa8f8e031afae1f84b80881 # v3.0.0 - with: - cache-dependency-path: uv.lock - install-cmd: uv sync --all-packages --all-groups --frozen --active - - - name: Run black - run: black --check --diff python-objectstore-client - - - name: Run isort - run: isort --check-only --diff python-objectstore-client - - - name: Run flake8 - run: flake8 python-objectstore-client + - name: Run ruff check + run: ruff check + - name: Run ruff format + run: ruff format - name: Run mypy - run: mypy python-objectstore-client + run: mypy . test: strategy: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 80a5f8da..28600fc8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,41 +5,24 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - - id: check-case-conflict - - id: check-executables-have-shebangs - - id: check-merge-conflict - - id: check-symlinks - - id: end-of-file-fixer - id: trailing-whitespace - - id: check-added-large-files - args: ["--maxkb=1024"] - - id: check-yaml - args: ["--allow-multiple-documents"] - - id: check-toml - - id: detect-private-key + - id: end-of-file-fixer + - id: check-merge-conflict - repo: local hooks: - - id: black - name: black - entry: .venv/bin/black + - id: ruff-check + name: ruff check + entry: ruff check --fix language: system types_or: [python, pyi] - require_serial: true - - id: isort - name: isort - entry: .venv/bin/isort + - id: ruff-format + name: ruff format + entry: ruff format language: system - types: [python] - - id: flake8 - name: flake8 - entry: .venv/bin/flake8 - language: system - types: [python] - require_serial: true + types_or: [python, pyi] - id: mypy name: mypy entry: .venv/bin/mypy language: system types: [python] - require_serial: true diff --git a/pyproject.toml b/pyproject.toml index 484b3f8e..389fa692 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,9 @@ name = "objectstore" version = "0.1.0" requires-python = ">=3.13" +[tool.uv] +required-version = "==0.9.3" + [tool.uv.workspace] members = [ "python-objectstore-client", @@ -11,5 +14,19 @@ members = [ [dependency-groups] dev = [ "devservices>=1.2.2", + "mypy>=1.17.1", + "ruff>=0.14.2", "pre-commit>=4.2.0", ] + +[tool.ruff.lint] +select = ["E", "F", "I", "UP"] # pycodestyle, pyflakes, isort, pyupgrade + +[tool.mypy] +no_implicit_reexport = true +warn_unreachable = true +warn_unused_ignores = true +warn_redundant_casts = true +local_partial_types = true +disallow_any_generics = true +disallow_untyped_defs = true diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 54792703..9a48924b 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -7,35 +7,10 @@ requires-python = ">=3.13" dependencies = [] [build-system] -requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini +requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini and the main pyproject.toml build-backend = "uv_build" [dependency-groups] dev = [ "pytest>=8.3.3", - "black>=25.1.0", - "isort>=5.13.2", - "flake8>=7.3.0", - "mypy>=1.17.1", ] - -[tool.mypy] -check_untyped_defs = true -no_implicit_reexport = true -warn_unreachable = true -warn_unused_configs = true -warn_unused_ignores = true -warn_redundant_casts = true -enable_error_code = ["ignore-without-code", "redundant-self"] -local_partial_types = true -disallow_any_generics = true -disallow_untyped_defs = true - -[tool.black] -line-length = 200 -target-version = ['py313'] - -[tool.isort] -profile = "black" -line_length = 200 -lines_between_sections = 1 diff --git a/python-objectstore-client/setup.cfg b/python-objectstore-client/setup.cfg deleted file mode 100644 index a6578a30..00000000 --- a/python-objectstore-client/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -extend-ignore = E501 diff --git a/uv.lock b/uv.lock index f4c9adad..70794409 100644 --- a/uv.lock +++ b/uv.lock @@ -8,27 +8,6 @@ members = [ "objectstore-client", ] -[[package]] -name = "black" -version = "25.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "mypy-extensions" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "platformdirs" }, - { name = "pytokens" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" }, - { url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" }, - { url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" }, - { url = "https://files.pythonhosted.org/packages/21/17/5c253aa80a0639ccc427a5c7144534b661505ae2b5a10b77ebe13fa25334/black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", size = 1343428, upload-time = "2025-09-19T00:32:13.839Z" }, - { url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" }, -] - [[package]] name = "certifi" version = "2025.10.5" @@ -47,18 +26,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] -[[package]] -name = "click" -version = "8.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, -] - [[package]] name = "colorama" version = "0.4.6" @@ -102,20 +69,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, ] -[[package]] -name = "flake8" -version = "7.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mccabe" }, - { name = "pycodestyle" }, - { name = "pyflakes" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9b/af/fbfe3c4b5a657d79e5c47a2827a362f9e1b763336a52f926126aa6dc7123/flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872", size = 48326, upload-time = "2025-06-20T19:31:35.838Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", size = 57922, upload-time = "2025-06-20T19:31:34.425Z" }, -] - [[package]] name = "identify" version = "2.6.15" @@ -134,24 +87,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] -[[package]] -name = "isort" -version = "7.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, -] - -[[package]] -name = "mccabe" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, -] - [[package]] name = "mypy" version = "1.18.2" @@ -204,7 +139,9 @@ source = { virtual = "." } [package.dev-dependencies] dev = [ { name = "devservices" }, + { name = "mypy" }, { name = "pre-commit" }, + { name = "ruff" }, ] [package.metadata] @@ -212,7 +149,9 @@ dev = [ [package.metadata.requires-dev] dev = [ { name = "devservices", specifier = ">=1.2.2" }, + { name = "mypy", specifier = ">=1.17.1" }, { name = "pre-commit", specifier = ">=4.2.0" }, + { name = "ruff", specifier = ">=0.14.2" }, ] [[package]] @@ -222,23 +161,13 @@ source = { editable = "python-objectstore-client" } [package.dev-dependencies] dev = [ - { name = "black" }, - { name = "flake8" }, - { name = "isort" }, - { name = "mypy" }, { name = "pytest" }, ] [package.metadata] [package.metadata.requires-dev] -dev = [ - { name = "black", specifier = ">=25.1.0" }, - { name = "flake8", specifier = ">=7.3.0" }, - { name = "isort", specifier = ">=5.13.2" }, - { name = "mypy", specifier = ">=1.17.1" }, - { name = "pytest", specifier = ">=8.3.3" }, -] +dev = [{ name = "pytest", specifier = ">=8.3.3" }] [[package]] name = "packaging" @@ -292,24 +221,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, ] -[[package]] -name = "pycodestyle" -version = "2.14.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, -] - -[[package]] -name = "pyflakes" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/45/dc/fd034dc20b4b264b3d015808458391acbf9df40b1e54750ef175d39180b1/pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", size = 64669, upload-time = "2025-06-20T18:45:27.834Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload-time = "2025-06-20T18:45:26.937Z" }, -] - [[package]] name = "pygments" version = "2.19.2" @@ -335,15 +246,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] -[[package]] -name = "pytokens" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/c2/dbadcdddb412a267585459142bfd7cc241e6276db69339353ae6e241ab2b/pytokens-0.2.0.tar.gz", hash = "sha256:532d6421364e5869ea57a9523bf385f02586d4662acbcc0342afd69511b4dd43", size = 15368, upload-time = "2025-10-15T08:02:42.738Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/5a/c269ea6b348b6f2c32686635df89f32dbe05df1088dd4579302a6f8f99af/pytokens-0.2.0-py3-none-any.whl", hash = "sha256:74d4b318c67f4295c13782ddd9abcb7e297ec5630ad060eb90abf7ebbefe59f8", size = 12038, upload-time = "2025-10-15T08:02:41.694Z" }, -] - [[package]] name = "pyyaml" version = "6.0.3" @@ -380,6 +282,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] +[[package]] +name = "ruff" +version = "0.14.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/34/8218a19b2055b80601e8fd201ec723c74c7fe1ca06d525a43ed07b6d8e85/ruff-0.14.2.tar.gz", hash = "sha256:98da787668f239313d9c902ca7c523fe11b8ec3f39345553a51b25abc4629c96", size = 5539663, upload-time = "2025-10-23T19:37:00.956Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/dd/23eb2db5ad9acae7c845700493b72d3ae214dce0b226f27df89216110f2b/ruff-0.14.2-py3-none-linux_armv6l.whl", hash = "sha256:7cbe4e593505bdec5884c2d0a4d791a90301bc23e49a6b1eb642dd85ef9c64f1", size = 12533390, upload-time = "2025-10-23T19:36:18.044Z" }, + { url = "https://files.pythonhosted.org/packages/5a/8c/5f9acff43ddcf3f85130d0146d0477e28ccecc495f9f684f8f7119b74c0d/ruff-0.14.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8d54b561729cee92f8d89c316ad7a3f9705533f5903b042399b6ae0ddfc62e11", size = 12887187, upload-time = "2025-10-23T19:36:22.664Z" }, + { url = "https://files.pythonhosted.org/packages/99/fa/047646491479074029665022e9f3dc6f0515797f40a4b6014ea8474c539d/ruff-0.14.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5c8753dfa44ebb2cde10ce5b4d2ef55a41fb9d9b16732a2c5df64620dbda44a3", size = 11925177, upload-time = "2025-10-23T19:36:24.778Z" }, + { url = "https://files.pythonhosted.org/packages/15/8b/c44cf7fe6e59ab24a9d939493a11030b503bdc2a16622cede8b7b1df0114/ruff-0.14.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d0bbeffb8d9f4fccf7b5198d566d0bad99a9cb622f1fc3467af96cb8773c9e3", size = 12358285, upload-time = "2025-10-23T19:36:26.979Z" }, + { url = "https://files.pythonhosted.org/packages/45/01/47701b26254267ef40369aea3acb62a7b23e921c27372d127e0f3af48092/ruff-0.14.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7047f0c5a713a401e43a88d36843d9c83a19c584e63d664474675620aaa634a8", size = 12303832, upload-time = "2025-10-23T19:36:29.192Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5c/ae7244ca4fbdf2bee9d6405dcd5bc6ae51ee1df66eb7a9884b77b8af856d/ruff-0.14.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bf8d2f9aa1602599217d82e8e0af7fd33e5878c4d98f37906b7c93f46f9a839", size = 13036995, upload-time = "2025-10-23T19:36:31.861Z" }, + { url = "https://files.pythonhosted.org/packages/27/4c/0860a79ce6fd4c709ac01173f76f929d53f59748d0dcdd662519835dae43/ruff-0.14.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1c505b389e19c57a317cf4b42db824e2fca96ffb3d86766c1c9f8b96d32048a7", size = 14512649, upload-time = "2025-10-23T19:36:33.915Z" }, + { url = "https://files.pythonhosted.org/packages/7f/7f/d365de998069720a3abfc250ddd876fc4b81a403a766c74ff9bde15b5378/ruff-0.14.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a307fc45ebd887b3f26b36d9326bb70bf69b01561950cdcc6c0bdf7bb8e0f7cc", size = 14088182, upload-time = "2025-10-23T19:36:36.983Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ea/d8e3e6b209162000a7be1faa41b0a0c16a133010311edc3329753cc6596a/ruff-0.14.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61ae91a32c853172f832c2f40bd05fd69f491db7289fb85a9b941ebdd549781a", size = 13599516, upload-time = "2025-10-23T19:36:39.208Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ea/c7810322086db68989fb20a8d5221dd3b79e49e396b01badca07b433ab45/ruff-0.14.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1967e40286f63ee23c615e8e7e98098dedc7301568bd88991f6e544d8ae096", size = 13272690, upload-time = "2025-10-23T19:36:41.453Z" }, + { url = "https://files.pythonhosted.org/packages/a9/39/10b05acf8c45786ef501d454e00937e1b97964f846bf28883d1f9619928a/ruff-0.14.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2877f02119cdebf52a632d743a2e302dea422bfae152ebe2f193d3285a3a65df", size = 13496497, upload-time = "2025-10-23T19:36:43.61Z" }, + { url = "https://files.pythonhosted.org/packages/59/a1/1f25f8301e13751c30895092485fada29076e5e14264bdacc37202e85d24/ruff-0.14.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e681c5bc777de5af898decdcb6ba3321d0d466f4cb43c3e7cc2c3b4e7b843a05", size = 12266116, upload-time = "2025-10-23T19:36:45.625Z" }, + { url = "https://files.pythonhosted.org/packages/5c/fa/0029bfc9ce16ae78164e6923ef392e5f173b793b26cc39aa1d8b366cf9dc/ruff-0.14.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e21be42d72e224736f0c992cdb9959a2fa53c7e943b97ef5d081e13170e3ffc5", size = 12281345, upload-time = "2025-10-23T19:36:47.618Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ab/ece7baa3c0f29b7683be868c024f0838770c16607bea6852e46b202f1ff6/ruff-0.14.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b8264016f6f209fac16262882dbebf3f8be1629777cf0f37e7aff071b3e9b92e", size = 12629296, upload-time = "2025-10-23T19:36:49.789Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7f/638f54b43f3d4e48c6a68062794e5b367ddac778051806b9e235dfb7aa81/ruff-0.14.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5ca36b4cb4db3067a3b24444463ceea5565ea78b95fe9a07ca7cb7fd16948770", size = 13371610, upload-time = "2025-10-23T19:36:51.882Z" }, + { url = "https://files.pythonhosted.org/packages/8d/35/3654a973ebe5b32e1fd4a08ed2d46755af7267da7ac710d97420d7b8657d/ruff-0.14.2-py3-none-win32.whl", hash = "sha256:41775927d287685e08f48d8eb3f765625ab0b7042cc9377e20e64f4eb0056ee9", size = 12415318, upload-time = "2025-10-23T19:36:53.961Z" }, + { url = "https://files.pythonhosted.org/packages/71/30/3758bcf9e0b6a4193a6f51abf84254aba00887dfa8c20aba18aa366c5f57/ruff-0.14.2-py3-none-win_amd64.whl", hash = "sha256:0df3424aa5c3c08b34ed8ce099df1021e3adaca6e90229273496b839e5a7e1af", size = 13565279, upload-time = "2025-10-23T19:36:56.578Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5d/aa883766f8ef9ffbe6aa24f7192fb71632f31a30e77eb39aa2b0dc4290ac/ruff-0.14.2-py3-none-win_arm64.whl", hash = "sha256:ea9d635e83ba21569fbacda7e78afbfeb94911c9434aff06192d9bc23fd5495a", size = 12554956, upload-time = "2025-10-23T19:36:58.714Z" }, +] + [[package]] name = "sentry-devenv" version = "1.23.0" From 0bbe63b8e46b30ae4092d4318c98fb524a8e857f Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:51:54 +0100 Subject: [PATCH 39/59] use uv run for CI --- .github/workflows/ci-python.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 33bf3438..b32fc885 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -20,12 +20,14 @@ jobs: - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - - name: Run ruff check - run: ruff check - - name: Run ruff format - run: ruff format + - name: Format + run: uv run ruff format + + - name: Lint + run: uv run ruff check + - name: Run mypy - run: mypy . + run: uv run mypy . test: strategy: From b592a3492601a3b039c29820a658858f7d11d7ba Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:52:46 +0100 Subject: [PATCH 40/59] test only on ubuntu-latest --- .github/workflows/ci-python.yml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index b32fc885..d3eba221 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -30,26 +30,13 @@ jobs: run: uv run mypy . test: - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest] - - name: Test (${{ matrix.os }}) - runs-on: ${{ matrix.os }} + name: Test + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - with: - version: '0.9.3' - enable-cache: false # we just cache the venv-dir directly in action-setup-venv - - - uses: getsentry/action-setup-venv@0958463ee0e02b9e8aa8f8e031afae1f84b80881 # v3.0.0 - with: - cache-dependency-path: uv.lock - install-cmd: uv sync --all-packages --all-groups --frozen --active - name: Run tests - run: pytest python-objectstore-client + run: uv run pytest python-objectstore-client From 10d6c9293b6eef70ed713409c4ccae07c9313c19 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:57:07 +0100 Subject: [PATCH 41/59] specify workflow permissions; remove concurrency --- .github/workflows/ci-python.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index d3eba221..ad7d8a86 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -1,15 +1,14 @@ name: CI / Python +permissions: + contents: read + on: push: branches: - main pull_request: -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - jobs: lint: name: Lint From 114e0d444c84ccbfdebb023c7d26a3d4bc08ae4f Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:58:29 +0100 Subject: [PATCH 42/59] format py file in devenv dir --- devenv/sync.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devenv/sync.py b/devenv/sync.py index 8492c51f..054d4dd9 100644 --- a/devenv/sync.py +++ b/devenv/sync.py @@ -1,6 +1,7 @@ -from devenv import constants from devenv.lib import config, uv +from devenv import constants + def main(context: dict[str, str]) -> int: reporoot = context["reporoot"] From 96c25d576e2247c47080e812361b7b1cc13ab17f Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:01:16 +0100 Subject: [PATCH 43/59] move pytest to top level; run uv sync in CI --- .github/workflows/ci-python.yml | 6 ++++++ pyproject.toml | 1 + python-objectstore-client/pyproject.toml | 5 ----- uv.lock | 12 ++---------- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index ad7d8a86..cf866a13 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -19,6 +19,9 @@ jobs: - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + - name: Install dependencies + - run: uv sync --all-packages --all-groups + - name: Format run: uv run ruff format @@ -37,5 +40,8 @@ jobs: - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + - name: Install dependencies + - run: uv sync --all-packages --all-groups + - name: Run tests run: uv run pytest python-objectstore-client diff --git a/pyproject.toml b/pyproject.toml index 389fa692..24292e51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ members = [ [dependency-groups] dev = [ "devservices>=1.2.2", + "pytest>=8.3.3", "mypy>=1.17.1", "ruff>=0.14.2", "pre-commit>=4.2.0", diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 9a48924b..345942d5 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -9,8 +9,3 @@ dependencies = [] [build-system] requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini and the main pyproject.toml build-backend = "uv_build" - -[dependency-groups] -dev = [ - "pytest>=8.3.3", -] diff --git a/uv.lock b/uv.lock index 70794409..d20bafab 100644 --- a/uv.lock +++ b/uv.lock @@ -141,6 +141,7 @@ dev = [ { name = "devservices" }, { name = "mypy" }, { name = "pre-commit" }, + { name = "pytest" }, { name = "ruff" }, ] @@ -151,6 +152,7 @@ dev = [ { name = "devservices", specifier = ">=1.2.2" }, { name = "mypy", specifier = ">=1.17.1" }, { name = "pre-commit", specifier = ">=4.2.0" }, + { name = "pytest", specifier = ">=8.3.3" }, { name = "ruff", specifier = ">=0.14.2" }, ] @@ -159,16 +161,6 @@ name = "objectstore-client" version = "0.1.0" source = { editable = "python-objectstore-client" } -[package.dev-dependencies] -dev = [ - { name = "pytest" }, -] - -[package.metadata] - -[package.metadata.requires-dev] -dev = [{ name = "pytest", specifier = ">=8.3.3" }] - [[package]] name = "packaging" version = "25.0" From 664e2119c4374663f2723882e9c9a530c9741d65 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:02:34 +0100 Subject: [PATCH 44/59] try removing uv run prefix from CI commands --- .github/workflows/ci-python.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index cf866a13..1acaefd8 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -23,13 +23,13 @@ jobs: - run: uv sync --all-packages --all-groups - name: Format - run: uv run ruff format + run: ruff format - name: Lint - run: uv run ruff check + run: ruff check - name: Run mypy - run: uv run mypy . + run: mypy . test: name: Test From 76c8943fcd7dbf129d4cbb3c9d25f282da798736 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:11:07 +0100 Subject: [PATCH 45/59] delete gitignore --- python-objectstore-client/.gitignore | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 python-objectstore-client/.gitignore diff --git a/python-objectstore-client/.gitignore b/python-objectstore-client/.gitignore deleted file mode 100644 index 505a3b1c..00000000 --- a/python-objectstore-client/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Python-generated files -__pycache__/ -*.py[oc] -build/ -dist/ -wheels/ -*.egg-info - -# Virtual environments -.venv From 395963c1ca8fb8584254b7fa61c0dc5110ccc201 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:13:09 +0100 Subject: [PATCH 46/59] ignore just dist --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7fb7b91a..445d69b1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ profile.json.gz .*.sw* **/__pycache__ +/dist From 0bb4a6f4666e3fd75e5e85ea3d5d575b9055bdf2 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:15:50 +0100 Subject: [PATCH 47/59] unify CI --- .github/workflows/ci-python.yml | 47 --------------------------------- .github/workflows/ci.yml | 36 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 47 deletions(-) delete mode 100644 .github/workflows/ci-python.yml diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml deleted file mode 100644 index 1acaefd8..00000000 --- a/.github/workflows/ci-python.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: CI / Python - -permissions: - contents: read - -on: - push: - branches: - - main - pull_request: - -jobs: - lint: - name: Lint - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - - - name: Install dependencies - - run: uv sync --all-packages --all-groups - - - name: Format - run: ruff format - - - name: Lint - run: ruff check - - - name: Run mypy - run: mypy . - - test: - name: Test - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - - - name: Install dependencies - - run: uv sync --all-packages --all-groups - - - name: Run tests - run: uv run pytest python-objectstore-client diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8005355..8102fd33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,27 @@ jobs: env: RUSTDOCFLAGS: -Dwarnings + lint-python: + name: Lint Python + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + + - name: Install dependencies + - run: uv sync --all-packages --all-groups + + - name: Format + run: ruff format + + - name: Lint + run: ruff check + + - name: Run mypy + run: mypy . + test_all: name: Test (all features) runs-on: ubuntu-latest @@ -89,6 +110,21 @@ jobs: - name: Run Tests run: cargo test --workspace --all-features + test-python: + name: Test Python + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 + + - name: Install dependencies + - run: uv sync --all-packages --all-groups + + - name: Run tests + run: uv run pytest python-objectstore-client + docs: name: Cargo Docs runs-on: ubuntu-latest From 2e19ec3a277205a5061c4046427aa2cdc88dd656 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:19:36 +0100 Subject: [PATCH 48/59] fix workflow file --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8102fd33..98567bb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - name: Install dependencies - - run: uv sync --all-packages --all-groups + run: uv sync --all-packages --all-groups - name: Format run: ruff format @@ -120,7 +120,7 @@ jobs: - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 - name: Install dependencies - - run: uv sync --all-packages --all-groups + run: uv sync --all-packages --all-groups - name: Run tests run: uv run pytest python-objectstore-client From 088fd482dce7f3c04e0c8a76a5a064b87531955a Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:19:59 +0100 Subject: [PATCH 49/59] improve --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98567bb6..8c8235ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: run: uv sync --all-packages --all-groups - name: Run tests - run: uv run pytest python-objectstore-client + run: pytest python-objectstore-client docs: name: Cargo Docs From 7d1d9792dc3c8da1b943a3f83e6825d9d2ae3040 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:21:55 +0100 Subject: [PATCH 50/59] improve --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c8235ac..fc16a50b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,13 +60,13 @@ jobs: run: uv sync --all-packages --all-groups - name: Format - run: ruff format + run: uv run ruff format - name: Lint - run: ruff check + run: uv run ruff check - name: Run mypy - run: mypy . + run: uv run mypy . test_all: name: Test (all features) @@ -123,7 +123,7 @@ jobs: run: uv sync --all-packages --all-groups - name: Run tests - run: pytest python-objectstore-client + run: uv run pytest python-objectstore-client docs: name: Cargo Docs From 6f6a046351a104437ff6d14c9da6d0ad07f3dacd Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:22:59 +0100 Subject: [PATCH 51/59] improve --- python-objectstore-client/tests/test_smoke.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-objectstore-client/tests/test_smoke.py b/python-objectstore-client/tests/test_smoke.py index 973231a0..07122242 100644 --- a/python-objectstore-client/tests/test_smoke.py +++ b/python-objectstore-client/tests/test_smoke.py @@ -1,4 +1,4 @@ -def test_imports(): +def test_imports() -> None: import objectstore_client _ = objectstore_client From 5389be3820bf1f5078b14fe2d8ce5843700319d9 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:35:15 +0100 Subject: [PATCH 52/59] change mypy rules slightly --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 24292e51..21bbe6bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,8 @@ select = ["E", "F", "I", "UP"] # pycodestyle, pyflakes, isort, pyupgrade [tool.mypy] no_implicit_reexport = true warn_unreachable = true -warn_unused_ignores = true warn_redundant_casts = true local_partial_types = true disallow_any_generics = true disallow_untyped_defs = true +warn_unused_configs = true From 10fb7cd448ea3374a91053216cc71de78488ba58 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:36:32 +0100 Subject: [PATCH 53/59] pin minor python version --- .python-version | 2 +- pyproject.toml | 2 +- python-objectstore-client/pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.python-version b/.python-version index 24ee5b1b..c10780c6 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.13 +3.13.1 diff --git a/pyproject.toml b/pyproject.toml index 21bbe6bf..36b41240 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "objectstore" version = "0.1.0" -requires-python = ">=3.13" +requires-python = ">=3.13.1" [tool.uv] required-version = "==0.9.3" diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index 345942d5..dff408c0 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -3,7 +3,7 @@ name = "objectstore-client" version = "0.1.0" description = "Python client for the Sentry Objectstore service" readme = "README.md" -requires-python = ">=3.13" +requires-python = ">=3.13.1" dependencies = [] [build-system] diff --git a/uv.lock b/uv.lock index d20bafab..efdd1dc1 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.13" +requires-python = ">=3.13.1" [manifest] members = [ From 28f41b422782e7031452d34dc0ef3a7ffff6c8f4 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:40:51 +0100 Subject: [PATCH 54/59] simplify build requirement --- python-objectstore-client/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-objectstore-client/pyproject.toml b/python-objectstore-client/pyproject.toml index dff408c0..8c798e0a 100644 --- a/python-objectstore-client/pyproject.toml +++ b/python-objectstore-client/pyproject.toml @@ -7,5 +7,5 @@ requires-python = ">=3.13.1" dependencies = [] [build-system] -requires = ["uv_build==0.9.3"] # must match the version specified in devenv/config.ini and the main pyproject.toml +requires = ["uv_build"] build-backend = "uv_build" From 93ada0e3fe8e3f30ceefa5783353a4eac1ed345d Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:42:16 +0100 Subject: [PATCH 55/59] improve --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 36b41240..bf8b8363 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ version = "0.1.0" requires-python = ">=3.13.1" [tool.uv] -required-version = "==0.9.3" +required-version = "==0.9.3" # keep in sync with devenv/config.ini [tool.uv.workspace] members = [ From 1687ac210dc9ef4ffa2da70fdeb0675cd639b49a Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:56:10 +0100 Subject: [PATCH 56/59] remove metrics.timing in favor of distribution --- .../src/objectstore_client/metrics.py | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/python-objectstore-client/src/objectstore_client/metrics.py b/python-objectstore-client/src/objectstore_client/metrics.py index 6e26d395..801875ca 100644 --- a/python-objectstore-client/src/objectstore_client/metrics.py +++ b/python-objectstore-client/src/objectstore_client/metrics.py @@ -2,9 +2,9 @@ import time from abc import abstractmethod -from collections.abc import Generator +from collections.abc import Generator, Mapping from contextlib import contextmanager -from typing import Mapping, Protocol, Union, runtime_checkable +from typing import Protocol, runtime_checkable Tags = Mapping[str, str] @@ -19,7 +19,7 @@ class MetricsBackend(Protocol): def increment( self, name: str, - value: Union[int, float] = 1, + value: int | float = 1, tags: Tags | None = None, ) -> None: """ @@ -28,24 +28,17 @@ def increment( raise NotImplementedError @abstractmethod - def gauge(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: + def gauge(self, name: str, value: int | float, tags: Tags | None = None) -> None: """ Sets a gauge metric to the given value. """ raise NotImplementedError - @abstractmethod - def timing(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: - """ - Records a timing metric. - """ - raise NotImplementedError - @abstractmethod def distribution( self, name: str, - value: Union[int, float], + value: int | float, tags: Tags | None = None, unit: str | None = None, ) -> None: @@ -63,21 +56,18 @@ class NoOpMetricsBackend(MetricsBackend): def increment( self, name: str, - value: Union[int, float] = 1, + value: int | float = 1, tags: Tags | None = None, ) -> None: pass - def gauge(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: - pass - - def timing(self, name: str, value: Union[int, float], tags: Tags | None = None) -> None: + def gauge(self, name: str, value: int | float, tags: Tags | None = None) -> None: pass def distribution( self, name: str, - value: Union[int, float], + value: int | float, tags: Tags | None = None, unit: str | None = None, ) -> None: @@ -99,17 +89,23 @@ def __init__(self, backend: MetricsBackend, operation: str, usecase: str): def record_latency(self, elapsed: float) -> None: tags = {"usecase": self.usecase} - self.backend.timing(f"storage.{self.operation}.latency", elapsed, tags=tags) + self.backend.distribution( + f"storage.{self.operation}.latency", elapsed, tags=tags + ) self.elapsed = elapsed def record_uncompressed_size(self, value: int) -> None: tags = {"usecase": self.usecase, "compression": "none"} - self.backend.distribution(f"storage.{self.operation}.size", value, tags=tags, unit="byte") + self.backend.distribution( + f"storage.{self.operation}.size", value, tags=tags, unit="byte" + ) self.uncompressed_size = value def record_compressed_size(self, value: int, compression: str = "unknown") -> None: tags = {"usecase": self.usecase, "compression": compression} - self.backend.distribution(f"storage.{self.operation}.size", value, tags=tags, unit="byte") + self.backend.distribution( + f"storage.{self.operation}.size", value, tags=tags, unit="byte" + ) self.compressed_size = value self.compression = compression @@ -136,7 +132,9 @@ def maybe_record_throughputs(self) -> None: for size, compression in sizes: tags = {"usecase": self.usecase, "compression": compression} - self.backend.distribution(f"storage.{self.operation}.throughput", size / self.elapsed, tags=tags) + self.backend.distribution( + f"storage.{self.operation}.throughput", size / self.elapsed, tags=tags + ) self.backend.distribution( f"storage.{self.operation}.inverse_throughput", self.elapsed / size, From e861c4968e8393ad1ee6bf4040d89548dc988069 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:58:52 +0100 Subject: [PATCH 57/59] Update .pre-commit-config.yaml --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28600fc8..ecaf111b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: hooks: - id: ruff-check name: ruff check - entry: ruff check --fix + entry: ruff check language: system types_or: [python, pyi] - id: ruff-format From e9b23067589f18a88d28dbf1fa05c246217173c0 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Wed, 29 Oct 2025 18:04:06 +0100 Subject: [PATCH 58/59] remove vendored itertools thingy; satisfy linter --- .../src/objectstore_client/client.py | 16 +++++++----- .../src/objectstore_client/metadata.py | 26 ++----------------- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/python-objectstore-client/src/objectstore_client/client.py b/python-objectstore-client/src/objectstore_client/client.py index 718e42d4..a11f1ef0 100644 --- a/python-objectstore-client/src/objectstore_client/client.py +++ b/python-objectstore-client/src/objectstore_client/client.py @@ -41,7 +41,6 @@ def __init__( self, objectstore_base_url: str, usecase: str, - options: dict | None = None, metrics_backend: MetricsBackend | None = None, propagate_traces: bool = False, ): @@ -50,7 +49,6 @@ def __init__( self._default_compression: Compression = "zstd" self._propagate_traces = propagate_traces self._metrics_backend = metrics_backend or NoOpMetricsBackend() - _ = options def _make_client(self, scope: str) -> Client: pool = urllib3.connectionpool.connection_from_url(self._base_url) @@ -98,7 +96,7 @@ def _make_headers(self) -> dict[str, str]: return dict(sentry_sdk.get_current_scope().iter_trace_propagation_headers()) return {} - def _make_url(self, id: str | None, full=False) -> str: + def _make_url(self, id: str | None, full: bool = False) -> str: base_path = f"/v1/{id}" if id else "/v1/" qs = urlencode({"usecase": self._usecase, "scope": self._scope}) if full: @@ -143,7 +141,9 @@ def put( for k, v in metadata.items(): headers[f"{HEADER_META_PREFIX}{k}"] = v - with measure_storage_operation(self._metrics_backend, "put", self._usecase) as metric_emitter: + with measure_storage_operation( + self._metrics_backend, "put", self._usecase + ) as metric_emitter: response = self._pool.request( "PUT", self._make_url(id), @@ -187,7 +187,9 @@ def get(self, id: str, decompress: bool = True) -> GetResult: if metadata.compression and decompress: if metadata.compression != "zstd": - raise NotImplementedError("Transparent decoding of anything but `zstd` is not implemented yet") + raise NotImplementedError( + "Transparent decoding of anything but `zstd` is not implemented yet" + ) metadata.compression = None dctx = zstandard.ZstdDecompressor() @@ -205,7 +207,7 @@ def object_url(self, id: str) -> str: """ return self._make_url(id, full=True) - def delete(self, id: str): + def delete(self, id: str) -> None: """ Deletes the blob with the given `id`. """ @@ -227,7 +229,7 @@ def __init__(self, message: str, status: int, response: str): self.response = response -def raise_for_status(response: urllib3.BaseHTTPResponse): +def raise_for_status(response: urllib3.BaseHTTPResponse) -> None: if response.status >= 400: res = str(response.data or response.read()) raise ClientError( diff --git a/python-objectstore-client/src/objectstore_client/metadata.py b/python-objectstore-client/src/objectstore_client/metadata.py index 10f4e26d..f7488959 100644 --- a/python-objectstore-client/src/objectstore_client/metadata.py +++ b/python-objectstore-client/src/objectstore_client/metadata.py @@ -5,7 +5,7 @@ from collections.abc import Mapping from dataclasses import dataclass from datetime import timedelta -from typing import Iterable, Iterator, Literal, TypeVar, cast +from typing import Literal, cast Compression = Literal["zstd"] @@ -74,28 +74,6 @@ def format_timedelta(delta: timedelta) -> str: return output -T = TypeVar("T") - - -def itertools_batched(iterable: Iterable[T], n: int, strict: bool = False) -> Iterator[tuple[T, ...]]: - """ - Vendored version of `itertools.batched`, not available in Python 3.11. - - Batch data from the iterable into tuples of length n. The last batch may be shorter than n. - - If strict is true, will raise a ValueError if the final batch is shorter than n. - - Loops over the input iterable and accumulates data into tuples up to size n. The input is consumed lazily, just enough to fill a batch. The result is yielded as soon as the batch is full or when the input iterable is exhausted: - """ - if n < 1: - raise ValueError("n must be at least one") - iterator = iter(iterable) - while batch := tuple(itertools.islice(iterator, n)): - if strict and len(batch) < n: - raise ValueError("final batch is shorter than n") - yield batch - - TIME_SPLIT = re.compile(r"[^\W\d_]+|\d+") @@ -103,7 +81,7 @@ def parse_timedelta(delta: str) -> timedelta: words = TIME_SPLIT.findall(delta) seconds = 0 - for num, unit in itertools_batched(words, n=2, strict=True): + for num, unit in itertools.batched(words, n=2, strict=True): num = int(num) multiplier = 0 From bb300b6fce344bdc26439c010bcff299b77b3871 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Thu, 30 Oct 2025 10:50:39 +0100 Subject: [PATCH 59/59] remove setup.cfg --- setup.cfg | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index c0cafb89..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -extend-ignore = E501,E203