From 563798a7c93badc4cc78caf36c2f83608e3c4812 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Mon, 23 Feb 2026 19:35:19 +0100 Subject: [PATCH 01/29] fix: interface socket's hard_min/max are irrelevant --- packages/tree_clipper/src/tree_clipper/export_nodes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/tree_clipper/src/tree_clipper/export_nodes.py b/packages/tree_clipper/src/tree_clipper/export_nodes.py index 80b444c..a28d8c8 100644 --- a/packages/tree_clipper/src/tree_clipper/export_nodes.py +++ b/packages/tree_clipper/src/tree_clipper/export_nodes.py @@ -223,6 +223,9 @@ def _export_property_simple( # https://github.com/Algebraic-UG/tree_clipper/issues/96 def clamp_and_report(value: int | float) -> int | float: + # https://github.com/Algebraic-UG/tree_clipper/issues/162 + if isinstance(obj, bpy.types.NodeTreeInterfaceSocket): + return value # https://github.com/Algebraic-UG/tree_clipper/issues/132 if ( isinstance(obj, bpy.types.NodeSocket) From 96f17b573bdc8eb470b9e8590517ff4f394debad Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Mon, 23 Feb 2026 19:39:54 +0100 Subject: [PATCH 02/29] chore: delete .python-version and put into ignore --- .gitignore | 2 +- .python-version | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 .python-version diff --git a/.gitignore b/.gitignore index eb02619..7b54387 100644 --- a/.gitignore +++ b/.gitignore @@ -85,7 +85,7 @@ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: -# .python-version +.python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. diff --git a/.python-version b/.python-version deleted file mode 100644 index 2c07333..0000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.11 From f7e00f9af188091051d32e7a74519e1261aebc02 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Mon, 23 Feb 2026 21:04:22 +0100 Subject: [PATCH 03/29] chore: change deps to test Blender 5.1 --- packages/tree_clipper/pyproject.toml | 3 +- .../tree_clipper_addon/blender_manifest.toml | 2 +- pyproject.toml | 31 +- uv.lock | 291 +++++------------- 4 files changed, 107 insertions(+), 220 deletions(-) diff --git a/packages/tree_clipper/pyproject.toml b/packages/tree_clipper/pyproject.toml index 30925da..28f087d 100644 --- a/packages/tree_clipper/pyproject.toml +++ b/packages/tree_clipper/pyproject.toml @@ -1,7 +1,6 @@ [project] name = "tree-clipper" version = "0.1.5" -requires-python = ">=3.11" dependencies = [] maintainers = [ { name="Algebraic", email="tree.clipper@algebraic.games" }, @@ -26,7 +25,7 @@ Homepage = "https://github.com/Algebraic-UG/tree_clipper" Issues = "https://github.com/Algebraic-UG/tree_clipper/issues" [project.optional-dependencies] -bpy = [ "bpy >= 5.0.0, < 5.1" ] +bpy = [ "bpy >= 5" ] [build-system] requires = ["uv_build >= 0.9.18, < 0.10.0"] diff --git a/packages/tree_clipper_addon/src/tree_clipper_addon/blender_manifest.toml b/packages/tree_clipper_addon/src/tree_clipper_addon/blender_manifest.toml index ce3c580..87e291f 100644 --- a/packages/tree_clipper_addon/src/tree_clipper_addon/blender_manifest.toml +++ b/packages/tree_clipper_addon/src/tree_clipper_addon/blender_manifest.toml @@ -21,7 +21,7 @@ tags = ["Import-Export", "Node"] blender_version_min = "5.0.0" # # Optional: Blender version that the extension does not support, earlier versions are supported. # # This can be omitted and defined later on the extensions platform if an issue is found. -blender_version_max = "5.1.0" +blender_version_max = "5.2.0" # License conforming to https://spdx.org/licenses/ (use "SPDX: prefix) # https://docs.blender.org/manual/en/dev/advanced/extensions/licenses.html diff --git a/pyproject.toml b/pyproject.toml index 33d2044..d44e4c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,26 @@ [project] name = "tree-clipper-workspace" version = "0.0.0" # not used -requires-python = ">=3.11" -dependencies = [ - "bpy >= 5.0.0, < 5.1", - "tree-clipper", -] + +# XXX: +# This is inconvenient, there's probably a better way. +# To test and build with a certain Blender version, comment in the respective lines below +# and run this command to rebuild the .venv +# +# uv sync --python 3.13 --prerelease=allow --index-strategy unsafe-best-match +# +# where the python version matches the one used by the respective Blender version. +# The index-strategy option is so that either the official index or the one from the dailybpy can be used. + +#requires-python = "== 3.11.*" +#dependencies = [ "bpy==5.0.*", "tree-clipper"] + +requires-python = "== 3.13.*" +dependencies = [ "bpy==5.1.*", "tree-clipper"] + +#requires-python = "== 3.13.*" +#dependencies = [ "bpy==5.2.*", "tree-clipper"] + [tool.uv.workspace] members = [ @@ -36,9 +51,9 @@ norecursedirs = [".git", "build", "__pycache__", "_vendor"] target = "packages/tree_clipper_addon/src/tree_clipper_addon/_vendor" packages = ["packages/tree_clipper"] -#[[tool.uv.index]] -#name = "bpy" -#url = "https://bradyajohnston.github.io/dailybpy/" +[[tool.uv.index]] +name = "bpy" +url = "https://bradyajohnston.github.io/dailybpy/" [[tool.uv.index]] name = "testpypi" diff --git a/uv.lock b/uv.lock index 9202cd1..6cc8dfe 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,9 @@ version = 1 revision = 3 -requires-python = ">=3.11" +requires-python = "==3.13.*" + +[options] +prerelease-mode = "allow" [manifest] members = [ @@ -12,8 +15,8 @@ members = [ [[package]] name = "bpy" -version = "5.0.0" -source = { registry = "https://pypi.org/simple" } +version = "5.1.0b0" +source = { registry = "https://bradyajohnston.github.io/dailybpy/" } dependencies = [ { name = "cython" }, { name = "numpy" }, @@ -21,19 +24,18 @@ dependencies = [ { name = "zstandard" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/88/6c/87bd36315453b9a82f6392c31ed3c6eb504dfda4b591a0ca9b3a29715d07/bpy-5.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4a64f8862b29cc21358666d3b790fdf22060fe57e4626b3a8e1a879a8fecf961", size = 228454431, upload-time = "2025-11-18T17:09:51.446Z" }, - { url = "https://files.pythonhosted.org/packages/72/92/8b830f3f0cf8e548b2ac385c4a255aabb6b9e7dadde8149d7790ca296ab4/bpy-5.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:57804ccf770052a47e02f161d8a4401d93a2b1c120ff3ce9f8617466e55691f9", size = 382627218, upload-time = "2025-11-18T17:09:23.339Z" }, - { url = "https://files.pythonhosted.org/packages/ae/01/bd9dc9806d5320a2caa4ad4f43ffdeebf70f8c398686d50d498a17de92b5/bpy-5.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:7b8b14b21006a487db88ff817eeb2d635073c24a8fb191b25c71b401641e1eaa", size = 340851458, upload-time = "2025-11-18T17:08:27.098Z" }, - { url = "https://files.pythonhosted.org/packages/56/15/fe803465ecd93da65bb6900f7feb7e93a767d7b84a865a4b0882a0c27155/bpy-5.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:19d0922b5e1b62852fd826cf85e78a86324d3360cf1bda0bb5fb41c82005cb7c", size = 201997189, upload-time = "2025-11-18T17:08:45.541Z" }, + { url = "https://github.com/BradyAJohnston/dailybpy/releases/download/daily-2026-02-23/bpy-5.1.0b0-cp313-cp313-macosx_11_0_arm64.whl" }, + { url = "https://github.com/BradyAJohnston/dailybpy/releases/download/daily-2026-02-23/bpy-5.1.0b0-cp313-cp313-manylinux_2_39_x86_64.whl" }, + { url = "https://github.com/BradyAJohnston/dailybpy/releases/download/daily-2026-02-23/bpy-5.1.0b0-cp313-cp313-win_amd64.whl" }, ] [[package]] name = "certifi" -version = "2025.11.12" +version = "2026.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, ] [[package]] @@ -42,38 +44,6 @@ version = "3.4.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, - { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, - { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, - { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, - { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, - { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, - { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, - { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, - { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, - { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, - { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, - { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, - { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, - { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, - { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, - { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, - { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, - { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, - { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, - { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, - { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, - { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, - { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, - { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, - { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, - { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, - { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, - { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, - { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, - { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, @@ -90,22 +60,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, - { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, - { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, - { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, - { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, - { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, - { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, - { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, - { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, - { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, - { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, - { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, - { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, - { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] @@ -120,36 +74,24 @@ wheels = [ [[package]] name = "cython" -version = "3.2.1" +version = "3.2.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/36/cce2972e13e83ffe58bc73bfd9d37340b5e5113e8243841a57511c7ae1c2/cython-3.2.1.tar.gz", hash = "sha256:2be1e4d0cbdf7f4cd4d9b8284a034e1989b59fd060f6bd4d24bf3729394d2ed8", size = 3270455, upload-time = "2025-11-12T19:02:59.847Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/85/7574c9cd44b69a27210444b6650f6477f56c75fee1b70d7672d3e4166167/cython-3.2.4.tar.gz", hash = "sha256:84226ecd313b233da27dc2eb3601b4f222b8209c3a7216d8733b031da1dc64e6", size = 3280291, upload-time = "2026-01-04T14:14:14.473Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/d4/ba7b9f341ec168de78bd659600e04bb7de3b2d069bf98b2178a135e88ea4/cython-3.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cb32c650e7f4476941d1f735cae75a2067d5e3279576273bb8802e8ea907222", size = 2949720, upload-time = "2025-11-12T19:03:17.492Z" }, - { url = "https://files.pythonhosted.org/packages/ad/47/c42417f424c0b928361f48d7dd0ae72716ee21f647b73ceb16f66b98663e/cython-3.2.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a2b306813d7f28aa0a2c3e4e63ada1427a8109917532df942cd5429db228252", size = 3242127, upload-time = "2025-11-12T19:03:19.227Z" }, - { url = "https://files.pythonhosted.org/packages/e6/fc/1040460889129551649ec35be45e05169871fbcf71bd8e13c533e86f9468/cython-3.2.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0959d9a36d4f004ce63acc1474b3c606745af98b65e8ae709efd0c10988e9d6b", size = 3377094, upload-time = "2025-11-12T19:03:21.25Z" }, - { url = "https://files.pythonhosted.org/packages/f8/f2/8c754298eefa40e21af0ae3592837c6e71254900d5aea1c8859e96b11de5/cython-3.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:60c62e734421365135cc2842013d883136054a26c617c001be494235edfc447a", size = 2767824, upload-time = "2025-11-12T19:03:23.317Z" }, - { url = "https://files.pythonhosted.org/packages/ee/0e/19d5041b87f98ed19c94c388607cd27c1f7458078c3bad5de2dead55b2e1/cython-3.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ea5097d97afd2ab14e98637b7033eba5146de29a5dedf89f5e946076396ab891", size = 2966736, upload-time = "2025-11-12T19:03:25.064Z" }, - { url = "https://files.pythonhosted.org/packages/84/b8/bcc36d9d2464348106984956608a52a42a01ab44ea64031207dffdebc078/cython-3.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a4bf12de0475bb6a21e2336a4a04dc4a2b4dd0507a2a3c703e045f3484266605", size = 3221633, upload-time = "2025-11-12T19:03:26.754Z" }, - { url = "https://files.pythonhosted.org/packages/79/20/7d4807fe4ebcef9f20f2e5f93312d0f5d02f9f76524fd4e37706d04e83f7/cython-3.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18c64a0f69a1b8164de70ec7efc72250c589fec21519170de21582300f6aaed9", size = 3389542, upload-time = "2025-11-12T19:03:28.656Z" }, - { url = "https://files.pythonhosted.org/packages/2a/92/b06ba6721299293bc41e89732070132c453bdbaaeabb8f8cc76851b75345/cython-3.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:5ba14907d5826d8010e82306ce279a0d3650f5b50a4813c80836a17b2213c520", size = 2755307, upload-time = "2025-11-12T19:03:30.684Z" }, - { url = "https://files.pythonhosted.org/packages/40/28/c6e36c214baeb27ae45b518552e74457536c7c964b1a55b5900b047fa467/cython-3.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b4e850fc7a2f72d19679dd083fe4d20bf66860fceabb4f3207112f240249d708", size = 2957307, upload-time = "2025-11-12T19:03:32.471Z" }, - { url = "https://files.pythonhosted.org/packages/c8/c8/b0b9ba64f81f2875c42aab5c0979d6454cd1ac6b3c1e2373ad552701565d/cython-3.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d20ca4afe993f7dccad3aeddbf4c3536cb0fd3ad6dc7a225935a666a5655af2", size = 3210919, upload-time = "2025-11-12T19:03:34.274Z" }, - { url = "https://files.pythonhosted.org/packages/f9/33/5d9ca6abba0e77e1851b843dd1b3c4095fbc6373166935e83c4414f80e88/cython-3.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5a54a757d01ca6a260b02ce5baf17d9db1c2253566ab5844ee4966ff2a69c19", size = 3373350, upload-time = "2025-11-12T19:03:35.927Z" }, - { url = "https://files.pythonhosted.org/packages/e4/29/4408c3486ff380a2d6ae0d4b71da5195efcef3c4360017113ee7d1cb7335/cython-3.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:1b81e56584727a328e00d91c164f8f0f2c59b02bf6857c3f000cd830fa571453", size = 2753425, upload-time = "2025-11-12T19:03:38.157Z" }, - { url = "https://files.pythonhosted.org/packages/f0/32/c1aa03ccadda89487ff31b90d8651c3706ce2744bf4f2c2ae213147e89bd/cython-3.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7af6ad01c0fe1965d1d3badaeb6df53c1f37383ebae1ccb405b73f628f87713", size = 2967833, upload-time = "2025-11-12T19:03:40.233Z" }, - { url = "https://files.pythonhosted.org/packages/ff/dc/3488d3ade0635408a2ebb05561a3009e2f54616bfefd1f107088dfeb2c4c/cython-3.2.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3ea7cd085b62acb67c0fbde5cd17a7d9e47992c965e81ec977cf9ea7c59cd65", size = 3256237, upload-time = "2025-11-12T19:03:42.005Z" }, - { url = "https://files.pythonhosted.org/packages/7b/ba/f3d35d3803c9a424fa8812893847114deb9e2440c1bc67a31ab9ec4b9355/cython-3.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:986aea38fdf231e78d73745f83271c5654852c822dc5141a1d3fba64429a6aa6", size = 3383100, upload-time = "2025-11-12T19:03:43.675Z" }, - { url = "https://files.pythonhosted.org/packages/86/dc/d72dbb2f8e7ca95d2d18fd86f32b2e385996576230e7ecddd7d250786825/cython-3.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:4960e26cd34c1385f21646339f2e0361fcdd2ed3c01cdb50fe734add577ec56a", size = 2790322, upload-time = "2025-11-12T19:03:45.373Z" }, - { url = "https://files.pythonhosted.org/packages/5a/7e/1194f4ba98b981bbdca945a292e4f49e87ea09d69516b24445409e7cf611/cython-3.2.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:4e9167316bf6ecfea33dcca62f074605648fb93cc053ef46b5deb3e5d12fc0d3", size = 2872858, upload-time = "2025-11-12T19:03:55.074Z" }, - { url = "https://files.pythonhosted.org/packages/6b/1a/393ca8ffec7ad3f02b8e4bffaba3dba4fb62c4a1c4c0b6dbf3b80e709fe3/cython-3.2.1-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3095df6cd470064742f428c937bed7200c5123b9e19ee04aa09ec61281e565a3", size = 3209664, upload-time = "2025-11-12T19:03:56.771Z" }, - { url = "https://files.pythonhosted.org/packages/37/57/f209f64c609d3d8fac60a572e56da2f621dc1789e399c58db61d5645a31f/cython-3.2.1-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db3f53b2d9afb206075a2605f1150aa019f0733c7795a38eccc6119c2e9c3f7b", size = 2854607, upload-time = "2025-11-12T19:03:59.413Z" }, - { url = "https://files.pythonhosted.org/packages/fc/af/1e5c73fe52423f40776130b0be914fd9f9f8dc26c4f6ea4c2ed04772d558/cython-3.2.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0fc5e7687ac8f8e2b2fb95648f43e9e074ebaa72fd5cb3d8e20e5f1e8b8e02d9", size = 2991567, upload-time = "2025-11-12T19:04:02.209Z" }, - { url = "https://files.pythonhosted.org/packages/39/2c/3ea175b6b1fdfb429f9e9c395240d894155b3c0615caced05fef43264cba/cython-3.2.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:bbb3bc152bc0de82b031c8d355418fa4890a92424209d59366c2c0bc9e6cf53c", size = 2889178, upload-time = "2025-11-12T19:04:05.272Z" }, - { url = "https://files.pythonhosted.org/packages/f1/88/b2ab22a3a3feac78c62354a823c5c0c33659909e9918f53aa05904532b4b/cython-3.2.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:a2022bc48ad0c2c0e0485bf0b54902913a3d81086b7d435f4437620c667799f6", size = 3223755, upload-time = "2025-11-12T19:04:07.262Z" }, - { url = "https://files.pythonhosted.org/packages/0b/56/9ba58629a03cbffb5965a3c65ccd91fa683d95d588c21a875da72fdc249b/cython-3.2.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:99fdd4ffc2dcb513f4be9ce71c6fedd895b96b1f814655b6bbab196df497b090", size = 3113456, upload-time = "2025-11-12T19:04:09.175Z" }, - { url = "https://files.pythonhosted.org/packages/56/5b/148c1a7ea5aebe460a70cad716a77e5fd0205be2de9fc5250491eb13ad8c/cython-3.2.1-cp39-abi3-win32.whl", hash = "sha256:06071f85bd5ce040464d43b2f9f287742a79f905e81b709fe904567230f1ed51", size = 2434223, upload-time = "2025-11-12T19:04:11.294Z" }, - { url = "https://files.pythonhosted.org/packages/7a/54/bb9b0c9db2a92a5e93747ca3027cfc645741411f8f1c6af2fb2a7b82df5d/cython-3.2.1-cp39-abi3-win_arm64.whl", hash = "sha256:e87c131d59480aee1ebac622b64f287c0e1d665ad1a1b7d498ac48accdb36c6b", size = 2439268, upload-time = "2025-11-12T19:04:12.931Z" }, - { url = "https://files.pythonhosted.org/packages/aa/30/373775b8d933d781d055c1dd0f110f275a101f320dab724c8c63a7c1b945/cython-3.2.1-py3-none-any.whl", hash = "sha256:cd72c46e7bffe8250c52d400e72c8d5d3086437b6aeec5b0eca99ccd337f5834", size = 1254219, upload-time = "2025-11-12T19:02:56.14Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/1cfca43b7d20a0fdb1eac67313d6bb6b18d18897f82dd0f17436bdd2ba7f/cython-3.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:28e8075087a59756f2d059273184b8b639fe0f16cf17470bd91c39921bc154e0", size = 2960506, upload-time = "2026-01-04T14:15:16.733Z" }, + { url = "https://files.pythonhosted.org/packages/71/bb/8f28c39c342621047fea349a82fac712a5e2b37546d2f737bbde48d5143d/cython-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03893c88299a2c868bb741ba6513357acd104e7c42265809fd58dce1456a36fc", size = 3213148, upload-time = "2026-01-04T14:15:18.804Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8", size = 3375764, upload-time = "2026-01-04T14:15:20.817Z" }, + { url = "https://files.pythonhosted.org/packages/91/3f/deb8f023a5c10c0649eb81332a58c180fad27c7533bb4aae138b5bc34d92/cython-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:83266c356c13c68ffe658b4905279c993d8a5337bb0160fa90c8a3e297ea9a2e", size = 2754238, upload-time = "2026-01-04T14:15:23.001Z" }, + { url = "https://files.pythonhosted.org/packages/0a/8b/fd393f0923c82be4ec0db712fffb2ff0a7a131707b842c99bf24b549274d/cython-3.2.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:36bf3f5eb56d5281aafabecbaa6ed288bc11db87547bba4e1e52943ae6961ccf", size = 2875622, upload-time = "2026-01-04T14:15:39.749Z" }, + { url = "https://files.pythonhosted.org/packages/73/48/48530d9b9d64ec11dbe0dd3178a5fe1e0b27977c1054ecffb82be81e9b6a/cython-3.2.4-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6d5267f22b6451eb1e2e1b88f6f78a2c9c8733a6ddefd4520d3968d26b824581", size = 3210669, upload-time = "2026-01-04T14:15:41.911Z" }, + { url = "https://files.pythonhosted.org/packages/5e/91/4865fbfef1f6bb4f21d79c46104a53d1a3fa4348286237e15eafb26e0828/cython-3.2.4-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3b6e58f73a69230218d5381817850ce6d0da5bb7e87eb7d528c7027cbba40b06", size = 2856835, upload-time = "2026-01-04T14:15:43.815Z" }, + { url = "https://files.pythonhosted.org/packages/fa/39/60317957dbef179572398253f29d28f75f94ab82d6d39ea3237fb6c89268/cython-3.2.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e71efb20048358a6b8ec604a0532961c50c067b5e63e345e2e359fff72feaee8", size = 2994408, upload-time = "2026-01-04T14:15:45.422Z" }, + { url = "https://files.pythonhosted.org/packages/8d/30/7c24d9292650db4abebce98abc9b49c820d40fa7c87921c0a84c32f4efe7/cython-3.2.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:28b1e363b024c4b8dcf52ff68125e635cb9cb4b0ba997d628f25e32543a71103", size = 2891478, upload-time = "2026-01-04T14:15:47.394Z" }, + { url = "https://files.pythonhosted.org/packages/86/70/03dc3c962cde9da37a93cca8360e576f904d5f9beecfc9d70b1f820d2e5f/cython-3.2.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:31a90b4a2c47bb6d56baeb926948348ec968e932c1ae2c53239164e3e8880ccf", size = 3225663, upload-time = "2026-01-04T14:15:49.446Z" }, + { url = "https://files.pythonhosted.org/packages/b1/97/10b50c38313c37b1300325e2e53f48ea9a2c078a85c0c9572057135e31d5/cython-3.2.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e65e4773021f8dc8532010b4fbebe782c77f9a0817e93886e518c93bd6a44e9d", size = 3115628, upload-time = "2026-01-04T14:15:51.323Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b1/d6a353c9b147848122a0db370863601fdf56de2d983b5c4a6a11e6ee3cd7/cython-3.2.4-cp39-abi3-win32.whl", hash = "sha256:2b1f12c0e4798293d2754e73cd6f35fa5bbdf072bdc14bc6fc442c059ef2d290", size = 2437463, upload-time = "2026-01-04T14:15:53.787Z" }, + { url = "https://files.pythonhosted.org/packages/2d/d8/319a1263b9c33b71343adfd407e5daffd453daef47ebc7b642820a8b68ed/cython-3.2.4-cp39-abi3-win_arm64.whl", hash = "sha256:3b8e62049afef9da931d55de82d8f46c9a147313b69d5ff6af6e9121d545ce7a", size = 2442754, upload-time = "2026-01-04T14:15:55.382Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/d3c15189f7c52aaefbaea76fb012119b04b9013f4bf446cb4eb4c26c4e6b/cython-3.2.4-py3-none-any.whl", hash = "sha256:732fc93bc33ae4b14f6afaca663b916c2fdd5dcbfad7114e17fb2434eeaea45c", size = 1257078, upload-time = "2026-01-04T14:14:12.373Z" }, ] [[package]] @@ -166,11 +108,11 @@ wheels = [ [[package]] name = "fake-bpy-module" -version = "20251003" +version = "20260220" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/d7/8e34a795715d18497a257929ace8776a94d6c2c744e36b61e75567cbda64/fake_bpy_module-20251003.tar.gz", hash = "sha256:43d7fd082efc34497e238de3ad4d31fb850f2d1a8bb07418ae36eae56c1c7434", size = 973644, upload-time = "2025-10-03T06:19:57.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/26/708b316bae17afc3e2835f107ee416dcf66825faf0a8add9f358a2085014/fake_bpy_module-20260220.tar.gz", hash = "sha256:cfcb1aaf0e81fad439cae351dad50cb0b654b06f6adce97182fd8b2165cd924e", size = 966767, upload-time = "2026-02-20T06:44:18.914Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/24/d318f51ae1ebe953038984ed26fa0f9cd5466ef83da30c317282645695ec/fake_bpy_module-20251003-py3-none-any.whl", hash = "sha256:424f75fee6f300fc6d8e0d39abb28dbccd8777f611afa47ecdb9a03c00f2f43f", size = 1103011, upload-time = "2025-10-03T06:19:55.524Z" }, + { url = "https://files.pythonhosted.org/packages/da/cf/37653315492b57271095f9457a6071099e26a8916582d04b4428017ad4ca/fake_bpy_module-20260220-py3-none-any.whl", hash = "sha256:9dfecbbb3a5bc558102e33563e8735a07829473c4d97b77d208adfc45264d4ef", size = 1107212, upload-time = "2026-02-20T06:44:17.112Z" }, ] [[package]] @@ -196,24 +138,6 @@ name = "numpy" version = "1.26.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554, upload-time = "2024-02-05T23:51:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127, upload-time = "2024-02-05T23:52:15.314Z" }, - { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994, upload-time = "2024-02-05T23:52:47.569Z" }, - { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005, upload-time = "2024-02-05T23:53:15.637Z" }, - { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297, upload-time = "2024-02-05T23:53:42.16Z" }, - { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567, upload-time = "2024-02-05T23:54:11.696Z" }, - { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812, upload-time = "2024-02-05T23:54:26.453Z" }, - { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913, upload-time = "2024-02-05T23:54:53.933Z" }, - { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, - { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, - { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, - { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" }, - { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" }, - { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" }, - { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" }, - { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, -] [[package]] name = "orderly-set" @@ -226,20 +150,20 @@ wheels = [ [[package]] name = "packaging" -version = "25.0" +version = "26.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" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } 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://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] [[package]] name = "pip" -version = "25.3" +version = "26.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/6e/74a3f0179a4a73a53d66ce57fdb4de0080a8baa1de0063de206d6167acc2/pip-25.3.tar.gz", hash = "sha256:8d0538dbbd7babbd207f261ed969c65de439f6bc9e5dbd3b3b9a77f25d95f343", size = 1803014, upload-time = "2025-10-25T00:55:41.394Z" } +sdist = { url = "https://files.pythonhosted.org/packages/48/83/0d7d4e9efe3344b8e2fe25d93be44f64b65364d3c8d7bc6dc90198d5422e/pip-26.0.1.tar.gz", hash = "sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8", size = 1812747, upload-time = "2026-02-05T02:20:18.702Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/3c/d717024885424591d5376220b5e836c2d5293ce2011523c9de23ff7bf068/pip-25.3-py3-none-any.whl", hash = "sha256:9655943313a94722b7774661c21049070f6bbb0a1516bf02f7c8d5d9201514cd", size = 1778622, upload-time = "2025-10-25T00:55:39.247Z" }, + { url = "https://files.pythonhosted.org/packages/de/f0/c81e05b613866b76d2d1066490adf1a3dbc4ee9d9c839961c3fc8a6997af/pip-26.0.1-py3-none-any.whl", hash = "sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b", size = 1787723, upload-time = "2026-02-05T02:20:16.416Z" }, ] [[package]] @@ -262,7 +186,7 @@ wheels = [ [[package]] name = "pytest" -version = "9.0.1" +version = "9.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -271,9 +195,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", size = 1564125, upload-time = "2025-11-12T13:05:09.333Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl", hash = "sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", size = 373668, upload-time = "2025-11-12T13:05:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, ] [[package]] @@ -293,28 +217,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.10" +version = "0.15.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/04/eab13a954e763b0606f460443fcbf6bb5a0faf06890ea3754ff16523dce5/ruff-0.15.2.tar.gz", hash = "sha256:14b965afee0969e68bb871eba625343b8673375f457af4abe98553e8bbb98342", size = 4558148, upload-time = "2026-02-19T22:32:20.271Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, - { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, - { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, - { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, - { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, - { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, - { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, - { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, - { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, - { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, - { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, - { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, - { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, - { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, - { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, - { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, - { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, + { url = "https://files.pythonhosted.org/packages/2f/70/3a4dc6d09b13cb3e695f28307e5d889b2e1a66b7af9c5e257e796695b0e6/ruff-0.15.2-py3-none-linux_armv6l.whl", hash = "sha256:120691a6fdae2f16d65435648160f5b81a9625288f75544dc40637436b5d3c0d", size = 10430565, upload-time = "2026-02-19T22:32:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/71/0b/bb8457b56185ece1305c666dc895832946d24055be90692381c31d57466d/ruff-0.15.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a89056d831256099658b6bba4037ac6dd06f49d194199215befe2bb10457ea5e", size = 10820354, upload-time = "2026-02-19T22:32:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c1/e0532d7f9c9e0b14c46f61b14afd563298b8b83f337b6789ddd987e46121/ruff-0.15.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e36dee3a64be0ebd23c86ffa3aa3fd3ac9a712ff295e192243f814a830b6bd87", size = 10170767, upload-time = "2026-02-19T22:32:13.188Z" }, + { url = "https://files.pythonhosted.org/packages/47/e8/da1aa341d3af017a21c7a62fb5ec31d4e7ad0a93ab80e3a508316efbcb23/ruff-0.15.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9fb47b6d9764677f8c0a193c0943ce9a05d6763523f132325af8a858eadc2b9", size = 10529591, upload-time = "2026-02-19T22:32:02.547Z" }, + { url = "https://files.pythonhosted.org/packages/93/74/184fbf38e9f3510231fbc5e437e808f0b48c42d1df9434b208821efcd8d6/ruff-0.15.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f376990f9d0d6442ea9014b19621d8f2aaf2b8e39fdbfc79220b7f0c596c9b80", size = 10260771, upload-time = "2026-02-19T22:32:36.938Z" }, + { url = "https://files.pythonhosted.org/packages/05/ac/605c20b8e059a0bc4b42360414baa4892ff278cec1c91fff4be0dceedefd/ruff-0.15.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dcc987551952d73cbf5c88d9fdee815618d497e4df86cd4c4824cc59d5dd75f", size = 11045791, upload-time = "2026-02-19T22:32:31.642Z" }, + { url = "https://files.pythonhosted.org/packages/fd/52/db6e419908f45a894924d410ac77d64bdd98ff86901d833364251bd08e22/ruff-0.15.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42a47fd785cbe8c01b9ff45031af875d101b040ad8f4de7bbb716487c74c9a77", size = 11879271, upload-time = "2026-02-19T22:32:29.305Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d8/7992b18f2008bdc9231d0f10b16df7dda964dbf639e2b8b4c1b4e91b83af/ruff-0.15.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe9f49354866e575b4c6943856989f966421870e85cd2ac94dccb0a9dcb2fea", size = 11303707, upload-time = "2026-02-19T22:32:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/d7/02/849b46184bcfdd4b64cde61752cc9a146c54759ed036edd11857e9b8443b/ruff-0.15.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7a672c82b5f9887576087d97be5ce439f04bbaf548ee987b92d3a7dede41d3a", size = 11149151, upload-time = "2026-02-19T22:32:44.234Z" }, + { url = "https://files.pythonhosted.org/packages/70/04/f5284e388bab60d1d3b99614a5a9aeb03e0f333847e2429bebd2aaa1feec/ruff-0.15.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ecc64f46f7019e2bcc3cdc05d4a7da958b629a5ab7033195e11a438403d956", size = 11091132, upload-time = "2026-02-19T22:32:24.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ae/88d844a21110e14d92cf73d57363fab59b727ebeabe78009b9ccb23500af/ruff-0.15.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8dcf243b15b561c655c1ef2f2b0050e5d50db37fe90115507f6ff37d865dc8b4", size = 10504717, upload-time = "2026-02-19T22:32:26.75Z" }, + { url = "https://files.pythonhosted.org/packages/64/27/867076a6ada7f2b9c8292884ab44d08fd2ba71bd2b5364d4136f3cd537e1/ruff-0.15.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dab6941c862c05739774677c6273166d2510d254dac0695c0e3f5efa1b5585de", size = 10263122, upload-time = "2026-02-19T22:32:10.036Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ef/faf9321d550f8ebf0c6373696e70d1758e20ccdc3951ad7af00c0956be7c/ruff-0.15.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1b9164f57fc36058e9a6806eb92af185b0697c9fe4c7c52caa431c6554521e5c", size = 10735295, upload-time = "2026-02-19T22:32:39.227Z" }, + { url = "https://files.pythonhosted.org/packages/2f/55/e8089fec62e050ba84d71b70e7834b97709ca9b7aba10c1a0b196e493f97/ruff-0.15.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80d24fcae24d42659db7e335b9e1531697a7102c19185b8dc4a028b952865fd8", size = 11241641, upload-time = "2026-02-19T22:32:34.617Z" }, + { url = "https://files.pythonhosted.org/packages/23/01/1c30526460f4d23222d0fabd5888868262fd0e2b71a00570ca26483cd993/ruff-0.15.2-py3-none-win32.whl", hash = "sha256:fd5ff9e5f519a7e1bd99cbe8daa324010a74f5e2ebc97c6242c08f26f3714f6f", size = 10507885, upload-time = "2026-02-19T22:32:15.635Z" }, + { url = "https://files.pythonhosted.org/packages/5c/10/3d18e3bbdf8fc50bbb4ac3cc45970aa5a9753c5cb51bf9ed9a3cd8b79fa3/ruff-0.15.2-py3-none-win_amd64.whl", hash = "sha256:d20014e3dfa400f3ff84830dfb5755ece2de45ab62ecea4af6b7262d0fb4f7c5", size = 11623725, upload-time = "2026-02-19T22:32:04.947Z" }, + { url = "https://files.pythonhosted.org/packages/6d/78/097c0798b1dab9f8affe73da9642bb4500e098cb27fd8dc9724816ac747b/ruff-0.15.2-py3-none-win_arm64.whl", hash = "sha256:cabddc5822acdc8f7b5527b36ceac55cc51eec7b1946e60181de8fe83ca8876e", size = 10941649, upload-time = "2026-02-19T22:32:18.108Z" }, ] [[package]] @@ -328,7 +251,7 @@ bpy = [ ] [package.metadata] -requires-dist = [{ name = "bpy", marker = "extra == 'bpy'", specifier = ">=5.0.0,<5.1" }] +requires-dist = [{ name = "bpy", marker = "extra == 'bpy'", specifier = ">=5" }] provides-extras = ["bpy"] [[package]] @@ -375,7 +298,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "bpy", specifier = ">=5.0.0,<5.1" }, + { name = "bpy", specifier = "==5.1.*" }, { name = "tree-clipper", editable = "packages/tree_clipper" }, ] @@ -392,36 +315,35 @@ dev = [ [[package]] name = "ty" -version = "0.0.3" +version = "0.0.18" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/cd/aee86c0da3240960d6b7e807f3a41c89bae741495d81ca303200b0103dc9/ty-0.0.3.tar.gz", hash = "sha256:831259e22d3855436701472d4c0da200cd45041bc677eae79415d684f541de8a", size = 4769098, upload-time = "2025-12-18T02:16:49.773Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/15/9682700d8d60fdca7afa4febc83a2354b29cdcd56e66e19c92b521db3b39/ty-0.0.18.tar.gz", hash = "sha256:04ab7c3db5dcbcdac6ce62e48940d3a0124f377c05499d3f3e004e264ae94b83", size = 5214774, upload-time = "2026-02-20T21:51:31.173Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/ef/2d0d18e8fe6b673d3e1ea642f18404d7edfa9d08310f7203e8f0e7dc862e/ty-0.0.3-py3-none-linux_armv6l.whl", hash = "sha256:cd035bb75acecb78ac1ba8c4cc696f57a586e29d36e84bd691bc3b5b8362794c", size = 9763890, upload-time = "2025-12-18T02:16:56.879Z" }, - { url = "https://files.pythonhosted.org/packages/bb/67/0ae31574619a7264df8cf8e641f246992db22ac1720c2a72953aa31cbe61/ty-0.0.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7708eaf73485e263efc7ef339f8e4487d3f5885779edbeec504fd72e4521c376", size = 9558276, upload-time = "2025-12-18T02:16:45.453Z" }, - { url = "https://files.pythonhosted.org/packages/d7/f7/3b9c033e80910972fca3783e4a52ba9cb7cd5c8b6828a87986646d64082b/ty-0.0.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3113a633f46ec789f6df675b7afc5d3ab20c247c92ae4dbb9aa5b704768c18b2", size = 9094451, upload-time = "2025-12-18T02:17:01.155Z" }, - { url = "https://files.pythonhosted.org/packages/9a/29/9a90ed6bef00142a088965100b5e0a5d11805b9729c151ca598331bbd92b/ty-0.0.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a451f3f73a04bf18e551b1ebebb79b20fac5f09740a353f7e07b5f607b217c4f", size = 9568049, upload-time = "2025-12-18T02:16:28.643Z" }, - { url = "https://files.pythonhosted.org/packages/2f/ab/8daeb12912c2de8a3154db652931f4ad0d27c555faebcaf34af08bcfd0d2/ty-0.0.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f6e926b6de0becf0452e1afad75cb71f889a4777cd14269e5447d46c01b2770", size = 9547711, upload-time = "2025-12-18T02:16:54.464Z" }, - { url = "https://files.pythonhosted.org/packages/91/54/f5c1f293f647beda717fee2448cc927ac0d05f66bebe18647680a67e1d67/ty-0.0.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:160e7974150f9f359c31d5808214676d1baa05321ab5a7b29fb09f4906dbdb38", size = 9983225, upload-time = "2025-12-18T02:17:05.672Z" }, - { url = "https://files.pythonhosted.org/packages/95/34/065962cfa2e87c10db839512229940a366b8ca1caffa2254a277b1694e5a/ty-0.0.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:726576df31d4e76934ffc64f2939d4a9bc195c7427452c8c159261ad00bd1b5e", size = 10851148, upload-time = "2025-12-18T02:16:38.354Z" }, - { url = "https://files.pythonhosted.org/packages/54/27/e2a8cbfc33999eef882ccd1b816ed615293f96e96f6df60cd12f84b69ca2/ty-0.0.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5014cf4744c94d9ea7b43314199ddaf52564a80b3d006e4ba0fe982bc42f4e8b", size = 10564441, upload-time = "2025-12-18T02:17:03.584Z" }, - { url = "https://files.pythonhosted.org/packages/91/6d/dcce3e222e59477c1f2b3a012cc76428d7032248138cd5544ad7f1cda7bd/ty-0.0.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a9a51dc040f2718725f34ae6ef51fe8f8bd689e21bd3e82f4e71767034928de", size = 10358651, upload-time = "2025-12-18T02:16:26.091Z" }, - { url = "https://files.pythonhosted.org/packages/53/36/b6d0154b83a5997d607bf1238200271c17223f68aab2c778ded5424f9c1e/ty-0.0.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e6188eddd3a228c449261bb398e8621d33b92c1fc03599afdfad4388327a48", size = 10120457, upload-time = "2025-12-18T02:16:51.864Z" }, - { url = "https://files.pythonhosted.org/packages/cc/46/05dc826674ee1a451406e4c253c71700a6f707bae88b706a4c9e9bba6919/ty-0.0.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5cc55e08d5d18edf1c5051af02456bd359716f07aae0a305e4cefe7735188540", size = 9551642, upload-time = "2025-12-18T02:16:33.518Z" }, - { url = "https://files.pythonhosted.org/packages/64/8a/f90b60d103fd5ec04ecbac091a64e607e6cd37cec6e718bba17cb2022644/ty-0.0.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:34b2d589412a81d1fd6d7fe461353068496c2bf1f7113742bd6d88d1d57ec3ad", size = 9572234, upload-time = "2025-12-18T02:16:31.013Z" }, - { url = "https://files.pythonhosted.org/packages/e8/72/5d3c6d34562d019ba7f3102b2a6d0c8e9e24ef39e70f09645c36a66765b7/ty-0.0.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8a065eb2959f141fe4adafc14d57463cfa34f6cc4844a4ed56b2dce1a53a419a", size = 9701682, upload-time = "2025-12-18T02:16:41.379Z" }, - { url = "https://files.pythonhosted.org/packages/ef/44/bda434f788b320c9550a48c549e4a8c507e3d8a6ccb04ba5bd098307ba1e/ty-0.0.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e7177421f830a493f98d22f86d940b5a38788866e6062f680881f19be35ba3bb", size = 10213714, upload-time = "2025-12-18T02:16:35.648Z" }, - { url = "https://files.pythonhosted.org/packages/53/a6/b76a787938026c3d209131e5773de32cf6fc41210e0dd97874aafa20f394/ty-0.0.3-py3-none-win32.whl", hash = "sha256:e3e590bf5f33cb118a53c6d5242eedf7924d45517a5ee676c7a16be3a1389d2f", size = 9160441, upload-time = "2025-12-18T02:16:43.404Z" }, - { url = "https://files.pythonhosted.org/packages/fe/db/da60eb8252768323aee0ce69a08b95011088c003f80204b12380fe562fd2/ty-0.0.3-py3-none-win_amd64.whl", hash = "sha256:5af25b1fed8a536ce8072a9ae6a70cd2b559aa5294d43f57071fbdcd31dd2b0e", size = 10034265, upload-time = "2025-12-18T02:16:47.602Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9c/9045cebdfc394c6f8c1e73a99d3aeda1bc639aace392e8ff4d695f1fab73/ty-0.0.3-py3-none-win_arm64.whl", hash = "sha256:29078b3100351a8b37339771615f13b8e4a4ff52b344d33f774f8d1a665a0ca5", size = 9513095, upload-time = "2025-12-18T02:16:59.073Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d8/920460d4c22ea68fcdeb0b2fb53ea2aeb9c6d7875bde9278d84f2ac767b6/ty-0.0.18-py3-none-linux_armv6l.whl", hash = "sha256:4e5e91b0a79857316ef893c5068afc4b9872f9d257627d9bc8ac4d2715750d88", size = 10280825, upload-time = "2026-02-20T21:51:25.03Z" }, + { url = "https://files.pythonhosted.org/packages/83/56/62587de582d3d20d78fcdddd0594a73822ac5a399a12ef512085eb7a4de6/ty-0.0.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ee0e578b3f8416e2d5416da9553b78fd33857868aa1384cb7fefeceee5ff102d", size = 10118324, upload-time = "2026-02-20T21:51:22.27Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2d/dbdace8d432a0755a7417f659bfd5b8a4261938ecbdfd7b42f4c454f5aa9/ty-0.0.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3f7a0487d36b939546a91d141f7fc3dbea32fab4982f618d5b04dc9d5b6da21e", size = 9605861, upload-time = "2026-02-20T21:51:16.066Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d9/de11c0280f778d5fc571393aada7fe9b8bc1dd6a738f2e2c45702b8b3150/ty-0.0.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5e2fa8d45f57ca487a470e4bf66319c09b561150e98ae2a6b1a97ef04c1a4eb", size = 10092701, upload-time = "2026-02-20T21:51:26.862Z" }, + { url = "https://files.pythonhosted.org/packages/0f/94/068d4d591d791041732171e7b63c37a54494b2e7d28e88d2167eaa9ad875/ty-0.0.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d75652e9e937f7044b1aca16091193e7ef11dac1c7ec952b7fb8292b7ba1f5f2", size = 10109203, upload-time = "2026-02-20T21:51:11.59Z" }, + { url = "https://files.pythonhosted.org/packages/34/e4/526a4aa56dc0ca2569aaa16880a1ab105c3b416dd70e87e25a05688999f3/ty-0.0.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:563c868edceb8f6ddd5e91113c17d3676b028f0ed380bdb3829b06d9beb90e58", size = 10614200, upload-time = "2026-02-20T21:51:20.298Z" }, + { url = "https://files.pythonhosted.org/packages/fd/3d/b68ab20a34122a395880922587fbfc3adf090d22e0fb546d4d20fe8c2621/ty-0.0.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:502e2a1f948bec563a0454fc25b074bf5cf041744adba8794d024277e151d3b0", size = 11153232, upload-time = "2026-02-20T21:51:14.121Z" }, + { url = "https://files.pythonhosted.org/packages/68/ea/678243c042343fcda7e6af36036c18676c355878dcdcd517639586d2cf9e/ty-0.0.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc881dea97021a3aa29134a476937fd8054775c4177d01b94db27fcfb7aab65b", size = 10832934, upload-time = "2026-02-20T21:51:32.92Z" }, + { url = "https://files.pythonhosted.org/packages/d8/bd/7f8d647cef8b7b346c0163230a37e903c7461c7248574840b977045c77df/ty-0.0.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:421fcc3bc64cab56f48edb863c7c1c43649ec4d78ff71a1acb5366ad723b6021", size = 10700888, upload-time = "2026-02-20T21:51:09.673Z" }, + { url = "https://files.pythonhosted.org/packages/6e/06/cb3620dc48c5d335ba7876edfef636b2f4498eff4a262ff90033b9e88408/ty-0.0.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0fe5038a7136a0e638a2fb1ad06e3d3c4045314c6ba165c9c303b9aeb4623d6c", size = 10078965, upload-time = "2026-02-20T21:51:07.678Z" }, + { url = "https://files.pythonhosted.org/packages/60/27/c77a5a84533fa3b685d592de7b4b108eb1f38851c40fac4e79cc56ec7350/ty-0.0.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d123600a52372677613a719bbb780adeb9b68f47fb5f25acb09171de390e0035", size = 10134659, upload-time = "2026-02-20T21:51:18.311Z" }, + { url = "https://files.pythonhosted.org/packages/43/6e/60af6b88c73469e628ba5253a296da6984e0aa746206f3034c31f1a04ed1/ty-0.0.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb4bc11d32a1bf96a829bf6b9696545a30a196ac77bbc07cc8d3dfee35e03723", size = 10297494, upload-time = "2026-02-20T21:51:39.631Z" }, + { url = "https://files.pythonhosted.org/packages/33/90/612dc0b68224c723faed6adac2bd3f930a750685db76dfe17e6b9e534a83/ty-0.0.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dda2efbf374ba4cd704053d04e32f2f784e85c2ddc2400006b0f96f5f7e4b667", size = 10791944, upload-time = "2026-02-20T21:51:37.13Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/f4ada0fd08a9e4138fe3fd2bcd3797753593f423f19b1634a814b9b2a401/ty-0.0.18-py3-none-win32.whl", hash = "sha256:c5768607c94977dacddc2f459ace6a11a408a0f57888dd59abb62d28d4fee4f7", size = 9677964, upload-time = "2026-02-20T21:51:42.039Z" }, + { url = "https://files.pythonhosted.org/packages/5e/fa/090ed9746e5c59fc26d8f5f96dc8441825171f1f47752f1778dad690b08b/ty-0.0.18-py3-none-win_amd64.whl", hash = "sha256:b78d0fa1103d36fc2fce92f2092adace52a74654ab7884d54cdaec8eb5016a4d", size = 10636576, upload-time = "2026-02-20T21:51:29.159Z" }, + { url = "https://files.pythonhosted.org/packages/92/4f/5dd60904c8105cda4d0be34d3a446c180933c76b84ae0742e58f02133713/ty-0.0.18-py3-none-win_arm64.whl", hash = "sha256:01770c3c82137c6b216aa3251478f0b197e181054ee92243772de553d3586398", size = 10095449, upload-time = "2026-02-20T21:51:34.914Z" }, ] [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" 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" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } 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://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, ] [[package]] @@ -435,40 +357,6 @@ version = "0.25.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", size = 795254, upload-time = "2025-09-14T22:16:26.137Z" }, - { url = "https://files.pythonhosted.org/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", size = 640559, upload-time = "2025-09-14T22:16:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", size = 5348020, upload-time = "2025-09-14T22:16:29.523Z" }, - { url = "https://files.pythonhosted.org/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", size = 5058126, upload-time = "2025-09-14T22:16:31.811Z" }, - { url = "https://files.pythonhosted.org/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", size = 5405390, upload-time = "2025-09-14T22:16:33.486Z" }, - { url = "https://files.pythonhosted.org/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", size = 5452914, upload-time = "2025-09-14T22:16:35.277Z" }, - { url = "https://files.pythonhosted.org/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", size = 5559635, upload-time = "2025-09-14T22:16:37.141Z" }, - { url = "https://files.pythonhosted.org/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", size = 5048277, upload-time = "2025-09-14T22:16:38.807Z" }, - { url = "https://files.pythonhosted.org/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", size = 5574377, upload-time = "2025-09-14T22:16:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", size = 4961493, upload-time = "2025-09-14T22:16:43.3Z" }, - { url = "https://files.pythonhosted.org/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", size = 5269018, upload-time = "2025-09-14T22:16:45.292Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", size = 5443672, upload-time = "2025-09-14T22:16:47.076Z" }, - { url = "https://files.pythonhosted.org/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", size = 5822753, upload-time = "2025-09-14T22:16:49.316Z" }, - { url = "https://files.pythonhosted.org/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", size = 5366047, upload-time = "2025-09-14T22:16:51.328Z" }, - { url = "https://files.pythonhosted.org/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl", hash = "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", size = 436484, upload-time = "2025-09-14T22:16:55.005Z" }, - { url = "https://files.pythonhosted.org/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", size = 506183, upload-time = "2025-09-14T22:16:52.753Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", size = 462533, upload-time = "2025-09-14T22:16:53.878Z" }, - { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" }, - { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" }, - { url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012, upload-time = "2025-09-14T22:17:01.156Z" }, - { url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148, upload-time = "2025-09-14T22:17:03.091Z" }, - { url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652, upload-time = "2025-09-14T22:17:04.979Z" }, - { url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993, upload-time = "2025-09-14T22:17:06.781Z" }, - { url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806, upload-time = "2025-09-14T22:17:08.415Z" }, - { url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659, upload-time = "2025-09-14T22:17:10.164Z" }, - { url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933, upload-time = "2025-09-14T22:17:11.857Z" }, - { url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008, upload-time = "2025-09-14T22:17:13.627Z" }, - { url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517, upload-time = "2025-09-14T22:17:16.103Z" }, - { url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292, upload-time = "2025-09-14T22:17:17.827Z" }, - { url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237, upload-time = "2025-09-14T22:17:19.954Z" }, - { url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922, upload-time = "2025-09-14T22:17:24.398Z" }, - { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, - { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, { url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735, upload-time = "2025-09-14T22:17:26.042Z" }, { url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440, upload-time = "2025-09-14T22:17:27.366Z" }, { url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070, upload-time = "2025-09-14T22:17:28.896Z" }, @@ -486,19 +374,4 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936, upload-time = "2025-09-14T22:17:52.658Z" }, { url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232, upload-time = "2025-09-14T22:17:50.402Z" }, { url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671, upload-time = "2025-09-14T22:17:51.533Z" }, - { url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887, upload-time = "2025-09-14T22:17:54.198Z" }, - { url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658, upload-time = "2025-09-14T22:17:55.423Z" }, - { url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849, upload-time = "2025-09-14T22:17:57.372Z" }, - { url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095, upload-time = "2025-09-14T22:17:59.498Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751, upload-time = "2025-09-14T22:18:01.618Z" }, - { url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818, upload-time = "2025-09-14T22:18:03.769Z" }, - { url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402, upload-time = "2025-09-14T22:18:05.954Z" }, - { url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108, upload-time = "2025-09-14T22:18:07.68Z" }, - { url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248, upload-time = "2025-09-14T22:18:09.753Z" }, - { url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330, upload-time = "2025-09-14T22:18:11.966Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123, upload-time = "2025-09-14T22:18:13.907Z" }, - { url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591, upload-time = "2025-09-14T22:18:16.465Z" }, - { url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" }, - { url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" }, - { url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" }, ] From 54a93bb3845c47e29affa2a5cb3c47033f0697d0 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Mon, 23 Feb 2026 21:06:04 +0100 Subject: [PATCH 04/29] fix: somehow the conftest doesn't work otherwise --- packages/tree_clipper/tests/conftest.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/tree_clipper/tests/conftest.py b/packages/tree_clipper/tests/conftest.py index b552ce7..d604672 100644 --- a/packages/tree_clipper/tests/conftest.py +++ b/packages/tree_clipper/tests/conftest.py @@ -22,5 +22,8 @@ def pytest_generate_tests(metafunc): cls for cls in all_subclasses(bpy.types.Node) if len(all_subclasses(cls)) == 0 ) - if metafunc.function == test_all_nodes: + if ( + metafunc == test_all_nodes + or metafunc.function.__name__ == test_all_nodes.__name__ + ): metafunc.parametrize("node_type", node_types) From c71b032bbeb6218429ea4394b6ad2c234334f1f7 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Mon, 23 Feb 2026 21:06:43 +0100 Subject: [PATCH 05/29] tidy: the printed message was a tad off --- packages/tree_clipper_addon/src/tree_clipper_addon/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tree_clipper_addon/src/tree_clipper_addon/__init__.py b/packages/tree_clipper_addon/src/tree_clipper_addon/__init__.py index c267317..bfb20f9 100644 --- a/packages/tree_clipper_addon/src/tree_clipper_addon/__init__.py +++ b/packages/tree_clipper_addon/src/tree_clipper_addon/__init__.py @@ -54,7 +54,7 @@ def register() -> None: - print("reloaded") + print("Registering Tree Clipper") for cls in classes: bpy.utils.register_class(cls) # the pointer properties in the items make it impossible to store on the operator From 4c6a2c38d8be87a4ef33098549ae43a0862d321f Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Tue, 24 Feb 2026 18:19:46 +0100 Subject: [PATCH 06/29] feat: add support for Field to List node --- .../src/tree_clipper/specific_handlers.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 7286d6d..05d9b31 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -92,6 +92,7 @@ ACTIVE_GENERATION_INDEX = "active_generation_index" ACTIVE_MAIN_INDEX = "active_main_index" DEFAULT_INPUT = "default_input" +LIST_ITEMS = "list_items" # this might not be needed anymore in many cases, because @@ -1471,6 +1472,38 @@ def serialize(self): return data +class FieldToListExporter(SpecificExporter[bpy.types.GeometryNodeFieldToList]): + def serialize(self): + return self.export_all_simple_writable_properties_and_list( + [INPUTS, OUTPUTS, BL_IDNAME, LIST_ITEMS], + [PARENT], + ) + + +class FieldToListImporter(SpecificImporter[bpy.types.GeometryNodeFieldToList]): + def deserialize(self): + self.import_all_simple_writable_properties_and_list( + # ordering is important, the list_items implicitly create sockets + [LIST_ITEMS, ACTIVE_INDEX, INPUTS, OUTPUTS] + ) + + +class FieldToListItemExporter(SpecificExporter[bpy.types.GeometryNodeFieldToListItem]): + def serialize(self): + return self.export_all_simple_writable_properties() + + +class FieldToGridItemsImporter( + SpecificImporter[bpy.types.GeometryNodeFieldToListItems] +): + def deserialize(self): + self.getter().clear() + for item in self.serialization[ITEMS]: + socket_type = item[DATA][SOCKET_TYPE] + name = item[DATA][NAME] + self.getter().new(name=name, socket_type=socket_type) + + # now they are cooked and ready to use ~ bon appétit BUILT_IN_EXPORTER = _BUILT_IN_EXPORTER BUILT_IN_IMPORTER = _BUILT_IN_IMPORTER From a1bf34f2f173a9bbd307b5c843e94f2f0cdc46d3 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 00:48:41 +0100 Subject: [PATCH 07/29] fix: skip 'add' and 'remove' attributes --- .../src/tree_clipper/specific_handlers.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 05d9b31..a4e8822 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -93,6 +93,8 @@ ACTIVE_MAIN_INDEX = "active_main_index" DEFAULT_INPUT = "default_input" LIST_ITEMS = "list_items" +ADD = "add" +REMOVE = "remove" # this might not be needed anymore in many cases, because @@ -1504,6 +1506,30 @@ def deserialize(self): self.getter().new(name=name, socket_type=socket_type) +class CryptomatteExporter(SpecificExporter[bpy.types.CompositorNodeCryptomatte]): + def serialize(self): + data = self.export_all_simple_writable_properties_and_list( + [INPUTS, OUTPUTS, BL_IDNAME], + [PARENT], + ) + # https://github.com/Algebraic-UG/tree_clipper/issues/165 + data.pop(ADD) + data.pop(REMOVE) + return data + + +class CryptomatteV2Exporter(SpecificExporter[bpy.types.CompositorNodeCryptomatteV2]): + def serialize(self): + data = self.export_all_simple_writable_properties_and_list( + [INPUTS, OUTPUTS, BL_IDNAME, ENTRIES], + [PARENT, IMAGE, SCENE], + ) + # https://github.com/Algebraic-UG/tree_clipper/issues/165 + data.pop(ADD) + data.pop(REMOVE) + return data + + # now they are cooked and ready to use ~ bon appétit BUILT_IN_EXPORTER = _BUILT_IN_EXPORTER BUILT_IN_IMPORTER = _BUILT_IN_IMPORTER From acc6f8036852ae457423f222a02c3303089d58cf Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 01:04:39 +0100 Subject: [PATCH 08/29] tidy: remove superfluous call --- packages/tree_clipper/src/tree_clipper/specific_handlers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index a4e8822..49def71 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1411,8 +1411,6 @@ def deserialize(self) -> None: [GRID_ITEMS, ACTIVE_INDEX, INPUTS, OUTPUTS] ) - return super().deserialize() - class FieldToGridItemExporter(SpecificExporter[bpy.types.GeometryNodeFieldToGridItem]): def serialize(self): From 9f759f6ad68aaac2c9aecb1ee4a53109bed0272c Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 01:04:23 +0100 Subject: [PATCH 09/29] tidy: reusing class name --- packages/tree_clipper/src/tree_clipper/specific_handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 49def71..6fcd32f 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1493,7 +1493,7 @@ def serialize(self): return self.export_all_simple_writable_properties() -class FieldToGridItemsImporter( +class FieldToListItemsImporter( SpecificImporter[bpy.types.GeometryNodeFieldToListItems] ): def deserialize(self): From 10755e86b549d082a5ee937558b5accf01101a68 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 01:11:01 +0100 Subject: [PATCH 10/29] fix: font is now a socket --- packages/tree_clipper/tests/test_external_items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tree_clipper/tests/test_external_items.py b/packages/tree_clipper/tests/test_external_items.py index 3fef7a4..a0b6bd4 100644 --- a/packages/tree_clipper/tests/test_external_items.py +++ b/packages/tree_clipper/tests/test_external_items.py @@ -57,7 +57,7 @@ def _create_setup(): node.text = _EXTERNAL_ITEM_MAKER["Text"]() # ty: ignore[invalid-assignment, unresolved-attribute] node = nodes.new("GeometryNodeStringToCurves") - node.font = _EXTERNAL_ITEM_MAKER["VectorFont"]() # ty: ignore[invalid-assignment, unresolved-attribute] + node.inputs["Font"].default_value = _EXTERNAL_ITEM_MAKER["VectorFont"]() # ty: ignore[invalid-assignment, unresolved-attribute] return name @@ -127,7 +127,7 @@ def _check_after_import(name: str): assert tree.nodes["Material"].material is not None # ty: ignore[unresolved-attribute] assert tree.nodes["Object"].object is not None # ty: ignore[unresolved-attribute] assert tree.nodes["Collection"].collection is not None # ty: ignore[unresolved-attribute] - assert tree.nodes["String to Curves"].font is not None # ty: ignore[unresolved-attribute] + assert tree.nodes["String to Curves"].inputs["Font"].default_value is not None # ty: ignore[unresolved-attribute] assert len(tree.nodes) == 7, "if this fails the lines above must also change" From ec516cae5d438129158ae039df95634df7716994 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:25:13 +0100 Subject: [PATCH 11/29] feat: store imported blender version for backward compat handling --- .../src/tree_clipper/import_nodes.py | 24 +++- .../src/tree_clipper/specific_abstract.py | 24 ++++ .../src/tree_clipper/specific_handlers.py | 112 ++++++++++-------- 3 files changed, 104 insertions(+), 56 deletions(-) diff --git a/packages/tree_clipper/src/tree_clipper/import_nodes.py b/packages/tree_clipper/src/tree_clipper/import_nodes.py index e299b9a..8bbef83 100644 --- a/packages/tree_clipper/src/tree_clipper/import_nodes.py +++ b/packages/tree_clipper/src/tree_clipper/import_nodes.py @@ -67,10 +67,14 @@ def __init__( class Importer: def __init__( self, + *, + blender_version: list[int], specific_handlers: dict[type, DESERIALIZER], getters: dict[int, GETTER], debug_prints: bool, ) -> None: + self.blender_version = blender_version + self.specific_handlers = specific_handlers self.getters = getters self.debug_prints = debug_prints @@ -498,10 +502,15 @@ def getter() -> bpy.types.ShaderNodeTree: def _check_version(data: dict) -> None: - exporter_blender_version = data[BLENDER_VERSION] - importer_blender_version = bpy.app.version_string - - if exporter_blender_version != importer_blender_version: + exporter_blender_version = [ + int(v) for v in data[BLENDER_VERSION].split(" ")[0].split(".") + ] + importer_blender_version = bpy.app.version + + if ( + exporter_blender_version[0] != importer_blender_version[0] + or exporter_blender_version[1] > importer_blender_version[1] + ): raise RuntimeError( f"Blender version mismatch. File version: {exporter_blender_version}, but running {importer_blender_version}" ) @@ -620,11 +629,18 @@ def set_external( assert int(external_id) in self.getters def start_import(self, parameters: ImportParameters) -> None: + version_cycle = self.data[BLENDER_VERSION].split(" ") + blender_version = [int(v) for v in version_cycle[0].split(".")] self.importer = Importer( + blender_version=blender_version, specific_handlers=parameters.specific_handlers, getters=self.getters, debug_prints=parameters.debug_prints, ) + if len(version_cycle) > 1: + self.importer.report.warnings.append( + f"This was exported from a Blender {version_cycle[1]} version." + ) def step(self) -> bool: assert isinstance(self.importer, Importer) diff --git a/packages/tree_clipper/src/tree_clipper/specific_abstract.py b/packages/tree_clipper/src/tree_clipper/specific_abstract.py index 1901976..7292efd 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_abstract.py +++ b/packages/tree_clipper/src/tree_clipper/specific_abstract.py @@ -275,6 +275,30 @@ def import_all_simple_writable_properties_and_list(self, id_list: list[str]): self.import_all_simple_writable_properties() self.import_properties_from_id_list(id_list) + def only_create_getters(self, id_list: list[str]): + for identifier in id_list: + self.register_getter( + getter=lambda: getattr(self.getter(), identifier), + serialization=self.serialization[identifier], + from_root=self.from_root.add_prop( + self.getter().bl_rna.properties[identifier] + ), + ) + + def register_getter( + self, + *, + getter: GETTER, + serialization: dict[str, Any], + from_root, + ): + self.importer._import_obj_with_deserializer( + getter=getter, + serialization=serialization, + deserializer=default_deserializer, + from_root=from_root, + ) + @abstractmethod def deserialize(self) -> None: """Do the actual importing here""" diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 6fcd32f..9e7d3fe 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -7,6 +7,7 @@ _BUILT_IN_IMPORTER, SpecificExporter, SpecificImporter, + default_serializer, ) from .common import ( @@ -95,6 +96,11 @@ LIST_ITEMS = "list_items" ADD = "add" REMOVE = "remove" +FONT = "font" +OVERFLOW = "overflow" +ALIGN_X = "align_x" +ALIGN_Y = "align_y" +PIVOT_MODE = "pivot_mode" # this might not be needed anymore in many cases, because @@ -1472,60 +1478,62 @@ def serialize(self): return data -class FieldToListExporter(SpecificExporter[bpy.types.GeometryNodeFieldToList]): - def serialize(self): - return self.export_all_simple_writable_properties_and_list( - [INPUTS, OUTPUTS, BL_IDNAME, LIST_ITEMS], - [PARENT], - ) - - -class FieldToListImporter(SpecificImporter[bpy.types.GeometryNodeFieldToList]): - def deserialize(self): - self.import_all_simple_writable_properties_and_list( - # ordering is important, the list_items implicitly create sockets - [LIST_ITEMS, ACTIVE_INDEX, INPUTS, OUTPUTS] - ) - - -class FieldToListItemExporter(SpecificExporter[bpy.types.GeometryNodeFieldToListItem]): - def serialize(self): - return self.export_all_simple_writable_properties() - - -class FieldToListItemsImporter( - SpecificImporter[bpy.types.GeometryNodeFieldToListItems] -): - def deserialize(self): - self.getter().clear() - for item in self.serialization[ITEMS]: - socket_type = item[DATA][SOCKET_TYPE] - name = item[DATA][NAME] - self.getter().new(name=name, socket_type=socket_type) - - -class CryptomatteExporter(SpecificExporter[bpy.types.CompositorNodeCryptomatte]): - def serialize(self): - data = self.export_all_simple_writable_properties_and_list( - [INPUTS, OUTPUTS, BL_IDNAME], - [PARENT], - ) - # https://github.com/Algebraic-UG/tree_clipper/issues/165 - data.pop(ADD) - data.pop(REMOVE) - return data +if (bpy.app.version[0] == 5 and bpy.app.version[1] >= 1) or bpy.app.version[0] > 5: + class FieldToListExporter(SpecificExporter[bpy.types.GeometryNodeFieldToList]): + def serialize(self): + return self.export_all_simple_writable_properties_and_list( + [INPUTS, OUTPUTS, BL_IDNAME, LIST_ITEMS], + [PARENT], + ) -class CryptomatteV2Exporter(SpecificExporter[bpy.types.CompositorNodeCryptomatteV2]): - def serialize(self): - data = self.export_all_simple_writable_properties_and_list( - [INPUTS, OUTPUTS, BL_IDNAME, ENTRIES], - [PARENT, IMAGE, SCENE], - ) - # https://github.com/Algebraic-UG/tree_clipper/issues/165 - data.pop(ADD) - data.pop(REMOVE) - return data + class FieldToListImporter(SpecificImporter[bpy.types.GeometryNodeFieldToList]): + def deserialize(self): + self.import_all_simple_writable_properties_and_list( + # ordering is important, the list_items implicitly create sockets + [LIST_ITEMS, ACTIVE_INDEX, INPUTS, OUTPUTS] + ) + _import_node_parent(self) + + class FieldToListItemExporter( + SpecificExporter[bpy.types.GeometryNodeFieldToListItem] + ): + def serialize(self): + return self.export_all_simple_writable_properties() + + class FieldToListItemsImporter( + SpecificImporter[bpy.types.GeometryNodeFieldToListItems] + ): + def deserialize(self): + self.getter().clear() + for item in self.serialization[ITEMS]: + socket_type = item[DATA][SOCKET_TYPE] + name = item[DATA][NAME] + self.getter().new(name=name, socket_type=socket_type) + + class CryptomatteExporter(SpecificExporter[bpy.types.CompositorNodeCryptomatte]): + def serialize(self): + data = self.export_all_simple_writable_properties_and_list( + [INPUTS, OUTPUTS, BL_IDNAME], + [PARENT], + ) + # https://github.com/Algebraic-UG/tree_clipper/issues/165 + data.pop(ADD) + data.pop(REMOVE) + return data + + class CryptomatteV2Exporter( + SpecificExporter[bpy.types.CompositorNodeCryptomatteV2] + ): + def serialize(self): + data = self.export_all_simple_writable_properties_and_list( + [INPUTS, OUTPUTS, BL_IDNAME, ENTRIES], + [PARENT, IMAGE, SCENE], + ) + # https://github.com/Algebraic-UG/tree_clipper/issues/165 + data.pop(ADD) + data.pop(REMOVE) + return data # now they are cooked and ready to use ~ bon appétit From 86df494d93c5c42f64221f40e4a7d6b2fe3d6fce Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:25:21 +0100 Subject: [PATCH 12/29] fix: missing parent import --- packages/tree_clipper/src/tree_clipper/specific_handlers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 9e7d3fe..da91f5b 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1416,6 +1416,7 @@ def deserialize(self) -> None: # ordering is important, the grid_items implicitly create sockets [GRID_ITEMS, ACTIVE_INDEX, INPUTS, OUTPUTS] ) + _import_node_parent(self) class FieldToGridItemExporter(SpecificExporter[bpy.types.GeometryNodeFieldToGridItem]): From e2b9f2bf61eeac47d0047814c50e841dd399b253 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:33:19 +0100 Subject: [PATCH 13/29] feat: add backward compat for String to Curves --- .../src/tree_clipper/specific_handlers.py | 89 +++++++++++++++++++ packages/tree_clipper/tests/conftest.py | 2 +- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index da91f5b..f80cb4a 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1536,6 +1536,95 @@ def serialize(self): data.pop(REMOVE) return data + class StringToCurvesImporter( + SpecificImporter[bpy.types.GeometryNodeStringToCurves] + ): + def deserialize(self): + # https://github.com/Algebraic-UG/tree_clipper/issues/167 + if self.importer.blender_version[:2] == [5, 0]: + # we have to skip the INPUTS/OUTPUTS collection importers because + # the number of sockets has changed between versions + self.import_all_simple_writable_properties_and_list([]) + _import_node_parent(self) + + # this might not be needed, but nice to have all the getters + self.only_create_getters([INPUTS, OUTPUTS]) + + # this will probably move somwhere else as soon as we need it twice + def map_socket(socket_name, input): + old_socket = next( + ( + old + for old in self.serialization[INPUTS if input else OUTPUTS][ + DATA + ][ITEMS] + if old[DATA][NAME] == socket_name + ), + None, + ) + assert old_socket is not None, f"Missing old socket {socket_name}" + if input: + self.register_getter( + getter=lambda: self.getter().inputs[socket_name], + serialization=old_socket, + from_root=self.from_root.add( + f"Mapped input '{socket_name}'" + ), + ) + else: + self.register_getter( + getter=lambda: self.getter().outputs[socket_name], + serialization=old_socket, + from_root=self.from_root.add( + f"Mapped output '{socket_name}'" + ), + ) + + # allow conneting the old links + map_socket("String", True) + map_socket("Size", True) + map_socket("Character Spacing", True) + map_socket("Word Spacing", True) + map_socket("Line Spacing", True) + map_socket("Text Box Width", True) + map_socket("Text Box Height", True) + + map_socket("Curve Instances", False) + map_socket("Line", False) + map_socket("Pivot Point", False) + + # map node attributes to default socket values + font = self.importer.getters.get(self.serialization[FONT]) + if font is not None: + font = font() + self.getter().inputs["Font"].default_value = font + + # these menu values need to be mapped from + # BOTTOM_BASELINE to Bottom Baseline + def map_menu_value(old: str): + return old.replace("_", " ").title() + + self.getter().inputs["Overflow"].default_value = map_menu_value( + self.serialization[OVERFLOW] + ) + self.getter().inputs["Align X"].default_value = map_menu_value( + self.serialization[ALIGN_X] + ) + self.getter().inputs["Align Y"].default_value = map_menu_value( + self.serialization[ALIGN_Y] + ) + self.getter().inputs["Pivot Point"].default_value = map_menu_value( + self.serialization[PIVOT_MODE] + ) + + return + + self.import_all_simple_writable_properties_and_list( + # ordering is important, the list_items implicitly create sockets + [INPUTS, OUTPUTS] + ) + _import_node_parent(self) + # now they are cooked and ready to use ~ bon appétit BUILT_IN_EXPORTER = _BUILT_IN_EXPORTER diff --git a/packages/tree_clipper/tests/conftest.py b/packages/tree_clipper/tests/conftest.py index d604672..a9604c9 100644 --- a/packages/tree_clipper/tests/conftest.py +++ b/packages/tree_clipper/tests/conftest.py @@ -23,7 +23,7 @@ def pytest_generate_tests(metafunc): ) if ( - metafunc == test_all_nodes + metafunc.function == test_all_nodes or metafunc.function.__name__ == test_all_nodes.__name__ ): metafunc.parametrize("node_type", node_types) From 281e62dcb38548bd66024fe3d710aa5e2f348555 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:41:14 +0100 Subject: [PATCH 14/29] refactor --- .../src/tree_clipper/specific_handlers.py | 92 ++++++++++--------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index f80cb4a..7ed4f17 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -127,6 +127,41 @@ def deferred(): specific_importer.importer.defer_after_nodes_before_links.append(deferred) +# This is needed for manually mapping sockets for backwards compatibility +def map_socket(*, specific_importer: SpecificImporter, socket_name: str, input: bool): + old_socket = next( + ( + old + for old in specific_importer.serialization[INPUTS if input else OUTPUTS][ + DATA + ][ITEMS] + if old[DATA][NAME] == socket_name + ), + None, + ) + assert old_socket is not None, f"Missing old socket {socket_name}" + if input: + specific_importer.register_getter( + getter=lambda: specific_importer.getter().inputs[socket_name], + serialization=old_socket, + from_root=specific_importer.from_root.add(f"Mapped input '{socket_name}'"), + ) + else: + specific_importer.register_getter( + getter=lambda: specific_importer.getter().outputs[socket_name], + serialization=old_socket, + from_root=specific_importer.from_root.add(f"Mapped output '{socket_name}'"), + ) + + +def map_socket_input(*, importer: SpecificImporter, name: str): + map_socket(specific_importer=importer, socket_name=name, input=True) + + +def map_socket_output(*, importer: SpecificImporter, name: str): + map_socket(specific_importer=importer, socket_name=name, input=False) + + # Possible socket data types: https://docs.blender.org/api/current/bpy_types_enum_items/node_socket_data_type_items.html#rna-enum-node-socket-data-type-items # Only a subset of those are supported on the capture attribute node: FLOAT, INT, VECTOR, RGBA, BOOLEAN, QUATERNION, MATRIX # TODO this is incomplete? @@ -1550,48 +1585,18 @@ def deserialize(self): # this might not be needed, but nice to have all the getters self.only_create_getters([INPUTS, OUTPUTS]) - # this will probably move somwhere else as soon as we need it twice - def map_socket(socket_name, input): - old_socket = next( - ( - old - for old in self.serialization[INPUTS if input else OUTPUTS][ - DATA - ][ITEMS] - if old[DATA][NAME] == socket_name - ), - None, - ) - assert old_socket is not None, f"Missing old socket {socket_name}" - if input: - self.register_getter( - getter=lambda: self.getter().inputs[socket_name], - serialization=old_socket, - from_root=self.from_root.add( - f"Mapped input '{socket_name}'" - ), - ) - else: - self.register_getter( - getter=lambda: self.getter().outputs[socket_name], - serialization=old_socket, - from_root=self.from_root.add( - f"Mapped output '{socket_name}'" - ), - ) - # allow conneting the old links - map_socket("String", True) - map_socket("Size", True) - map_socket("Character Spacing", True) - map_socket("Word Spacing", True) - map_socket("Line Spacing", True) - map_socket("Text Box Width", True) - map_socket("Text Box Height", True) - - map_socket("Curve Instances", False) - map_socket("Line", False) - map_socket("Pivot Point", False) + map_socket_input(importer=self, name="String") + map_socket_input(importer=self, name="Size") + map_socket_input(importer=self, name="Character Spacing") + map_socket_input(importer=self, name="Word Spacing") + map_socket_input(importer=self, name="Line Spacing") + map_socket_input(importer=self, name="Text Box Width") + map_socket_input(importer=self, name="Text Box Height") + + map_socket_output(importer=self, name="Curve Instances") + map_socket_output(importer=self, name="Line") + map_socket_output(importer=self, name="Pivot Point") # map node attributes to default socket values font = self.importer.getters.get(self.serialization[FONT]) @@ -1619,10 +1624,7 @@ def map_menu_value(old: str): return - self.import_all_simple_writable_properties_and_list( - # ordering is important, the list_items implicitly create sockets - [INPUTS, OUTPUTS] - ) + self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) _import_node_parent(self) From 954ec7948267a38eb6b5677107dc5143024df0fc Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:48:04 +0100 Subject: [PATCH 15/29] feat: add backward compat for UV Unwrap --- .../src/tree_clipper/specific_handlers.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 7ed4f17..976fcce 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1627,6 +1627,25 @@ def map_menu_value(old: str): self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) _import_node_parent(self) + class UVUnwrapImporter(SpecificImporter[bpy.types.GeometryNodeUVUnwrap]): + def deserialize(self): + # https://github.com/Algebraic-UG/tree_clipper/issues/168 + if self.importer.blender_version[:2] == [5, 0]: + self.import_all_simple_writable_properties_and_list([OUTPUTS]) + # this might not be needed, but nice to have all the getters + self.only_create_getters([INPUTS]) + + map_socket_input(importer=self, name="Selection") + map_socket_input(importer=self, name="Seam") + map_socket_input(importer=self, name="Margin") + map_socket_input(importer=self, name="Fill Holes") + map_socket_input(importer=self, name="Method") + + return + + self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) + _import_node_parent(self) + # now they are cooked and ready to use ~ bon appétit BUILT_IN_EXPORTER = _BUILT_IN_EXPORTER From 83215e3b538fc7c4eeadf8cb414f89b8b1dde307 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:52:52 +0100 Subject: [PATCH 16/29] feat: add backward compat for Pack UV Islands --- .../src/tree_clipper/specific_handlers.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 976fcce..d883b72 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1646,6 +1646,25 @@ def deserialize(self): self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) _import_node_parent(self) + class PackUVIslandsImporter(SpecificImporter[bpy.types.GeometryNodeUVPackIslands]): + def deserialize(self): + # https://github.com/Algebraic-UG/tree_clipper/issues/169 + if self.importer.blender_version[:2] == [5, 0]: + self.import_all_simple_writable_properties_and_list([OUTPUTS]) + # this might not be needed, but nice to have all the getters + self.only_create_getters([INPUTS]) + + map_socket_input(importer=self, name="UV") + map_socket_input(importer=self, name="Selection") + map_socket_input(importer=self, name="Margin") + map_socket_input(importer=self, name="Rotate") + map_socket_input(importer=self, name="Method") + + return + + self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) + _import_node_parent(self) + # now they are cooked and ready to use ~ bon appétit BUILT_IN_EXPORTER = _BUILT_IN_EXPORTER From ae6504d9e206c44f84dea7c903227e92da30b3a2 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 15:54:55 +0100 Subject: [PATCH 17/29] fix: actually import the sockets' default_value --- packages/tree_clipper/src/tree_clipper/specific_handlers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index d883b72..a3db81a 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -141,13 +141,13 @@ def map_socket(*, specific_importer: SpecificImporter, socket_name: str, input: ) assert old_socket is not None, f"Missing old socket {socket_name}" if input: - specific_importer.register_getter( + specific_importer.importer._import_obj( getter=lambda: specific_importer.getter().inputs[socket_name], serialization=old_socket, from_root=specific_importer.from_root.add(f"Mapped input '{socket_name}'"), ) else: - specific_importer.register_getter( + specific_importer.importer._import_obj( getter=lambda: specific_importer.getter().outputs[socket_name], serialization=old_socket, from_root=specific_importer.from_root.add(f"Mapped output '{socket_name}'"), From fc2f073f29988a263cdadffc2a8e65fa5ee4bd74 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:49:37 +0100 Subject: [PATCH 18/29] chore: make default hint available for tests --- packages/tree_clipper/src/tree_clipper/common.py | 1 + packages/tree_clipper/tests/util.py | 1 + .../src/tree_clipper_addon/operators_export.py | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/tree_clipper/src/tree_clipper/common.py b/packages/tree_clipper/src/tree_clipper/common.py index 0c01297..b8f0ea5 100644 --- a/packages/tree_clipper/src/tree_clipper/common.py +++ b/packages/tree_clipper/src/tree_clipper/common.py @@ -148,3 +148,4 @@ def most_specific_type_handled( EXTERNAL_SERIALIZATION = dict[str, int | str | None] DEFAULT_FILE = str(Path(tempfile.gettempdir()) / "default.json") +DEFAULT_HINT = "Hint for Import" diff --git a/packages/tree_clipper/tests/util.py b/packages/tree_clipper/tests/util.py index c95e964..86df310 100644 --- a/packages/tree_clipper/tests/util.py +++ b/packages/tree_clipper/tests/util.py @@ -12,6 +12,7 @@ MATERIAL_NAME, TREES, NAME, + DEFAULT_HINT, ) from tree_clipper.id_data_getter import get_data_block_from_id_name from tree_clipper.export_nodes import ExportIntermediate, ExportParameters diff --git a/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py b/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py index b1ac01c..c602b0d 100644 --- a/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py +++ b/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py @@ -1,3 +1,4 @@ +from tree_clipper.common import DEFAULT_HINT import bpy from typing import Any, TYPE_CHECKING @@ -140,7 +141,7 @@ def draw_item( class Tree_Clipper_External_Export_Item(bpy.types.PropertyGroup): external_id: bpy.props.IntProperty() # type: ignore - description: bpy.props.StringProperty(name="", default="Hint for Import") # type: ignore + description: bpy.props.StringProperty(name="", default=DEFAULT_HINT) # type: ignore skip: bpy.props.BoolProperty(name="Hide in Import", default=False) # type: ignore From 947638a2dc6de61924665fa88fbb5d76c9c2ea4c Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:49:54 +0100 Subject: [PATCH 19/29] fix: allow passing None as external ref --- packages/tree_clipper/src/tree_clipper/import_nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tree_clipper/src/tree_clipper/import_nodes.py b/packages/tree_clipper/src/tree_clipper/import_nodes.py index 8bbef83..007c86d 100644 --- a/packages/tree_clipper/src/tree_clipper/import_nodes.py +++ b/packages/tree_clipper/src/tree_clipper/import_nodes.py @@ -595,7 +595,7 @@ def get_external(self) -> dict[str, EXTERNAL_SERIALIZATION]: def set_external( self, - ids_and_references: Iterator[Tuple[int, bpy.types.ID]], + ids_and_references: Iterator[Tuple[int, bpy.types.ID | None]], ) -> None: for external_id, external_item in ids_and_references: scene_id = self.get_external()[str(external_id)][EXTERNAL_SCENE_ID] From 68223b25a0f30cc8fb9952a2c7befabfd272fcce Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:50:44 +0100 Subject: [PATCH 20/29] fix: make external items test work for 5.0 again --- packages/tree_clipper/tests/test_external_items.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/tree_clipper/tests/test_external_items.py b/packages/tree_clipper/tests/test_external_items.py index a0b6bd4..041e956 100644 --- a/packages/tree_clipper/tests/test_external_items.py +++ b/packages/tree_clipper/tests/test_external_items.py @@ -57,7 +57,10 @@ def _create_setup(): node.text = _EXTERNAL_ITEM_MAKER["Text"]() # ty: ignore[invalid-assignment, unresolved-attribute] node = nodes.new("GeometryNodeStringToCurves") - node.inputs["Font"].default_value = _EXTERNAL_ITEM_MAKER["VectorFont"]() # ty: ignore[invalid-assignment, unresolved-attribute] + if bpy.app.version[0] == 5 and bpy.app.version[1] == 0: + node.font = _EXTERNAL_ITEM_MAKER["VectorFont"]() # ty: ignore[invalid-assignment, unresolved-attribute] + elif bpy.app.version[0] == 5 and bpy.app.version[1] >= 1: + node.inputs["Font"].default_value = _EXTERNAL_ITEM_MAKER["VectorFont"]() # ty: ignore[invalid-assignment, unresolved-attribute] return name @@ -127,7 +130,10 @@ def _check_after_import(name: str): assert tree.nodes["Material"].material is not None # ty: ignore[unresolved-attribute] assert tree.nodes["Object"].object is not None # ty: ignore[unresolved-attribute] assert tree.nodes["Collection"].collection is not None # ty: ignore[unresolved-attribute] - assert tree.nodes["String to Curves"].inputs["Font"].default_value is not None # ty: ignore[unresolved-attribute] + if bpy.app.version[0] == 5 and bpy.app.version[1] == 0: + assert tree.nodes["String to Curves"].font is not None # ty: ignore[unresolved-attribute] + elif bpy.app.version[0] == 5 and bpy.app.version[1] >= 1: + assert tree.nodes["String to Curves"].inputs["Font"].default_value is not None # ty: ignore[unresolved-attribute] assert len(tree.nodes) == 7, "if this fails the lines above must also change" From b2a36359dec98f566a29d2336c72fc443b9e21eb Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:52:00 +0100 Subject: [PATCH 21/29] feat: add some tests for the backwards compatibility --- .../5_0_pack_uv_islands.json | 3 + .../5_0_string_to_curves.json | 3 + .../blender_5_0_to_5_1/5_0_uv_unwrap.json | 3 + .../5_1_pack_uv_islands.json | 3 + .../5_1_string_to_curves.json | 3 + .../blender_5_0_to_5_1/5_1_uv_unwrap.json | 3 + .../tree_clipper/tests/test_5_0_to_5_1.py | 47 ++++++++++++++ packages/tree_clipper/tests/util.py | 62 +++++++++++++++++++ 8 files changed, 127 insertions(+) create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_pack_uv_islands.json create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_string_to_curves.json create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_uv_unwrap.json create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_pack_uv_islands.json create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_string_to_curves.json create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_uv_unwrap.json create mode 100644 packages/tree_clipper/tests/test_5_0_to_5_1.py diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_pack_uv_islands.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_pack_uv_islands.json new file mode 100644 index 0000000..d7a9f59 --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_pack_uv_islands.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad59d33b95a1c785aa37cca382f0ee82da9b09b19155de6ec40cfe2ba9e602c4 +size 37706 diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_string_to_curves.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_string_to_curves.json new file mode 100644 index 0000000..aaeca3b --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_string_to_curves.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:262715b4f34c64f97fa71c962d7666736439fa4c2c7f68c1cdce6aa1cf60b5ca +size 55949 diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_uv_unwrap.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_uv_unwrap.json new file mode 100644 index 0000000..35b283b --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_uv_unwrap.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:623eab321a23689e8a88c2fcc6280cbcf603a306a633ba3549ab9a407ce69644 +size 36870 diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_pack_uv_islands.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_pack_uv_islands.json new file mode 100644 index 0000000..3921d80 --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_pack_uv_islands.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7002b0a9e18163ba5b31c0a1f44e919e5dadc8974d8e8a944a8cfe747beb8018 +size 40714 diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_string_to_curves.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_string_to_curves.json new file mode 100644 index 0000000..e6eaf6a --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_string_to_curves.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e00cb74799d44223d2d4f40221e49bc21e8b97aff75cd23a6b8eda0a54b173c8 +size 62848 diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_uv_unwrap.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_uv_unwrap.json new file mode 100644 index 0000000..8eb8ba8 --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_uv_unwrap.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50b6bfab86b8ab2121ae9ba073e371f10266a175d614eae05f939de529ac31b5 +size 39504 diff --git a/packages/tree_clipper/tests/test_5_0_to_5_1.py b/packages/tree_clipper/tests/test_5_0_to_5_1.py new file mode 100644 index 0000000..6ac3712 --- /dev/null +++ b/packages/tree_clipper/tests/test_5_0_to_5_1.py @@ -0,0 +1,47 @@ +import bpy + +from pathlib import Path +import deepdiff +import json + +from .util import ( + save_failed, + BACKWARDS_COMPATIBILITY_FILES_DIR, + import_and_check_export, +) + +_DIR = BACKWARDS_COMPATIBILITY_FILES_DIR / "blender_5_0_to_5_1" +if bpy.app.version[0] == 5 and bpy.app.version[1] == 1: + + def test_backward_compatibility_string_to_curves(): + try: + import_and_check_export( + import_file=_DIR / "5_0_string_to_curves.json", + export_file=_DIR / "5_1_string_to_curves.json", + ) + except: + # store in case of failure for easy debugging + save_failed(f"{test_backward_compatibility_string_to_curves.__name__}") + raise + + def test_backward_compatibility_uv_unwrap(): + try: + import_and_check_export( + import_file=_DIR / "5_0_uv_unwrap.json", + export_file=_DIR / "5_1_uv_unwrap.json", + ) + except: + # store in case of failure for easy debugging + save_failed(f"{test_backward_compatibility_uv_unwrap.__name__}") + raise + + def test_backward_compatibility_pack_uv_islands(): + try: + import_and_check_export( + import_file=_DIR / "5_0_pack_uv_islands.json", + export_file=_DIR / "5_1_pack_uv_islands.json", + ) + except: + # store in case of failure for easy debugging + save_failed(f"{test_backward_compatibility_pack_uv_islands.__name__}") + raise diff --git a/packages/tree_clipper/tests/util.py b/packages/tree_clipper/tests/util.py index 86df310..7407c1e 100644 --- a/packages/tree_clipper/tests/util.py +++ b/packages/tree_clipper/tests/util.py @@ -193,7 +193,69 @@ def make_everything_local(): material.make_local(clear_liboverride=True) +def import_and_check_export( + *, + import_file: Path, + export_file: Path, + debug_prints: bool = False, +): + import_intermediate = ImportIntermediate(file_path=import_file) + + import_intermediate.set_external( + (int(external_id), None) + for external_id, _ in import_intermediate.get_external().items() + ) + + import_report = import_intermediate.import_all( + parameters=ImportParameters( + specific_handlers=BUILT_IN_IMPORTER, + debug_prints=debug_prints, + ) + ) + + assert len(import_report.warnings) == 0 + + if MATERIAL_NAME in import_intermediate.data: + is_material = True + name = import_intermediate.data[MATERIAL_NAME] + else: + is_material = False + name = import_report.last_getter().name # ty:ignore[unresolved-attribute, call-non-callable] + + export_intermediate = ExportIntermediate( + parameters=ExportParameters( + is_material=is_material, + name=name, + specific_handlers=BUILT_IN_EXPORTER, + export_sub_trees=True, + debug_prints=debug_prints, + write_from_roots=False, + ) + ) + + while export_intermediate.step(): + pass + + export_intermediate.set_external( + (external_id, DEFAULT_HINT) + for external_id, external_item in export_intermediate.get_external().items() + ) + + string = export_intermediate.export_to_str(compress=False, json_indent=4) + + with open(export_file, "r") as f: + expected_string = f.read() + + diff = deepdiff.DeepDiff( + json.loads(expected_string), json.loads(string), math_epsilon=0.01 + ) + + print(diff.pretty()) + assert diff == {} + + BINARY_BLEND_FILES_DIR = Path(__file__).parent / "binary_blend_files" +BACKWARDS_COMPATIBILITY_FILES_DIR = Path(__file__).parent / "backwards_compatibility" def all_subclasses(cls): From 2d8dba900f102424e42bcdf56599a77cfaa7c3e3 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:53:30 +0100 Subject: [PATCH 22/29] tidy: remove some superfluous ignores --- packages/tree_clipper/tests/conftest.py | 2 +- packages/tree_clipper/tests/test_5_0_to_5_1.py | 1 - packages/tree_clipper/tests/util.py | 10 +++------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/tree_clipper/tests/conftest.py b/packages/tree_clipper/tests/conftest.py index a9604c9..142f49c 100644 --- a/packages/tree_clipper/tests/conftest.py +++ b/packages/tree_clipper/tests/conftest.py @@ -1,5 +1,5 @@ import bpy -import _rna_info as rna_info # ty:ignore[unresolved-import] +import _rna_info as rna_info import pytest diff --git a/packages/tree_clipper/tests/test_5_0_to_5_1.py b/packages/tree_clipper/tests/test_5_0_to_5_1.py index 6ac3712..f829d32 100644 --- a/packages/tree_clipper/tests/test_5_0_to_5_1.py +++ b/packages/tree_clipper/tests/test_5_0_to_5_1.py @@ -1,7 +1,6 @@ import bpy from pathlib import Path -import deepdiff import json from .util import ( diff --git a/packages/tree_clipper/tests/util.py b/packages/tree_clipper/tests/util.py index 7407c1e..93f5ec1 100644 --- a/packages/tree_clipper/tests/util.py +++ b/packages/tree_clipper/tests/util.py @@ -22,17 +22,13 @@ def make_test_object() -> bpy.types.Object: obj = bpy.data.objects.new(name="test", object_data=None) - bpy.context.scene.collection.objects.link( # ty :ignore[possibly-missing-attribute] - obj - ) + bpy.context.scene.collection.objects.link(obj) return obj def make_test_collection() -> bpy.types.Collection: collection = bpy.data.collections.new(name="test") - bpy.context.scene.collection.children.link( # ty :ignore[possibly-missing-attribute] - collection - ) + bpy.context.scene.collection.children.link(collection) return collection @@ -220,7 +216,7 @@ def import_and_check_export( name = import_intermediate.data[MATERIAL_NAME] else: is_material = False - name = import_report.last_getter().name # ty:ignore[unresolved-attribute, call-non-callable] + name = import_report.last_getter().name export_intermediate = ExportIntermediate( parameters=ExportParameters( From c500594e95465801880d0e082194003bbe32073a Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:55:10 +0100 Subject: [PATCH 23/29] fix: remove this weirdness The issue that this was supposed to fix was just caused by some stale pytest cache. --- packages/tree_clipper/tests/conftest.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/tree_clipper/tests/conftest.py b/packages/tree_clipper/tests/conftest.py index 142f49c..401dadc 100644 --- a/packages/tree_clipper/tests/conftest.py +++ b/packages/tree_clipper/tests/conftest.py @@ -22,8 +22,5 @@ def pytest_generate_tests(metafunc): cls for cls in all_subclasses(bpy.types.Node) if len(all_subclasses(cls)) == 0 ) - if ( - metafunc.function == test_all_nodes - or metafunc.function.__name__ == test_all_nodes.__name__ - ): + if metafunc.function == test_all_nodes: metafunc.parametrize("node_type", node_types) From b02868ee31b271605b44aa776babf90706342a0a Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 16:58:15 +0100 Subject: [PATCH 24/29] tidy: ruff --- packages/tree_clipper/src/tree_clipper/specific_handlers.py | 1 - packages/tree_clipper/tests/test_5_0_to_5_1.py | 3 --- packages/tree_clipper/tests/util.py | 6 +++--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index a3db81a..4a6f4a2 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -7,7 +7,6 @@ _BUILT_IN_IMPORTER, SpecificExporter, SpecificImporter, - default_serializer, ) from .common import ( diff --git a/packages/tree_clipper/tests/test_5_0_to_5_1.py b/packages/tree_clipper/tests/test_5_0_to_5_1.py index f829d32..a82c227 100644 --- a/packages/tree_clipper/tests/test_5_0_to_5_1.py +++ b/packages/tree_clipper/tests/test_5_0_to_5_1.py @@ -1,8 +1,5 @@ import bpy -from pathlib import Path -import json - from .util import ( save_failed, BACKWARDS_COMPATIBILITY_FILES_DIR, diff --git a/packages/tree_clipper/tests/util.py b/packages/tree_clipper/tests/util.py index 93f5ec1..258f633 100644 --- a/packages/tree_clipper/tests/util.py +++ b/packages/tree_clipper/tests/util.py @@ -137,7 +137,7 @@ def export_to_string(name: str) -> str: export_intermediate.set_external( ( external_id, - external_item.pointed_to_by.get_pointee().name, # ty: ignore[possibly-missing-attribute] + external_item.pointed_to_by.get_pointee().name, ) for external_id, external_item in export_intermediate.get_external().items() ) @@ -156,7 +156,7 @@ def get_same_external_item(external_item: EXTERNAL_SERIALIZATION): assert isinstance(fixed_type_name, str) data_block = get_data_block_from_id_name(fixed_type_name) name = external_item[EXTERNAL_DESCRIPTION] - return data_block[name] # ty: ignore[invalid-argument-type] + return data_block[name] import_intermediate.set_external( (int(external_id), get_same_external_item(external_item)) @@ -171,7 +171,7 @@ def get_same_external_item(external_item: EXTERNAL_SERIALIZATION): ) after = export_to_string( - import_report.rename_material[1] # ty:ignore[non-subscriptable] + import_report.rename_material[1] # ty:ignore[not-subscriptable] if is_material else import_report.renames_node_group[original_name] ) From af68889589a165d43b497c90c384470ab540ad50 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 17:07:46 +0100 Subject: [PATCH 25/29] fix: vendorize task --- .vscode/tasks.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ea0728b..2f64269 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,6 +7,7 @@ "command": "uv", "args": [ "run", + "--prerelease=allow", "python-vendorize", ], "options": { From a7e011d38ff43f4a243bb25f844ab25aa094a623 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 17:08:02 +0100 Subject: [PATCH 26/29] fix: import in addon --- .../src/tree_clipper_addon/operators_export.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py b/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py index c602b0d..cf97589 100644 --- a/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py +++ b/packages/tree_clipper_addon/src/tree_clipper_addon/operators_export.py @@ -1,4 +1,3 @@ -from tree_clipper.common import DEFAULT_HINT import bpy from typing import Any, TYPE_CHECKING @@ -9,7 +8,7 @@ from pathlib import Path -from ._vendor.tree_clipper.common import DEFAULT_FILE +from ._vendor.tree_clipper.common import DEFAULT_FILE, DEFAULT_HINT from ._vendor.tree_clipper.specific_handlers import ( BUILT_IN_EXPORTER, From 54913f2b6b6f2249555f9bf700fd6a366b24ecc5 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Wed, 25 Feb 2026 17:55:27 +0100 Subject: [PATCH 27/29] feat: add backward compat for Fill Curve --- .../src/tree_clipper/specific_handlers.py | 17 +++++++++++++++++ .../blender_5_0_to_5_1/5_0_fill_curve.json | 3 +++ .../blender_5_0_to_5_1/5_1_fill_curve.json | 3 +++ packages/tree_clipper/tests/test_5_0_to_5_1.py | 11 +++++++++++ 4 files changed, 34 insertions(+) create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_fill_curve.json create mode 100644 packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_fill_curve.json diff --git a/packages/tree_clipper/src/tree_clipper/specific_handlers.py b/packages/tree_clipper/src/tree_clipper/specific_handlers.py index 4a6f4a2..bc6f050 100644 --- a/packages/tree_clipper/src/tree_clipper/specific_handlers.py +++ b/packages/tree_clipper/src/tree_clipper/specific_handlers.py @@ -1664,6 +1664,23 @@ def deserialize(self): self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) _import_node_parent(self) + class FillCurveImporter(SpecificImporter[bpy.types.GeometryNodeFillCurve]): + def deserialize(self): + # https://github.com/Algebraic-UG/tree_clipper/issues/170 + if self.importer.blender_version[:2] == [5, 0]: + self.import_all_simple_writable_properties_and_list([OUTPUTS]) + # this might not be needed, but nice to have all the getters + self.only_create_getters([INPUTS]) + + map_socket_input(importer=self, name="Curve") + map_socket_input(importer=self, name="Group ID") + map_socket_input(importer=self, name="Mode") + + return + + self.import_all_simple_writable_properties_and_list([INPUTS, OUTPUTS]) + _import_node_parent(self) + # now they are cooked and ready to use ~ bon appétit BUILT_IN_EXPORTER = _BUILT_IN_EXPORTER diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_fill_curve.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_fill_curve.json new file mode 100644 index 0000000..0cc9b0d --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_0_fill_curve.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20140793b5292034c578ba4c08f1c8b1fb6694a3eee098253679afe702d36692 +size 27014 diff --git a/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_fill_curve.json b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_fill_curve.json new file mode 100644 index 0000000..a769a86 --- /dev/null +++ b/packages/tree_clipper/tests/backwards_compatibility/blender_5_0_to_5_1/5_1_fill_curve.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df3e56870e000b5f8f4a86d23d4d8893d65effe670c3040fb6bd400348f1a05a +size 28420 diff --git a/packages/tree_clipper/tests/test_5_0_to_5_1.py b/packages/tree_clipper/tests/test_5_0_to_5_1.py index a82c227..f61aa4e 100644 --- a/packages/tree_clipper/tests/test_5_0_to_5_1.py +++ b/packages/tree_clipper/tests/test_5_0_to_5_1.py @@ -41,3 +41,14 @@ def test_backward_compatibility_pack_uv_islands(): # store in case of failure for easy debugging save_failed(f"{test_backward_compatibility_pack_uv_islands.__name__}") raise + + def test_backward_compatibility_fill_curve(): + try: + import_and_check_export( + import_file=_DIR / "5_0_fill_curve.json", + export_file=_DIR / "5_1_fill_curve.json", + ) + except: + # store in case of failure for easy debugging + save_failed(f"{test_backward_compatibility_fill_curve.__name__}") + raise From 08603fc40d376fc7c6f47a2e942b0c51efe00614 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Thu, 26 Feb 2026 00:00:47 +0100 Subject: [PATCH 28/29] feat: add simple import test for old exports --- packages/tree_clipper/tests/conftest.py | 10 +++++++++- .../tests/test_backwards_compatibility.py | 14 ++++++++++++++ packages/tree_clipper/tests/util.py | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 packages/tree_clipper/tests/test_backwards_compatibility.py diff --git a/packages/tree_clipper/tests/conftest.py b/packages/tree_clipper/tests/conftest.py index 401dadc..3e4cc6e 100644 --- a/packages/tree_clipper/tests/conftest.py +++ b/packages/tree_clipper/tests/conftest.py @@ -3,8 +3,9 @@ import pytest -from .util import all_subclasses +from .util import all_subclasses, BACKWARDS_COMPATIBILITY_FILES_DIR from .test_all_nodes import test_all_nodes +from .test_backwards_compatibility import test_backwards_compatibility_to_0_1_1 @pytest.fixture(autouse=True) @@ -24,3 +25,10 @@ def pytest_generate_tests(metafunc): if metafunc.function == test_all_nodes: metafunc.parametrize("node_type", node_types) + + exports_from_0_1_1 = [ + str(p) for p in (BACKWARDS_COMPATIBILITY_FILES_DIR / "v0.1.1").rglob("*.json") + ] + + if metafunc.function == test_backwards_compatibility_to_0_1_1: + metafunc.parametrize("file", exports_from_0_1_1) diff --git a/packages/tree_clipper/tests/test_backwards_compatibility.py b/packages/tree_clipper/tests/test_backwards_compatibility.py new file mode 100644 index 0000000..24bdb3f --- /dev/null +++ b/packages/tree_clipper/tests/test_backwards_compatibility.py @@ -0,0 +1,14 @@ +from pathlib import Path + +from .util import import_and_check + + +def test_backwards_compatibility_to_0_1_1(file: str): + file_path = Path(file) + + # once this is done, we can remove this return + # https://github.com/Algebraic-UG/tree_clipper/issues/171 + if file_path.parent.stem == "CompositorNodeTree": + return + + import_and_check(import_file=file_path) diff --git a/packages/tree_clipper/tests/util.py b/packages/tree_clipper/tests/util.py index 258f633..92aa044 100644 --- a/packages/tree_clipper/tests/util.py +++ b/packages/tree_clipper/tests/util.py @@ -189,6 +189,24 @@ def make_everything_local(): material.make_local(clear_liboverride=True) +def import_and_check(*, import_file: Path, debug_prints: bool = False): + import_intermediate = ImportIntermediate(file_path=import_file) + + import_intermediate.set_external( + (int(external_id), None) + for external_id, _ in import_intermediate.get_external().items() + ) + + import_report = import_intermediate.import_all( + parameters=ImportParameters( + specific_handlers=BUILT_IN_IMPORTER, + debug_prints=debug_prints, + ) + ) + + assert len(import_report.warnings) == 0 + + def import_and_check_export( *, import_file: Path, From c30493d668bd661bbf2d3d8626b1deb8899991f7 Mon Sep 17 00:00:00 2001 From: Vollkornaffe Date: Thu, 26 Feb 2026 00:05:05 +0100 Subject: [PATCH 29/29] Revert "accept bpy version override in CI" This reverts commit 7c2d16b0a887a5fd7480571e3fe3e0db0716ac20. --- .github/workflows/test.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cb3c358..f89510a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,11 +6,6 @@ on: pull_request: branches: ["*"] workflow_dispatch: - inputs: - bpy_spec: - description: 'Override bpy requirement (e.g. "bpy==5.1.0" or "bpy>=5.0,<5.2")' - required: false - default: "" # Cancel in-progress runs when a new workflow with the same group is triggered concurrency: @@ -49,10 +44,6 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v5 - - name: Lock with bpy override - if: ${{ github.event.inputs.bpy_spec != '' }} - run: uv lock --upgrade-package "${{ github.event.inputs.bpy_spec }}" - - name: Install tree_clipper run: uv sync --all-extras