From 44b2c79ae8071b66d4c6e603ea874bac95fb07dc269370672eaab43e48baddc9 Mon Sep 17 00:00:00 2001 From: Steve Kowalik Date: Mon, 17 Nov 2025 02:11:25 +0000 Subject: [PATCH] - Update to 25.3.0: * Potentially breaking: Abstract sets are now structured into frozensets. * Python 3.14 is now supported and part of the test matrix. * Fix unstructuring NewTypes with the {class}BaseConverter. * Make some Hypothesis tests more robust. * {func}cattrs.strategies.include_subclasses now works with generic parent classes and the tagged union strategy. * Potentially breaking: Sequences are now structured into tuples. * Add a use_alias parameter to cattrs.Converter. * The union passthrough strategy now by default accepts ints for unions that contain floats but not ints, when configured to be able to handle both ints and floats. This more closely matches the current typing behavior. * Fix unstructuring of generic classes with stringified annotations. * The default disambiguation hook factory is now only enabled for converters with unstructure_strat=AS_DICT (the default). * Switch to uv and just in lieu of PDM, tox and Make. * Fixed AttributeError: no attribute '__parameters__' while structuring attrs classes that inherit from parametrized generic aliases from collections.abc. * Potentially breaking: The converters raise StructureHandlerNotFoundError more eagerly (on hook creation, instead of on hook use). This helps surfacing problems with missing hooks sooner. * typing.Self is now supported in attrs classes, dataclasses, TypedDicts and the dict NamedTuple factories. See typing.Self for details. * PEP 695 type aliases can now be used with BaseConverter.register_structure_hook and BaseConverter.register_unstructure_hook. Previously, they required the use of BaseConverter.register_structure_hook_func. * Some defaultdicts are now supported by default, and OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-cattrs?expand=0&rev=15 --- .gitattributes | 23 ++ .gitignore | 1 + cattrs-24.1.3.tar.gz | 3 + cattrs-25.3.0.tar.gz | 3 + fix-test-no-nans.patch | 682 ++++++++++++++++++++++++++++++++++++++ python-cattrs.changes | 274 +++++++++++++++ python-cattrs.spec | 88 +++++ support-python-3.13.patch | 438 ++++++++++++++++++++++++ 8 files changed, 1512 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 cattrs-24.1.3.tar.gz create mode 100644 cattrs-25.3.0.tar.gz create mode 100644 fix-test-no-nans.patch create mode 100644 python-cattrs.changes create mode 100644 python-cattrs.spec create mode 100644 support-python-3.13.patch diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/cattrs-24.1.3.tar.gz b/cattrs-24.1.3.tar.gz new file mode 100644 index 0000000..42a27d6 --- /dev/null +++ b/cattrs-24.1.3.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:981a6ef05875b5bb0c7fb68885546186d306f10f0f6718fe9b96c226e68821ff +size 426684 diff --git a/cattrs-25.3.0.tar.gz b/cattrs-25.3.0.tar.gz new file mode 100644 index 0000000..22d0e8b --- /dev/null +++ b/cattrs-25.3.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ac88d9e5eda10436c4517e390a4142d88638fe682c436c93db7ce4a277b884a +size 509321 diff --git a/fix-test-no-nans.patch b/fix-test-no-nans.patch new file mode 100644 index 0000000..5a2a267 --- /dev/null +++ b/fix-test-no-nans.patch @@ -0,0 +1,682 @@ +From 96ed9a1c972814c379f9ea8faa3413aacd4ce6cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= +Date: Thu, 29 Aug 2024 18:40:35 +0200 +Subject: [PATCH] Stop generating nan values in tests to work with latest attrs + (#576) + +--- + pdm.lock | 172 ++++++++++++++++++++---------------- + pyproject.toml | 8 +- + tests/test_baseconverter.py | 18 ++-- + tests/test_converter.py | 38 ++++---- + tests/test_gen_dict.py | 10 ++- + tests/typed.py | 51 ++++++++--- + tests/untyped.py | 2 +- + 7 files changed, 176 insertions(+), 123 deletions(-) + +Index: cattrs-24.1.2/pdm.lock +=================================================================== +--- cattrs-24.1.2.orig/pdm.lock ++++ cattrs-24.1.2/pdm.lock +@@ -4,10 +4,10 @@ + [metadata] + groups = ["default", "bench", "bson", "cbor2", "docs", "lint", "msgpack", "msgspec", "orjson", "pyyaml", "test", "tomlkit", "ujson"] + strategy = ["cross_platform"] +-lock_version = "4.4.1" +-content_hash = "sha256:80497e8d5b756fc000f8a8b58b2ae6e6501168628e264daf7de6049fa45b096e" ++lock_version = "4.5.0" ++content_hash = "sha256:c32bd648a77ba4ea8214234796f8785a16e071604a46fd16737d4fc15ad7dba0" + +-[[package]] ++[[metadata.targets]] + name = "alabaster" + version = "0.7.13" + requires_python = ">=3.6" +@@ -249,62 +249,82 @@ files = [ + + [[package]] + name = "coverage" +-version = "7.4.0" ++version = "7.6.1" + requires_python = ">=3.8" + summary = "Code coverage measurement for Python" + files = [ +- {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, +- {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, +- {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, +- {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, +- {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, +- {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, +- {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, +- {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, +- {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, +- {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, +- {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, +- {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, +- {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, +- {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, +- {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, +- {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, +- {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, +- {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, +- {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, +- {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, +- {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, +- {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, +- {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, +- {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, +- {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, +- {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, +- {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, +- {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, +- {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, +- {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, +- {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, +- {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, +- {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, +- {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, +- {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, +- {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, +- {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, +- {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, +- {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, +- {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, +- {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, +- {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, +- {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, +- {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, +- {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, +- {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, +- {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, +- {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, +- {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, +- {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, +- {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, +- {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, ++ {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, ++ {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, ++ {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, ++ {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, ++ {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, ++ {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, ++ {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, ++ {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, ++ {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, ++ {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, ++ {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, ++ {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, ++ {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, ++ {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, ++ {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, ++ {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, ++ {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, ++ {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, ++ {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, ++ {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, ++ {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, ++ {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, ++ {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, ++ {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, ++ {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, ++ {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, ++ {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, ++ {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, ++ {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, ++ {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, ++ {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, ++ {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, ++ {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, ++ {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, ++ {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, ++ {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, ++ {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, ++ {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, ++ {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, ++ {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, ++ {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, ++ {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, ++ {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, ++ {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, ++ {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, ++ {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, ++ {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, ++ {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, ++ {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, ++ {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, ++ {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, ++ {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, ++ {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, ++ {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, ++ {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, ++ {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, ++ {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, ++ {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, ++ {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, ++ {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, ++ {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, ++ {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, ++ {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, ++ {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, ++ {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, ++ {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, ++ {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, ++ {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, ++ {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, ++ {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, ++ {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, ++ {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, + ] + + [[package]] +@@ -339,12 +359,12 @@ files = [ + + [[package]] + name = "execnet" +-version = "2.0.2" +-requires_python = ">=3.7" ++version = "2.1.1" ++requires_python = ">=3.8" + summary = "execnet: rapid multi-Python deployment" + files = [ +- {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, +- {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, ++ {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, ++ {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, + ] + + [[package]] +@@ -365,17 +385,17 @@ files = [ + + [[package]] + name = "hypothesis" +-version = "6.90.0" ++version = "6.111.2" + requires_python = ">=3.8" + summary = "A library for property-based testing" + dependencies = [ +- "attrs>=19.2.0", ++ "attrs>=22.2.0", + "exceptiongroup>=1.0.0; python_version < \"3.11\"", + "sortedcontainers<3.0.0,>=2.1.0", + ] + files = [ +- {file = "hypothesis-6.90.0-py3-none-any.whl", hash = "sha256:4d7d3d3d5e4e4a9954b448fc8220cd73573e3e32adb00059f6907de6b55dcd5e"}, +- {file = "hypothesis-6.90.0.tar.gz", hash = "sha256:0ab33900b9362318bd03d911a77a0dda8629c1877420074d87ae466919f6e4c0"}, ++ {file = "hypothesis-6.111.2-py3-none-any.whl", hash = "sha256:055e8228958e22178d6077e455fd86a72044d02dac130dbf9c8b31e161b9809c"}, ++ {file = "hypothesis-6.111.2.tar.gz", hash = "sha256:0496ad28c7240ee9ba89fcc7fb1dc74e89f3e40fbcbbb5f73c0091558dec8e6e"}, + ] + + [[package]] +@@ -897,12 +917,12 @@ files = [ + + [[package]] + name = "pluggy" +-version = "1.3.0" ++version = "1.5.0" + requires_python = ">=3.8" + summary = "plugin and hook calling mechanisms for python" + files = [ +- {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, +- {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ++ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, ++ {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, + ] + + [[package]] +@@ -1030,7 +1050,7 @@ files = [ + + [[package]] + name = "pytest" +-version = "8.0.0" ++version = "8.3.2" + requires_python = ">=3.8" + summary = "pytest: simple powerful testing with Python" + dependencies = [ +@@ -1038,12 +1058,12 @@ dependencies = [ + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", +- "pluggy<2.0,>=1.3.0", +- "tomli>=1.0.0; python_version < \"3.11\"", ++ "pluggy<2,>=1.5", ++ "tomli>=1; python_version < \"3.11\"", + ] + files = [ +- {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, +- {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, ++ {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, ++ {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, + ] + + [[package]] +@@ -1062,16 +1082,16 @@ files = [ + + [[package]] + name = "pytest-xdist" +-version = "3.4.0" +-requires_python = ">=3.7" ++version = "3.6.1" ++requires_python = ">=3.8" + summary = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" + dependencies = [ +- "execnet>=1.1", +- "pytest>=6.2.0", ++ "execnet>=2.1", ++ "pytest>=7.0.0", + ] + files = [ +- {file = "pytest-xdist-3.4.0.tar.gz", hash = "sha256:3a94a931dd9e268e0b871a877d09fe2efb6175c2c23d60d56a6001359002b832"}, +- {file = "pytest_xdist-3.4.0-py3-none-any.whl", hash = "sha256:e513118bf787677a427e025606f55e95937565e06dfaac8d87f55301e57ae607"}, ++ {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, ++ {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, + ] + + [[package]] +Index: cattrs-24.1.2/pyproject.toml +=================================================================== +--- cattrs-24.1.2.orig/pyproject.toml ++++ cattrs-24.1.2/pyproject.toml +@@ -7,13 +7,13 @@ lint = [ + "ruff>=0.0.277", + ] + test = [ +- "hypothesis>=6.79.4", +- "pytest>=7.4.0", ++ "hypothesis>=6.111.2", ++ "pytest>=8.3.2", + "pytest-benchmark>=4.0.0", + "immutables>=0.20", + "typing-extensions>=4.7.1", +- "coverage>=7.4.0", +- "pytest-xdist>=3.4.0", ++ "coverage>=7.6.1", ++ "pytest-xdist>=3.6.1", + ] + docs = [ + "sphinx>=5.3.0", +Index: cattrs-24.1.2/tests/test_baseconverter.py +=================================================================== +--- cattrs-24.1.2.orig/tests/test_baseconverter.py ++++ cattrs-24.1.2/tests/test_baseconverter.py +@@ -15,7 +15,7 @@ from .typed import nested_typed_classes, + unstructure_strats = one_of(just(s) for s in UnstructureStrategy) + + +-@given(simple_typed_classes(newtypes=False), unstructure_strats) ++@given(simple_typed_classes(newtypes=False, allow_nan=False), unstructure_strats) + def test_simple_roundtrip(cls_and_vals, strat): + """ + Simple classes with metadata can be unstructured and restructured. +@@ -27,7 +27,10 @@ def test_simple_roundtrip(cls_and_vals, + assert inst == converter.structure(converter.unstructure(inst), cl) + + +-@given(simple_typed_attrs(defaults=True, newtypes=False), unstructure_strats) ++@given( ++ simple_typed_attrs(defaults=True, newtypes=False, allow_nan=False), ++ unstructure_strats, ++) + def test_simple_roundtrip_defaults(attr_and_strat, strat): + """ + Simple classes with metadata can be unstructured and restructured. +@@ -43,7 +46,7 @@ def test_simple_roundtrip_defaults(attr_ + assert inst == converter.structure(converter.unstructure(inst), cl) + + +-@given(nested_typed_classes(newtypes=False)) ++@given(nested_typed_classes(newtypes=False, allow_nan=False)) + def test_nested_roundtrip(cls_and_vals): + """ + Nested classes with metadata can be unstructured and restructured. +@@ -55,7 +58,7 @@ def test_nested_roundtrip(cls_and_vals): + assert inst == converter.structure(converter.unstructure(inst), cl) + + +-@given(nested_typed_classes(kw_only=False, newtypes=False)) ++@given(nested_typed_classes(kw_only=False, newtypes=False, allow_nan=False)) + def test_nested_roundtrip_tuple(cls_and_vals): + """ + Nested classes with metadata can be unstructured and restructured. +@@ -70,8 +73,8 @@ def test_nested_roundtrip_tuple(cls_and_ + + @settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) + @given( +- simple_typed_classes(defaults=False, newtypes=False), +- simple_typed_classes(defaults=False, newtypes=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), + unstructure_strats, + ) + def test_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat): +@@ -113,8 +116,8 @@ def test_union_field_roundtrip(cl_and_va + @pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax") + @settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) + @given( +- simple_typed_classes(defaults=False, newtypes=False), +- simple_typed_classes(defaults=False, newtypes=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), + unstructure_strats, + ) + def test_310_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat): +@@ -153,7 +156,7 @@ def test_310_union_field_roundtrip(cl_an + assert inst == converter.structure(converter.unstructure(inst), C) + + +-@given(simple_typed_classes(defaults=False, newtypes=False)) ++@given(simple_typed_classes(defaults=False, newtypes=False, allow_nan=False)) + def test_optional_field_roundtrip(cl_and_vals): + """ + Classes with optional fields can be unstructured and structured. +@@ -175,7 +178,7 @@ def test_optional_field_roundtrip(cl_and + + + @pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax") +-@given(simple_typed_classes(defaults=False, newtypes=False)) ++@given(simple_typed_classes(defaults=False, newtypes=False, allow_nan=False)) + def test_310_optional_field_roundtrip(cl_and_vals): + """ + Classes with optional fields can be unstructured and structured. +Index: cattrs-24.1.2/tests/test_converter.py +=================================================================== +--- cattrs-24.1.2.orig/tests/test_converter.py ++++ cattrs-24.1.2/tests/test_converter.py +@@ -40,7 +40,10 @@ from .typed import ( + unstructure_strats = one_of(just(s) for s in UnstructureStrategy) + + +-@given(simple_typed_classes() | simple_typed_dataclasses(), booleans()) ++@given( ++ simple_typed_classes(allow_nan=False) | simple_typed_dataclasses(allow_nan=False), ++ booleans(), ++) + def test_simple_roundtrip(cls_and_vals, detailed_validation): + """ + Simple classes with metadata can be unstructured and restructured. +@@ -54,8 +57,8 @@ def test_simple_roundtrip(cls_and_vals, + + + @given( +- simple_typed_classes(kw_only=False, newtypes=False) +- | simple_typed_dataclasses(newtypes=False), ++ simple_typed_classes(kw_only=False, newtypes=False, allow_nan=False) ++ | simple_typed_dataclasses(newtypes=False, allow_nan=False), + booleans(), + ) + def test_simple_roundtrip_tuple(cls_and_vals, dv: bool): +@@ -72,7 +75,7 @@ def test_simple_roundtrip_tuple(cls_and_ + assert inst == converter.structure(unstructured, cl) + + +-@given(simple_typed_attrs(defaults=True)) ++@given(simple_typed_attrs(defaults=True, allow_nan=False)) + def test_simple_roundtrip_defaults(attr_and_vals): + """ + Simple classes with metadata can be unstructured and restructured. +@@ -87,7 +90,9 @@ def test_simple_roundtrip_defaults(attr_ + assert inst == converter.structure(converter.unstructure(inst), cl) + + +-@given(simple_typed_attrs(defaults=True, kw_only=False, newtypes=False)) ++@given( ++ simple_typed_attrs(defaults=True, kw_only=False, newtypes=False, allow_nan=False) ++) + def test_simple_roundtrip_defaults_tuple(attr_and_vals): + """ + Simple classes with metadata can be unstructured and restructured. +@@ -103,7 +108,8 @@ def test_simple_roundtrip_defaults_tuple + + + @given( +- simple_typed_classes(newtypes=False) | simple_typed_dataclasses(newtypes=False), ++ simple_typed_classes(newtypes=False, allow_nan=False) ++ | simple_typed_dataclasses(newtypes=False, allow_nan=False), + unstructure_strats, + ) + def test_simple_roundtrip_with_extra_keys_forbidden(cls_and_vals, strat): +@@ -200,7 +206,7 @@ def test_forbid_extra_keys_nested_overri + assert cve.value.exceptions[0].extra_fields == {"b"} + + +-@given(nested_typed_classes(defaults=True, min_attrs=1), booleans()) ++@given(nested_typed_classes(defaults=True, min_attrs=1, allow_nan=False), booleans()) + def test_nested_roundtrip(cls_and_vals, omit_if_default): + """ + Nested classes with metadata can be unstructured and restructured. +@@ -214,7 +220,9 @@ def test_nested_roundtrip(cls_and_vals, + + + @given( +- nested_typed_classes(defaults=True, min_attrs=1, kw_only=False, newtypes=False), ++ nested_typed_classes( ++ defaults=True, min_attrs=1, kw_only=False, newtypes=False, allow_nan=False ++ ), + booleans(), + ) + def test_nested_roundtrip_tuple(cls_and_vals, omit_if_default: bool): +@@ -233,8 +241,8 @@ def test_nested_roundtrip_tuple(cls_and_ + + @settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) + @given( +- simple_typed_classes(defaults=False, newtypes=False), +- simple_typed_classes(defaults=False, newtypes=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), + unstructure_strats, + ) + def test_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat): +@@ -278,8 +286,8 @@ def test_union_field_roundtrip(cl_and_va + @pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax") + @settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) + @given( +- simple_typed_classes(defaults=False, newtypes=False), +- simple_typed_classes(defaults=False, newtypes=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), ++ simple_typed_classes(defaults=False, newtypes=False, allow_nan=False), + unstructure_strats, + ) + def test_310_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat): +@@ -320,7 +328,7 @@ def test_310_union_field_roundtrip(cl_an + assert inst == converter.structure(unstructured, C) + + +-@given(simple_typed_classes(defaults=False)) ++@given(simple_typed_classes(defaults=False, allow_nan=False)) + def test_optional_field_roundtrip(cl_and_vals): + """ + Classes with optional fields can be unstructured and structured. +@@ -342,7 +350,7 @@ def test_optional_field_roundtrip(cl_and + + + @pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax") +-@given(simple_typed_classes(defaults=False)) ++@given(simple_typed_classes(defaults=False, allow_nan=False)) + def test_310_optional_field_roundtrip(cl_and_vals): + """ + Classes with optional fields can be unstructured and structured. +@@ -363,7 +371,7 @@ def test_310_optional_field_roundtrip(cl + assert inst == converter.structure(unstructured, C) + + +-@given(simple_typed_classes(defaults=True)) ++@given(simple_typed_classes(defaults=True, allow_nan=False)) + def test_omit_default_roundtrip(cl_and_vals): + """ + Omit default on the converter works. +Index: cattrs-24.1.2/tests/test_gen_dict.py +=================================================================== +--- cattrs-24.1.2.orig/tests/test_gen_dict.py ++++ cattrs-24.1.2/tests/test_gen_dict.py +@@ -160,9 +160,9 @@ def test_individual_overrides(converter_ + + + @given( +- cl_and_vals=nested_typed_classes() +- | simple_typed_classes() +- | simple_typed_dataclasses(), ++ cl_and_vals=nested_typed_classes(allow_nan=False) ++ | simple_typed_classes(allow_nan=False) ++ | simple_typed_dataclasses(allow_nan=False), + dv=..., + ) + def test_unmodified_generated_structuring(cl_and_vals, dv: bool): +@@ -185,7 +185,9 @@ def test_unmodified_generated_structurin + + + @given( +- simple_typed_classes(min_attrs=1) | simple_typed_dataclasses(min_attrs=1), data() ++ simple_typed_classes(min_attrs=1, allow_nan=False) ++ | simple_typed_dataclasses(min_attrs=1, allow_nan=False), ++ data(), + ) + def test_renaming(cl_and_vals, data): + converter = Converter() +Index: cattrs-24.1.2/tests/typed.py +=================================================================== +--- cattrs-24.1.2.orig/tests/typed.py ++++ cattrs-24.1.2/tests/typed.py +@@ -67,7 +67,7 @@ def simple_typed_classes( + newtypes=True, + text_codec: str = "utf8", + allow_infinity=None, +- allow_nan=None, ++ allow_nan=True, + ) -> SearchStrategy[Tuple[Type, PosArgs, KwArgs]]: + """Yield tuples of (class, values).""" + return lists_of_typed_attrs( +@@ -82,7 +82,9 @@ def simple_typed_classes( + ).flatmap(partial(_create_hyp_class, frozen=frozen)) + + +-def simple_typed_dataclasses(defaults=None, min_attrs=0, frozen=False, newtypes=True): ++def simple_typed_dataclasses( ++ defaults=None, min_attrs=0, frozen=False, newtypes=True, allow_nan=True ++): + """Yield tuples of (class, values).""" + return lists_of_typed_attrs( + defaults, +@@ -90,15 +92,20 @@ def simple_typed_dataclasses(defaults=No + for_frozen=frozen, + allow_mutable_defaults=False, + newtypes=newtypes, ++ allow_nan=allow_nan, + ).flatmap(partial(_create_dataclass, frozen=frozen)) + + + def simple_typed_classes_and_strats( +- defaults=None, min_attrs=0, kw_only=None, newtypes=True ++ defaults=None, min_attrs=0, kw_only=None, newtypes=True, allow_nan=True + ) -> SearchStrategy[Tuple[Type, SearchStrategy[PosArgs], SearchStrategy[KwArgs]]]: + """Yield tuples of (class, (strategies)).""" + return lists_of_typed_attrs( +- defaults, min_size=min_attrs, kw_only=kw_only, newtypes=newtypes ++ defaults, ++ min_size=min_attrs, ++ kw_only=kw_only, ++ newtypes=newtypes, ++ allow_nan=allow_nan, + ).flatmap(_create_hyp_class_and_strat) + + +@@ -111,7 +118,7 @@ def lists_of_typed_attrs( + newtypes=True, + text_codec="utf8", + allow_infinity=None, +- allow_nan=None, ++ allow_nan=True, + ) -> SearchStrategy[List[Tuple[_CountingAttr, SearchStrategy[PosArg]]]]: + # Python functions support up to 255 arguments. + return lists( +@@ -142,7 +149,7 @@ def simple_typed_attrs( + newtypes=True, + text_codec="utf8", + allow_infinity=None, +- allow_nan=None, ++ allow_nan=True, + ) -> SearchStrategy[Tuple[_CountingAttr, SearchStrategy[PosArgs]]]: + if not is_39_or_later: + res = ( +@@ -400,7 +407,7 @@ def str_typed_attrs(draw, defaults=None, + + @composite + def float_typed_attrs( +- draw, defaults=None, kw_only=None, allow_infinity=None, allow_nan=None ++ draw, defaults=None, kw_only=None, allow_infinity=None, allow_nan=True + ): + """ + Generate a tuple of an attribute and a strategy that yields floats for that +@@ -832,7 +839,7 @@ def dict_of_class( + + + def _create_hyp_nested_strategy( +- simple_class_strategy: SearchStrategy, kw_only=None, newtypes=True ++ simple_class_strategy: SearchStrategy, kw_only=None, newtypes=True, allow_nan=True + ) -> SearchStrategy[Tuple[Type, SearchStrategy[PosArgs], SearchStrategy[KwArgs]]]: + """ + Create a recursive attrs class. +@@ -847,7 +854,8 @@ def _create_hyp_nested_strategy( + attrs_and_classes: SearchStrategy[ + Tuple[List[Tuple[_CountingAttr, PosArgs]], Tuple[Type, SearchStrategy[PosArgs]]] + ] = tuples( +- lists_of_typed_attrs(kw_only=kw_only, newtypes=newtypes), simple_class_strategy ++ lists_of_typed_attrs(kw_only=kw_only, newtypes=newtypes, allow_nan=allow_nan), ++ simple_class_strategy, + ) + + return nested_classes(attrs_and_classes) +@@ -891,22 +899,37 @@ def nested_classes( + + + def nested_typed_classes_and_strat( +- defaults=None, min_attrs=0, kw_only=None, newtypes=True ++ defaults=None, min_attrs=0, kw_only=None, newtypes=True, allow_nan=True + ) -> SearchStrategy[Tuple[Type, SearchStrategy[PosArgs]]]: + return recursive( + simple_typed_classes_and_strats( +- defaults=defaults, min_attrs=min_attrs, kw_only=kw_only, newtypes=newtypes ++ defaults=defaults, ++ min_attrs=min_attrs, ++ kw_only=kw_only, ++ newtypes=newtypes, ++ allow_nan=allow_nan, ++ ), ++ partial( ++ _create_hyp_nested_strategy, ++ kw_only=kw_only, ++ newtypes=newtypes, ++ allow_nan=allow_nan, + ), +- partial(_create_hyp_nested_strategy, kw_only=kw_only, newtypes=newtypes), + max_leaves=20, + ) + + + @composite +-def nested_typed_classes(draw, defaults=None, min_attrs=0, kw_only=None, newtypes=True): ++def nested_typed_classes( ++ draw, defaults=None, min_attrs=0, kw_only=None, newtypes=True, allow_nan=True ++): + cl, strat, kwarg_strat = draw( + nested_typed_classes_and_strat( +- defaults=defaults, min_attrs=min_attrs, kw_only=kw_only, newtypes=newtypes ++ defaults=defaults, ++ min_attrs=min_attrs, ++ kw_only=kw_only, ++ newtypes=newtypes, ++ allow_nan=allow_nan, + ) + ) + return cl, draw(strat), draw(kwarg_strat) +Index: cattrs-24.1.2/tests/untyped.py +=================================================================== +--- cattrs-24.1.2.orig/tests/untyped.py ++++ cattrs-24.1.2/tests/untyped.py +@@ -356,7 +356,7 @@ def float_attrs(draw, defaults=None, kw_ + """ + default = NOTHING + if defaults is True or (defaults is None and draw(st.booleans())): +- default = draw(st.floats()) ++ default = draw(st.floats(allow_nan=False)) + return ( + attr.ib( + default=default, kw_only=draw(st.booleans()) if kw_only is None else kw_only diff --git a/python-cattrs.changes b/python-cattrs.changes new file mode 100644 index 0000000..c2e4365 --- /dev/null +++ b/python-cattrs.changes @@ -0,0 +1,274 @@ +------------------------------------------------------------------- +Mon Nov 17 02:10:39 UTC 2025 - Steve Kowalik + +- Update to 25.3.0: + * Potentially breaking: Abstract sets are now structured into frozensets. + * Python 3.14 is now supported and part of the test matrix. + * Fix unstructuring NewTypes with the {class}BaseConverter. + * Make some Hypothesis tests more robust. + * {func}cattrs.strategies.include_subclasses now works with generic parent + classes and the tagged union strategy. + * Potentially breaking: Sequences are now structured into tuples. + * Add a use_alias parameter to cattrs.Converter. + * The union passthrough strategy now by default accepts ints for unions + that contain floats but not ints, when configured to be able to handle + both ints and floats. This more closely matches the current typing + behavior. + * Fix unstructuring of generic classes with stringified annotations. + * The default disambiguation hook factory is now only enabled for + converters with unstructure_strat=AS_DICT (the default). + * Switch to uv and just in lieu of PDM, tox and Make. + * Fixed AttributeError: no attribute '__parameters__' while structuring + attrs classes that inherit from parametrized generic aliases from + collections.abc. + * Potentially breaking: The converters raise StructureHandlerNotFoundError + more eagerly (on hook creation, instead of on hook use). This helps + surfacing problems with missing hooks sooner. + * typing.Self is now supported in attrs classes, dataclasses, TypedDicts + and the dict NamedTuple factories. See typing.Self for details. + * PEP 695 type aliases can now be used with + BaseConverter.register_structure_hook and + BaseConverter.register_unstructure_hook. Previously, they required the + use of BaseConverter.register_structure_hook_func. + * Some defaultdicts are now supported by default, and + cattrs.cols.is_defaultdict and cattrs.cols.defaultdict_structure_factory + are exposed through cattrs.cols. + * Generic PEP 695 type aliases are now supported. + * The tagged union strategy now also supports type aliases of unions. + * Converter.copy and BaseConverter.copy are correctly annotated as + returning Self. + * Many preconf converters (bson, stdlib JSON, cbor2, msgpack, msgspec, + orjson, ujson) skip unstructuring int and str enums, leaving them to the + underlying libraries to handle with greater efficiency. + * The msgspec JSON preconf converter now handles dataclasses with private + attributes more efficiently. + * Preconf converters now handle dictionaries with literal keys properly. + * Structuring TypedDicts from invalid inputs now properly raises a + ClassValidationError. + * cattrs.strategies.include_subclasses now properly works with generic + parent classes. + * Python 3.13 is now supported. + * Python 3.8 is no longer supported, as it is end-of-life. +- Dropped patches, no longer required: + * fix-test-no-nans.patch + * support-python-3.13.patch + +------------------------------------------------------------------- +Wed May 7 11:21:09 UTC 2025 - John Paul Adrian Glaubitz + +- Update to 24.1.3 + * Fix structuring of keyword-only dataclass fields when not + using detailed validation. (#637) +- Refresh support-python-3.13.patch + +------------------------------------------------------------------- +Fri Nov 15 14:19:05 UTC 2024 - Yunus Acar + +- add fix-test-no-nans.patch to get the tests to work with the + latest attrs +- add support-python-3.13.patch to add python-3.13 support + +------------------------------------------------------------------- +Mon Oct 28 22:38:02 UTC 2024 - Dirk Müller + +- update to 24.1.2: + * Fix {meth}`BaseConverter.register_structure_hook` and + {meth}`BaseConverter.register_unstructure_hook` type hints. + * Fix {meth}`BaseConverter.register_structure_hook_factory` and + {meth}`BaseConverter.register_unstructure_hook_factory` type + hints. + * **Potentially breaking**: Unstructuring hooks for + `typing.Any` are consistent now: values are unstructured + using their runtime type. + * Introduce {meth}`BaseConverter.get_structure_hook` and + {meth}`BaseConverter.get_unstructure_hook` methods. + * Enhance the {func}`cattrs.cols.is_mapping` predicate function + to also cover virtual subclasses of `abc.Mapping`. + * Introduce the _msgspec_ {mod}`preconf converter + `. + * Add support for PEP 695 type aliases. + * Add support for PEP 696 `TypeVar`s with defaults. + * Add support for named tuples with type metadata + (`typing.NamedTuple`). + * Add support for optionally un/unstructuring named tuples + using dictionaries. + * PEP 695 generics are now tested. + * Imports are now sorted using Ruff. + * Tests are run with the pytest-xdist plugin by default. + * Rework the introductory parts of the documentation, + introducing the Basics section. + * The documentation has been significantly reworked. + * The docs now use the Inter font. + * Make type annotations for `include_subclasses` and + `tagged_union` strategies more lenient. + +------------------------------------------------------------------- +Mon Apr 8 10:41:21 UTC 2024 - Dirk Müller + +- add sle15_python_module_pythons + +------------------------------------------------------------------- +Thu Dec 14 09:18:25 UTC 2023 - Petr Gajdos + +- update to 23.2.3: + * Fix a regression when unstructuring dictionary values typed + as `Any`. + * (#453 #462) + * Fix a regression when unstructuring unspecialized generic + classes. + * (#465 #466) + * Optimize function source code caching. + * (#445 #464) + * Generate unique files only in case of linecache enabled. + * (#445 #441) + * ## 23.2.2 (2023-11-21) + * Fix a regression when unstructuring `Any | None`. + * (#453 #454) + * ## 23.2.1 (2023-11-18) + * Fix unnecessary `typing_extensions` import on Python 3.11. + * (#446 #447) + * ## 23.2.0 (2023-11-17) + * **Potentially breaking**: skip _attrs_ fields marked as + `init=False` by default. This change is potentially breaking + for unstructuring. + * See here for instructions on how to restore the old behavior. + * (#40 #395) + * **Potentially breaking**: + {py:func}`cattrs.gen.make_dict_structure_fn` and + {py:func}`cattrs.gen.typeddicts.make_dict_structure_fn` will + use the values for the `detailed_validation` and + `forbid_extra_keys` parameters from the given converter by + default now. + * If you're using these functions directly, the old behavior + can be restored by passing in the desired values directly. + * (#410 #411) + * **Potentially breaking**: The default union structuring + strategy will also use fields annotated as `typing.Literal` + to help guide structuring. + * See here for instructions on how to restore the old behavior. + * (#391) + * Python 3.12 is now supported. Python 3.7 is no longer + supported; use older releases there. + * (#424) + * Implement the `union passthrough` strategy, enabling much + richer union handling for preconfigured converters. Learn + more here. + * Introduce the `use_class_methods` strategy. Learn more here. + * (#405) + * The `omit` parameter of {py:func}`cattrs.override` is now of + type `bool | None` (from `bool`). + * `None` is the new default and means to apply default _cattrs_ + handling to the attribute, which is to omit the attribute if + it's marked as `init=False`, and keep it otherwise. + * Converters can now be initialized with custom fallback hook + factories for un/structuring. + * (#331 #441) + * Add support for `date` to preconfigured converters. + * (#420) + * Add support for `datetime.date`s to the PyYAML preconfigured + converter. + * (#393) + * Fix {py:func}`format_exception() ` + parameter working for recursive calls to + {py:func}`transform_error `. + * (#389) + * _attrs_ aliases are now supported, although aliased fields + still map to their attribute name instead of their alias by + default when un/structuring. + * (#322 #391) + * Fix TypedDicts with periods in their field names. + * (#376 #377) + * Optimize and improve unstructuring of `Optional` (unions of + one type and `None`). + * (#380 #381) + * Fix {py:func}`format_exception ` + and {py:func}`transform_error ` type + annotations. + * Improve the implementation of `cattrs._compat.is_typeddict`. + The implementation is now simpler, and relies on fewer + private implementation details from `typing` and + typing_extensions. + * (#384) + * Improve handling of TypedDicts with forward references. + * Speed up generated _attrs_ and TypedDict structuring + functions by changing their signature slightly. + * (#388) + * Fix copying of converters with function hooks. + * (#398 #399) + * Broaden {py:func}`loads' + ` type + definition for the preconf orjson converter. + * (#400) + * {py:class}`AttributeValidationNote + ` and + {py:class}`IterableValidationNote + ` are now picklable. + * (#408) + * Fix structuring `Final` lists. + * (#412) + * Fix certain cases of structuring `Annotated` types. + * (#418) + * Fix the tagged union strategy to work with + `forbid_extra_keys`. + * (#402 #443) + * Use PDM instead of Poetry. + * _cattrs_ is now linted with Ruff. + * Remove some unused lines in the unstructuring code. + * (#416) + * Fix handling classes inheriting from non-generic protocols. + * (#374 #436) + * The documentation Makefile now supports the `htmlview` and + `htmllive` targets. (#442) + * _cattrs_ is now published using PyPI Trusted Publishers, and + `main` branch commits are automatically deployed to Test + PyPI. + * ## 23.1.2 (2023-06-02) + * Improve `typing_extensions` version bound. (#372) + * ## 23.1.1 (2023-05-30) + * Add `typing_extensions` as a direct dependency on 3.10. + * (#369 #370) + * ## 23.1.0 (2023-05-30) + * Introduce the `tagged_union` strategy. + * (#318 #317) + * Introduce the `cattrs.transform_error` helper function for + formatting validation exceptions. (258 342) + * Add support for `typing.TypedDict` and + `typing_extensions.TypedDict`. + * (#296 #364) + * Add support for `typing.Final`. + * (#340 #349) + * Introduce `override.struct_hook` and + `override.unstruct_hook`. Learn more here. + * (#326) + * Fix generating structuring functions for types with angle + brackets (`<>`) and pipe symbols (`|`) in the name. + * (#319 #327) + * `pathlib.Path` is now supported by default. + * (#81) + * Add `cbor2` serialization library to the `cattrs.preconf` + package. + * Add optional dependencies for `cattrs.preconf` third-party + libraries. (#337) + * All preconf converters now allow overriding the default + `unstruct_collection_overrides` in `make_converter`. + * (#350 #353) + * Subclasses structuring and unstructuring is now supported via + a custom `include_subclasses` strategy. + * (#312) + * Add support for `typing_extensions.Annotated` when the python + version is less than `3.9`. (#366) + * Add unstructuring and structuring support for the standard + library `deque`. + * (#355) + +------------------------------------------------------------------- +Mon May 8 21:15:51 UTC 2023 - Ben Greiner + +- Slim down build requirement to poetry-core +- Explicitily require a bunch of test dependencies instead + +------------------------------------------------------------------- +Mon Jan 23 04:22:53 UTC 2023 - Steve Kowalik + +- Initial release of 22.2.0. + diff --git a/python-cattrs.spec b/python-cattrs.spec new file mode 100644 index 0000000..f5a5e53 --- /dev/null +++ b/python-cattrs.spec @@ -0,0 +1,88 @@ +# +# spec file for package python-cattrs +# +# Copyright (c) 2025 SUSE LLC and contributors +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%{?sle15_python_module_pythons} +Name: python-cattrs +Version: 25.3.0 +Release: 0 +Summary: Composable complex class support for attrs and dataclasses +License: MIT +URL: https://github.com/python-attrs/cattrs +Source: https://files.pythonhosted.org/packages/source/c/cattrs/cattrs-%{version}.tar.gz +BuildRequires: %{python_module base >= 3.9} +BuildRequires: %{python_module hatch-vcs} +BuildRequires: %{python_module hatchling} +BuildRequires: %{python_module pip} +BuildRequires: python-rpm-macros +# SECTION test requirements +BuildRequires: %{python_module attrs >= 25.4} +BuildRequires: %{python_module PyYAML} +BuildRequires: %{python_module cbor2} +BuildRequires: %{python_module hypothesis} +BuildRequires: %{python_module immutables} +BuildRequires: %{python_module msgpack >= 1.0.2} +BuildRequires: %{python_module msgspec} +BuildRequires: %{python_module orjson} +BuildRequires: %{python_module pymongo} +BuildRequires: %{python_module pytest-benchmark} +BuildRequires: %{python_module pytest} +BuildRequires: %{python_module tomlkit} +BuildRequires: %{python_module typing_extensions >= 4.14} +BuildRequires: %{python_module ujson} +# /SECTION +BuildRequires: fdupes +Requires: python-attrs >= 25.4 +%if %python_version_nodots < 311 +Requires: python-exceptiongroup >= 1.1.1 +%endif +Requires: python-typing_extensions >= 4.14 +Suggests: python-cbor2 +Suggests: python-ujson +Suggests: python-orjson +Suggests: python-msgpack +Suggests: python-PyYAML +Suggests: python-tomlkit +Suggests: python-cbor2 +Suggests: python-pymongo +BuildArch: noarch +%python_subpackages + +%description +Composable complex class support for attrs and dataclasses. + +%prep +%autosetup -p1 -n cattrs-%{version} + +%build +%pyproject_wheel + +%install +%pyproject_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} + +%check +%pytest + +%files %{python_files} +%doc README.md HISTORY.md CONTRIBUTING.md +%license LICENSE +%{python_sitelib}/cattr +%{python_sitelib}/cattrs +%{python_sitelib}/cattrs-%{version}.dist-info + +%changelog diff --git a/support-python-3.13.patch b/support-python-3.13.patch new file mode 100644 index 0000000..0f4c240 --- /dev/null +++ b/support-python-3.13.patch @@ -0,0 +1,438 @@ +From 24aeb89d24d5f7d9304249516e35b831152314d0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= +Date: Sat, 5 Oct 2024 03:55:06 +0200 +Subject: [PATCH] Python 3.13 support (#543) + +* Python 3.13 support + +* Update msgspec + +* Ignore msgspec on 3.13 + +* Update orjson + +* Bump typing_extensions + +* Fix typing.NoDefault for list unstructuring +--- + .github/workflows/main.yml | 2 +- + pdm.lock | 191 +++++++++++++++++++------------------ + pyproject.toml | 5 +- + src/cattrs/dispatch.py | 3 +- + src/cattrs/gen/__init__.py | 6 ++ + tests/conftest.py | 2 + + tests/test_preconf.py | 11 ++- + tox.ini | 13 ++- + 8 files changed, 131 insertions(+), 102 deletions(-) + +diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml +index de772e7..5a2de57 100644 +--- a/.github/workflows/main.yml ++++ b/.github/workflows/main.yml +@@ -14,7 +14,7 @@ jobs: + + strategy: + matrix: +- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "pypy-3.10"] ++ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "pypy-3.10"] + fail-fast: false + + steps: +diff --git a/pdm.lock b/pdm.lock +index 53b69d4..7164add 100644 +--- a/pdm.lock ++++ b/pdm.lock +@@ -648,46 +648,46 @@ files = [ + + [[package]] + name = "msgspec" +-version = "0.18.5" ++version = "0.18.6" + requires_python = ">=3.8" + summary = "A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML." + files = [ +- {file = "msgspec-0.18.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50479d88f3c4e9c73b55fbe84dc14b1cee8cec753e9170bbeafe3f9837e9f7af"}, +- {file = "msgspec-0.18.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf885edac512e464c70a5f4f93b6f778c83ea4b91d646b6d72f6f5ac950f268e"}, +- {file = "msgspec-0.18.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773a38ead7832d171d1b9406bf42448a218245584af36e42c31f26d9f48a493a"}, +- {file = "msgspec-0.18.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5999eb65646b131f439ebb07c22446e8976b7fd8a312dca09ce6fa2c21162bb"}, +- {file = "msgspec-0.18.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a0ec78bd93684db61dfccf7a421b2e1a525b1a0546b4d8c4e339151be57d58a6"}, +- {file = "msgspec-0.18.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b547c7ad9786a79b0090a811d95d2d04063625a66fd96ed767cdfbabd8087c67"}, +- {file = "msgspec-0.18.5-cp310-cp310-win_amd64.whl", hash = "sha256:e4c2fc93a98afefd1a78e957ca63363a8e5fd1b58bf70a8d66413c8f2a4723a2"}, +- {file = "msgspec-0.18.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee1f9414523d9a53744d21a6a2b6a636d9008be016963148a2646b38132e11dd"}, +- {file = "msgspec-0.18.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0017f6af35a3959002df4c82af60c1df2160701529dd89b17df971fde5945257"}, +- {file = "msgspec-0.18.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13da9df61745b7757070dae6e3476ab4e13bb9dd3e3d11b050dfcae540058bd1"}, +- {file = "msgspec-0.18.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01ed3472a0508f88a25a9d3bccafb840110f0fc5eb493b4baa43646e4e7c75c2"}, +- {file = "msgspec-0.18.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f55c4610cb0514aef8b35bfd0682f4cc2d7efd5e9b58acf30abd90b2a2376b5d"}, +- {file = "msgspec-0.18.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8f7c0460aefdc8f01ea35f26e38c62b574bbf0b138ade860f557bbf9e9dac50c"}, +- {file = "msgspec-0.18.5-cp311-cp311-win_amd64.whl", hash = "sha256:024f880df7d2f8cfdb9f9904efa0f386d3692457159bd58f850c20f11c07d16f"}, +- {file = "msgspec-0.18.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3d206af4280172948d014d20b2cea7939784a99ea9a7ac943ce71100dbe8f98"}, +- {file = "msgspec-0.18.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:261cc6e3a687e6f31b80056ab12f6adff3255f9b68b86d92b0b497f8b289c84c"}, +- {file = "msgspec-0.18.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6af133ba491a09ef8dcbc2d9904bcec220247e2067bb75d5d6daa12e0739d6c"}, +- {file = "msgspec-0.18.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d318593e0ddc11b600552a470ec27baeb0b86a8e37903ac5ce7472ba0d6f7bf8"}, +- {file = "msgspec-0.18.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9a7b682cca3ba251a19cc769d38615ddd9551e086858decd950c156c2e79ecc1"}, +- {file = "msgspec-0.18.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b491b2549d22e11d7cfe34a231f9bd006cb6b71adefa070a070075d2f601e75c"}, +- {file = "msgspec-0.18.5-cp312-cp312-win_amd64.whl", hash = "sha256:c79e7115f0143688c5d866359e7b6b76dd1581a81c9aeac7805a9d6320e9f2ca"}, +- {file = "msgspec-0.18.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c13e0a510bbd00cb29d193fceff55d1e17a99c9f97284cdbe61c15496c2f7803"}, +- {file = "msgspec-0.18.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f4eeb22921ca6cdfbf17ca874eccbe23eb010c89ffb3017b628940c37d53ce4a"}, +- {file = "msgspec-0.18.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9420750f19c311e490db3edff9d153621c4989c582cf1be40c307c86d6cc2c1e"}, +- {file = "msgspec-0.18.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6431305c645fb2a88a6da1fcec53dbaac61697f1219000b9589f9286532aabc0"}, +- {file = "msgspec-0.18.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7b49cba0577edc8ac166263b5fec3619fe5a267805cfc041bccaf8a0c58ef05"}, +- {file = "msgspec-0.18.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3f387cabddf2dc26d6fa7f1a8158deefc8db9e0626eacebbe4875f421c66d574"}, +- {file = "msgspec-0.18.5-cp38-cp38-win_amd64.whl", hash = "sha256:482bdf77f3892dd603061b2b21ac6a4492bb797a552c92e833a41fe157162257"}, +- {file = "msgspec-0.18.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f290bfe7e21e8069890d101d8a060500b22a3aeb7860274644c4ec9240ddbedc"}, +- {file = "msgspec-0.18.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0027fba5362a3cb1bdd5503709aa2dbffad22dffd50f415086ed5f74f229ead9"}, +- {file = "msgspec-0.18.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd8a64da668b4eeef4b21dcecc640ed6950db661e2ea42ae52bbac5a2dbffb3a"}, +- {file = "msgspec-0.18.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be2440fa5699e1b3062d17fdfd8c6a459d72bb4edbce403353af6f39c8c5a6fa"}, +- {file = "msgspec-0.18.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:eccba21248f90f332335b109e89685e79940367974812cd13975313f480f3dd8"}, +- {file = "msgspec-0.18.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c30fadc1a1118097920dd868e42469fed32c7078ca2feff2fc19e7c017065322"}, +- {file = "msgspec-0.18.5-cp39-cp39-win_amd64.whl", hash = "sha256:fae28faef5fd61847930d8e86fd83c18f991a338efd8fbf69c1d35d42c652f41"}, +- {file = "msgspec-0.18.5.tar.gz", hash = "sha256:8e545651531f2d01b983d0ac0c7f3b6d99674267ff261b5f344f5016160b5608"}, ++ {file = "msgspec-0.18.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77f30b0234eceeff0f651119b9821ce80949b4d667ad38f3bfed0d0ebf9d6d8f"}, ++ {file = "msgspec-0.18.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a76b60e501b3932782a9da039bd1cd552b7d8dec54ce38332b87136c64852dd"}, ++ {file = "msgspec-0.18.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06acbd6edf175bee0e36295d6b0302c6de3aaf61246b46f9549ca0041a9d7177"}, ++ {file = "msgspec-0.18.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40a4df891676d9c28a67c2cc39947c33de516335680d1316a89e8f7218660410"}, ++ {file = "msgspec-0.18.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a6896f4cd5b4b7d688018805520769a8446df911eb93b421c6c68155cdf9dd5a"}, ++ {file = "msgspec-0.18.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3ac4dd63fd5309dd42a8c8c36c1563531069152be7819518be0a9d03be9788e4"}, ++ {file = "msgspec-0.18.6-cp310-cp310-win_amd64.whl", hash = "sha256:fda4c357145cf0b760000c4ad597e19b53adf01382b711f281720a10a0fe72b7"}, ++ {file = "msgspec-0.18.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e77e56ffe2701e83a96e35770c6adb655ffc074d530018d1b584a8e635b4f36f"}, ++ {file = "msgspec-0.18.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5351afb216b743df4b6b147691523697ff3a2fc5f3d54f771e91219f5c23aaa"}, ++ {file = "msgspec-0.18.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3232fabacef86fe8323cecbe99abbc5c02f7698e3f5f2e248e3480b66a3596b"}, ++ {file = "msgspec-0.18.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b524df6ea9998bbc99ea6ee4d0276a101bcc1aa8d14887bb823914d9f60d07"}, ++ {file = "msgspec-0.18.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:37f67c1d81272131895bb20d388dd8d341390acd0e192a55ab02d4d6468b434c"}, ++ {file = "msgspec-0.18.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0feb7a03d971c1c0353de1a8fe30bb6579c2dc5ccf29b5f7c7ab01172010492"}, ++ {file = "msgspec-0.18.6-cp311-cp311-win_amd64.whl", hash = "sha256:41cf758d3f40428c235c0f27bc6f322d43063bc32da7b9643e3f805c21ed57b4"}, ++ {file = "msgspec-0.18.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d86f5071fe33e19500920333c11e2267a31942d18fed4d9de5bc2fbab267d28c"}, ++ {file = "msgspec-0.18.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce13981bfa06f5eb126a3a5a38b1976bddb49a36e4f46d8e6edecf33ccf11df1"}, ++ {file = "msgspec-0.18.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e97dec6932ad5e3ee1e3c14718638ba333befc45e0661caa57033cd4cc489466"}, ++ {file = "msgspec-0.18.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad237100393f637b297926cae1868b0d500f764ccd2f0623a380e2bcfb2809ca"}, ++ {file = "msgspec-0.18.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db1d8626748fa5d29bbd15da58b2d73af25b10aa98abf85aab8028119188ed57"}, ++ {file = "msgspec-0.18.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:d70cb3d00d9f4de14d0b31d38dfe60c88ae16f3182988246a9861259c6722af6"}, ++ {file = "msgspec-0.18.6-cp312-cp312-win_amd64.whl", hash = "sha256:1003c20bfe9c6114cc16ea5db9c5466e49fae3d7f5e2e59cb70693190ad34da0"}, ++ {file = "msgspec-0.18.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f7d9faed6dfff654a9ca7d9b0068456517f63dbc3aa704a527f493b9200b210a"}, ++ {file = "msgspec-0.18.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9da21f804c1a1471f26d32b5d9bc0480450ea77fbb8d9db431463ab64aaac2cf"}, ++ {file = "msgspec-0.18.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46eb2f6b22b0e61c137e65795b97dc515860bf6ec761d8fb65fdb62aa094ba61"}, ++ {file = "msgspec-0.18.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8355b55c80ac3e04885d72db515817d9fbb0def3bab936bba104e99ad22cf46"}, ++ {file = "msgspec-0.18.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9080eb12b8f59e177bd1eb5c21e24dd2ba2fa88a1dbc9a98e05ad7779b54c681"}, ++ {file = "msgspec-0.18.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cc001cf39becf8d2dcd3f413a4797c55009b3a3cdbf78a8bf5a7ca8fdb76032c"}, ++ {file = "msgspec-0.18.6-cp38-cp38-win_amd64.whl", hash = "sha256:fac5834e14ac4da1fca373753e0c4ec9c8069d1fe5f534fa5208453b6065d5be"}, ++ {file = "msgspec-0.18.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:974d3520fcc6b824a6dedbdf2b411df31a73e6e7414301abac62e6b8d03791b4"}, ++ {file = "msgspec-0.18.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fd62e5818731a66aaa8e9b0a1e5543dc979a46278da01e85c3c9a1a4f047ef7e"}, ++ {file = "msgspec-0.18.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7481355a1adcf1f08dedd9311193c674ffb8bf7b79314b4314752b89a2cf7f1c"}, ++ {file = "msgspec-0.18.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6aa85198f8f154cf35d6f979998f6dadd3dc46a8a8c714632f53f5d65b315c07"}, ++ {file = "msgspec-0.18.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e24539b25c85c8f0597274f11061c102ad6b0c56af053373ba4629772b407be"}, ++ {file = "msgspec-0.18.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c61ee4d3be03ea9cd089f7c8e36158786cd06e51fbb62529276452bbf2d52ece"}, ++ {file = "msgspec-0.18.6-cp39-cp39-win_amd64.whl", hash = "sha256:b5c390b0b0b7da879520d4ae26044d74aeee5144f83087eb7842ba59c02bc090"}, ++ {file = "msgspec-0.18.6.tar.gz", hash = "sha256:a59fc3b4fcdb972d09138cb516dbde600c99d07c38fd9372a6ef500d2d031b4e"}, + ] + + [[package]] +@@ -720,60 +720,67 @@ files = [ + + [[package]] + name = "orjson" +-version = "3.9.5" +-requires_python = ">=3.7" ++version = "3.10.7" ++requires_python = ">=3.8" + summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" + files = [ +- {file = "orjson-3.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ad6845912a71adcc65df7c8a7f2155eba2096cf03ad2c061c93857de70d699ad"}, +- {file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e298e0aacfcc14ef4476c3f409e85475031de24e5b23605a465e9bf4b2156273"}, +- {file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:83c9939073281ef7dd7c5ca7f54cceccb840b440cec4b8a326bda507ff88a0a6"}, +- {file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e174cc579904a48ee1ea3acb7045e8a6c5d52c17688dfcb00e0e842ec378cabf"}, +- {file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8d51702f42c785b115401e1d64a27a2ea767ae7cf1fb8edaa09c7cf1571c660"}, +- {file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f13d61c0c7414ddee1ef4d0f303e2222f8cced5a2e26d9774751aecd72324c9e"}, +- {file = "orjson-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d748cc48caf5a91c883d306ab648df1b29e16b488c9316852844dd0fd000d1c2"}, +- {file = "orjson-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bd19bc08fa023e4c2cbf8294ad3f2b8922f4de9ba088dbc71e6b268fdf54591c"}, +- {file = "orjson-3.9.5-cp310-none-win32.whl", hash = "sha256:5793a21a21bf34e1767e3d61a778a25feea8476dcc0bdf0ae1bc506dc34561ea"}, +- {file = "orjson-3.9.5-cp310-none-win_amd64.whl", hash = "sha256:2bcec0b1024d0031ab3eab7a8cb260c8a4e4a5e35993878a2da639d69cdf6a65"}, +- {file = "orjson-3.9.5-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8547b95ca0e2abd17e1471973e6d676f1d8acedd5f8fb4f739e0612651602d66"}, +- {file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87ce174d6a38d12b3327f76145acbd26f7bc808b2b458f61e94d83cd0ebb4d76"}, +- {file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a960bb1bc9a964d16fcc2d4af5a04ce5e4dfddca84e3060c35720d0a062064fe"}, +- {file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a7aa5573a949760d6161d826d34dc36db6011926f836851fe9ccb55b5a7d8e8"}, +- {file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b2852afca17d7eea85f8e200d324e38c851c96598ac7b227e4f6c4e59fbd3df"}, +- {file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa185959c082475288da90f996a82e05e0c437216b96f2a8111caeb1d54ef926"}, +- {file = "orjson-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:89c9332695b838438ea4b9a482bce8ffbfddde4df92750522d928fb00b7b8dce"}, +- {file = "orjson-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2493f1351a8f0611bc26e2d3d407efb873032b4f6b8926fed8cfed39210ca4ba"}, +- {file = "orjson-3.9.5-cp311-none-win32.whl", hash = "sha256:ffc544e0e24e9ae69301b9a79df87a971fa5d1c20a6b18dca885699709d01be0"}, +- {file = "orjson-3.9.5-cp311-none-win_amd64.whl", hash = "sha256:89670fe2732e3c0c54406f77cad1765c4c582f67b915c74fda742286809a0cdc"}, +- {file = "orjson-3.9.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:15df211469625fa27eced4aa08dc03e35f99c57d45a33855cc35f218ea4071b8"}, +- {file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9f17c59fe6c02bc5f89ad29edb0253d3059fe8ba64806d789af89a45c35269a"}, +- {file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca6b96659c7690773d8cebb6115c631f4a259a611788463e9c41e74fa53bf33f"}, +- {file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26fafe966e9195b149950334bdbe9026eca17fe8ffe2d8fa87fdc30ca925d30"}, +- {file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9006b1eb645ecf460da067e2dd17768ccbb8f39b01815a571bfcfab7e8da5e52"}, +- {file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebfdbf695734b1785e792a1315e41835ddf2a3e907ca0e1c87a53f23006ce01d"}, +- {file = "orjson-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4a3943234342ab37d9ed78fb0a8f81cd4b9532f67bf2ac0d3aa45fa3f0a339f3"}, +- {file = "orjson-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e6762755470b5c82f07b96b934af32e4d77395a11768b964aaa5eb092817bc31"}, +- {file = "orjson-3.9.5-cp312-none-win_amd64.whl", hash = "sha256:c74df28749c076fd6e2157190df23d43d42b2c83e09d79b51694ee7315374ad5"}, +- {file = "orjson-3.9.5-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5bfa79916ef5fef75ad1f377e54a167f0de334c1fa4ebb8d0224075f3ec3d8c0"}, +- {file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87dfa6ac0dae764371ab19b35eaaa46dfcb6ef2545dfca03064f21f5d08239f"}, +- {file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50ced24a7b23058b469ecdb96e36607fc611cbaee38b58e62a55c80d1b3ad4e1"}, +- {file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1b74ea2a3064e1375da87788897935832e806cc784de3e789fd3c4ab8eb3fa5"}, +- {file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7cb961efe013606913d05609f014ad43edfaced82a576e8b520a5574ce3b2b9"}, +- {file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1225d2d5ee76a786bda02f8c5e15017462f8432bb960de13d7c2619dba6f0275"}, +- {file = "orjson-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f39f4b99199df05c7ecdd006086259ed25886cdbd7b14c8cdb10c7675cfcca7d"}, +- {file = "orjson-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a461dc9fb60cac44f2d3218c36a0c1c01132314839a0e229d7fb1bba69b810d8"}, +- {file = "orjson-3.9.5-cp38-none-win32.whl", hash = "sha256:dedf1a6173748202df223aea29de814b5836732a176b33501375c66f6ab7d822"}, +- {file = "orjson-3.9.5-cp38-none-win_amd64.whl", hash = "sha256:fa504082f53efcbacb9087cc8676c163237beb6e999d43e72acb4bb6f0db11e6"}, +- {file = "orjson-3.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6900f0248edc1bec2a2a3095a78a7e3ef4e63f60f8ddc583687eed162eedfd69"}, +- {file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17404333c40047888ac40bd8c4d49752a787e0a946e728a4e5723f111b6e55a5"}, +- {file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0eefb7cfdd9c2bc65f19f974a5d1dfecbac711dae91ed635820c6b12da7a3c11"}, +- {file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68c78b2a3718892dc018adbc62e8bab6ef3c0d811816d21e6973dee0ca30c152"}, +- {file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:591ad7d9e4a9f9b104486ad5d88658c79ba29b66c5557ef9edf8ca877a3f8d11"}, +- {file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cc2cbf302fbb2d0b2c3c142a663d028873232a434d89ce1b2604ebe5cc93ce8"}, +- {file = "orjson-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b26b5aa5e9ee1bad2795b925b3adb1b1b34122cb977f30d89e0a1b3f24d18450"}, +- {file = "orjson-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef84724f7d29dcfe3aafb1fc5fc7788dca63e8ae626bb9298022866146091a3e"}, +- {file = "orjson-3.9.5-cp39-none-win32.whl", hash = "sha256:664cff27f85939059472afd39acff152fbac9a091b7137092cb651cf5f7747b5"}, +- {file = "orjson-3.9.5-cp39-none-win_amd64.whl", hash = "sha256:91dda66755795ac6100e303e206b636568d42ac83c156547634256a2e68de694"}, +- {file = "orjson-3.9.5.tar.gz", hash = "sha256:6daf5ee0b3cf530b9978cdbf71024f1c16ed4a67d05f6ec435c6e7fe7a52724c"}, ++ {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, ++ {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, ++ {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, ++ {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, ++ {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, ++ {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, ++ {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, ++ {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, ++ {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, ++ {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, ++ {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, ++ {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, ++ {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, ++ {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, ++ {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, ++ {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, ++ {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, ++ {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, ++ {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, ++ {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, ++ {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, ++ {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, ++ {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, ++ {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, ++ {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, ++ {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, ++ {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, ++ {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, ++ {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, ++ {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, ++ {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, ++ {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, ++ {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, ++ {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, ++ {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, ++ {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, ++ {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, ++ {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, ++ {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, ++ {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, ++ {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, ++ {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, ++ {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, ++ {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, ++ {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, ++ {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, ++ {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, ++ {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, ++ {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, ++ {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, ++ {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, ++ {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, ++ {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, ++ {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, ++ {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, ++ {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, ++ {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + ] + + [[package]] +@@ -1459,12 +1466,12 @@ files = [ + + [[package]] + name = "typing-extensions" +-version = "4.8.0" ++version = "4.12.2" + requires_python = ">=3.8" + summary = "Backported and Experimental Type Hints for Python 3.8+" + files = [ +- {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, +- {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ++ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, ++ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + ] + + [[package]] +diff --git a/pyproject.toml b/pyproject.toml +index 7288cee..9114c20 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -43,7 +43,7 @@ authors = [ + ] + dependencies = [ + "attrs>=23.1.0", +- "typing-extensions>=4.1.0, !=4.6.3; python_version < '3.11'", ++ "typing-extensions>=4.12.2", + "exceptiongroup>=1.1.1; python_version < '3.11'", + ] + requires-python = ">=3.8" +@@ -59,6 +59,7 @@ classifiers = [ + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ++ "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Typing :: Typed", +@@ -77,7 +78,7 @@ ujson = [ + "ujson>=5.7.0", + ] + orjson = [ +- "orjson>=3.9.2; implementation_name == \"cpython\"", ++ "orjson>=3.10.7; implementation_name == \"cpython\"", + ] + msgpack = [ + "msgpack>=1.0.5", +diff --git a/src/cattrs/dispatch.py b/src/cattrs/dispatch.py +index 3d746db..f98dc51 100644 +--- a/src/cattrs/dispatch.py ++++ b/src/cattrs/dispatch.py +@@ -91,9 +91,9 @@ class MultiStrategyDispatch(Generic[Hook]): + MultiStrategyDispatch uses a combination of exact-match dispatch, + singledispatch, and FunctionDispatch. + +- :param converter: A converter to be used for factories that require converters. + :param fallback_factory: A hook factory to be called when a hook cannot be + produced. ++ :param converter: A converter to be used for factories that require converters. + + .. versionchanged:: 23.2.0 + Fallbacks are now factories. +@@ -103,7 +103,6 @@ class MultiStrategyDispatch(Generic[Hook]): + """ + + _fallback_factory: HookFactory[Hook] +- _converter: BaseConverter + _direct_dispatch: dict[TargetType, Hook] + _function_dispatch: FunctionDispatch + _single_dispatch: Any +diff --git a/src/cattrs/gen/__init__.py b/src/cattrs/gen/__init__.py +index 97d2876..bb31236 100644 +--- a/src/cattrs/gen/__init__.py ++++ b/src/cattrs/gen/__init__.py +@@ -14,6 +14,7 @@ from typing import ( + ) + + from attrs import NOTHING, Attribute, Factory, resolve_types ++from typing_extensions import NoDefault + + from .._compat import ( + ANIES, +@@ -1029,6 +1030,9 @@ def iterable_unstructure_factory( + """A hook factory for unstructuring iterables. + + :param unstructure_to: Force unstructuring to this type, if provided. ++ ++ .. versionchanged:: 24.2.0 ++ `typing.NoDefault` is now correctly handled as `Any`. + """ + handler = converter.unstructure + +@@ -1039,6 +1043,8 @@ def iterable_unstructure_factory( + type_arg = cl.__args__[0] + if isinstance(type_arg, TypeVar): + type_arg = getattr(type_arg, "__default__", Any) ++ if type_arg is NoDefault: ++ type_arg = Any + handler = converter.get_unstructure_hook(type_arg, cache_result=False) + if handler == identity: + # Save ourselves the trouble of iterating over it all. +diff --git a/tests/conftest.py b/tests/conftest.py +index d295990..4b014df 100644 +--- a/tests/conftest.py ++++ b/tests/conftest.py +@@ -37,3 +37,5 @@ if sys.version_info < (3, 12): + collect_ignore_glob.append("*_695.py") + if platform.python_implementation() == "PyPy": + collect_ignore_glob.append("*_cpython.py") ++if sys.version_info >= (3, 13): # Remove when msgspec supports 3.13. ++ collect_ignore_glob.append("*test_msgspec_cpython.py") +diff --git a/tests/test_preconf.py b/tests/test_preconf.py +index dba47fe..b7cf464 100644 +--- a/tests/test_preconf.py ++++ b/tests/test_preconf.py +@@ -4,7 +4,7 @@ from enum import Enum, IntEnum, unique + from json import dumps as json_dumps + from json import loads as json_loads + from platform import python_implementation +-from typing import Any, Dict, List, NamedTuple, NewType, Tuple, Union ++from typing import Any, Dict, Final, List, NamedTuple, NewType, Tuple, Union + + import pytest + from attrs import define +@@ -699,7 +699,10 @@ def test_cbor2_unions(union_and_val: tuple, detailed_validation: bool): + assert converter.structure(val, type) == val + + +-@pytest.mark.skipif(python_implementation() == "PyPy", reason="no msgspec on PyPy") ++NO_MSGSPEC: Final = python_implementation() == "PyPy" or sys.version_info[:2] >= (3, 13) ++ ++ ++@pytest.mark.skipif(NO_MSGSPEC, reason="msgspec not available") + @given(everythings(allow_inf=False)) + def test_msgspec_json_converter(everything: Everything): + from cattrs.preconf.msgspec import make_converter as msgspec_make_converter +@@ -709,7 +712,7 @@ def test_msgspec_json_converter(everything: Everything): + assert converter.loads(raw, Everything) == everything + + +-@pytest.mark.skipif(python_implementation() == "PyPy", reason="no msgspec on PyPy") ++@pytest.mark.skipif(NO_MSGSPEC, reason="msgspec not available") + @given(everythings(allow_inf=False)) + def test_msgspec_json_unstruct_collection_overrides(everything: Everything): + """Ensure collection overrides work.""" +@@ -724,7 +727,7 @@ def test_msgspec_json_unstruct_collection_overrides(everything: Everything): + assert raw["a_frozenset"] == sorted(raw["a_frozenset"]) + + +-@pytest.mark.skipif(python_implementation() == "PyPy", reason="no msgspec on PyPy") ++@pytest.mark.skipif(NO_MSGSPEC, reason="msgspec not available") + @given( + union_and_val=native_unions( + include_datetimes=False, +diff --git a/tox.ini b/tox.ini +index 21297bd..31ca9dc 100644 +--- a/tox.ini ++++ b/tox.ini +@@ -6,10 +6,12 @@ python = + 3.10: py310 + 3.11: py311, docs + 3.12: py312, lint ++ 3.13: py313 + pypy-3: pypy3 + ++ + [tox] +-envlist = pypy3, py38, py39, py310, py311, py312, lint, docs ++envlist = pypy3, py38, py39, py310, py311, py312, py313, lint, docs + isolated_build = true + skipsdist = true + +@@ -42,6 +44,15 @@ setenv = + COVERAGE_PROCESS_START={toxinidir}/pyproject.toml + COVERAGE_CORE=sysmon + ++[testenv:py313] ++setenv = ++ PDM_IGNORE_SAVED_PYTHON="1" ++ COVERAGE_PROCESS_START={toxinidir}/pyproject.toml ++ COVERAGE_CORE=sysmon ++commands_pre = ++ pdm sync -G ujson,msgpack,pyyaml,tomlkit,cbor2,bson,orjson,test ++ python -c 'import pathlib; pathlib.Path("{env_site_packages_dir}/cov.pth").write_text("import coverage; coverage.process_startup()")' ++ + [testenv:pypy3] + setenv = + FAST = 1 +-- +2.49.0 +