From d7af7f356278b23fb05821d9a5d65806c42729d6 Mon Sep 17 00:00:00 2001 From: James Estevez Date: Tue, 30 Sep 2025 15:27:50 -0700 Subject: [PATCH 1/5] deps: Update Pydantic to version 2 with compatibility support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update dependencies for Pydantic V2 migration: - Pydantic: 1.10.22 → 2.11.9 (major version upgrade) - Snowfakery: Point to migrate_to_pydantic_v2 branch - Add hatch direct references support for Git dependencies This enables Pydantic V2 features while maintaining compatibility. The V1 compatibility layer allows safe migration without breaking changes. Major frameworks like FastAPI use this approach successfully. Official Pydantic team recommends V1 compatibility for complex projects. --- pyproject.toml | 7 ++- uv.lock | 130 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 103 insertions(+), 34 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 14ee39ce02..b17199500d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ dependencies = [ "MarkupSafe", "packaging>=23.0", "psutil", - "pydantic<2", + "pydantic>=2.0,<3", "PyJWT", "pytz", "pyyaml", @@ -53,7 +53,7 @@ dependencies = [ "sarge", "selenium<4", "simple-salesforce==1.11.4", - "snowfakery>=4.0.0", + "snowfakery @ git+https://github.com/SFDO-Tooling/snowfakery.git@migrate_to_pydantic_v2", "xmltodict", "docutils<=0.21.2", ] @@ -105,6 +105,9 @@ Changelog = "https://cumulusci.readthedocs.io/en/stable/history.html" [tool.hatch.version] path = "cumulusci/__about__.py" +[tool.hatch.metadata] +allow-direct-references = true + [tool.hatch.build] include = [ "/cumulusci", diff --git a/uv.lock b/uv.lock index efb1f015cb..81712f7390 100644 --- a/uv.lock +++ b/uv.lock @@ -29,6 +29,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, ] +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + [[package]] name = "annoy" version = "1.17.3" @@ -401,6 +410,7 @@ dependencies = [ { name = "keyring" }, { name = "lxml" }, { name = "markupsafe" }, + { name = "packaging" }, { name = "psutil" }, { name = "pydantic" }, { name = "pyjwt" }, @@ -474,9 +484,10 @@ requires-dist = [ { name = "lxml" }, { name = "markupsafe" }, { name = "numpy", marker = "extra == 'select'" }, + { name = "packaging", specifier = ">=23.0" }, { name = "pandas", marker = "extra == 'select'" }, { name = "psutil" }, - { name = "pydantic", specifier = "<2" }, + { name = "pydantic", specifier = ">=2.0,<3" }, { name = "pyjwt" }, { name = "python-dateutil" }, { name = "pytz" }, @@ -494,7 +505,7 @@ requires-dist = [ { name = "scikit-learn", marker = "extra == 'select'" }, { name = "selenium", specifier = "<4" }, { name = "simple-salesforce", specifier = "==1.11.4" }, - { name = "snowfakery", specifier = ">=4.0.0" }, + { name = "snowfakery", git = "https://github.com/SFDO-Tooling/snowfakery.git?rev=migrate_to_pydantic_v2" }, { name = "sqlalchemy", specifier = "<2" }, { name = "xmltodict" }, ] @@ -1401,35 +1412,82 @@ wheels = [ [[package]] name = "pydantic" -version = "1.10.22" +version = "2.11.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.33.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9a/57/5996c63f0deec09e9e901a2b838247c97c6844999562eac4e435bcb83938/pydantic-1.10.22.tar.gz", hash = "sha256:ee1006cebd43a8e7158fb7190bb8f4e2da9649719bff65d0c287282ec38dec6d", size = 356771, upload-time = "2025-04-24T13:38:43.605Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/03/e435ed85a9abda29e3fbdb49c572fe4131a68c6daf3855a01eebda9e1b27/pydantic-1.10.22-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e530a8da353f791ad89e701c35787418605d35085f4bdda51b416946070e938", size = 2845682, upload-time = "2025-04-24T13:37:10.142Z" }, - { url = "https://files.pythonhosted.org/packages/72/ea/4a625035672f6c06d3f1c7e33aa0af6bf1929991e27017e98b9c2064ae0b/pydantic-1.10.22-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:654322b85642e9439d7de4c83cb4084ddd513df7ff8706005dada43b34544946", size = 2553286, upload-time = "2025-04-24T13:37:11.946Z" }, - { url = "https://files.pythonhosted.org/packages/a4/f0/424ad837746e69e9f061ba9be68c2a97aef7376d1911692904d8efbcd322/pydantic-1.10.22-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8bece75bd1b9fc1c32b57a32831517943b1159ba18b4ba32c0d431d76a120ae", size = 3141232, upload-time = "2025-04-24T13:37:14.394Z" }, - { url = "https://files.pythonhosted.org/packages/14/67/4979c19e8cfd092085a292485e0b42d74e4eeefbb8cd726aa8ba38d06294/pydantic-1.10.22-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eccb58767f13c6963dcf96d02cb8723ebb98b16692030803ac075d2439c07b0f", size = 3214272, upload-time = "2025-04-24T13:37:16.201Z" }, - { url = "https://files.pythonhosted.org/packages/1a/04/32339ce43e97519d19e7759902515c750edbf4832a13063a4ab157f83f42/pydantic-1.10.22-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7778e6200ff8ed5f7052c1516617423d22517ad36cc7a3aedd51428168e3e5e8", size = 3321646, upload-time = "2025-04-24T13:37:19.086Z" }, - { url = "https://files.pythonhosted.org/packages/92/35/dffc1b29cb7198aadab68d75447191e59bdbc1f1d2d51826c9a4460d372f/pydantic-1.10.22-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffe02767d27c39af9ca7dc7cd479c00dda6346bb62ffc89e306f665108317a2", size = 3244258, upload-time = "2025-04-24T13:37:20.929Z" }, - { url = "https://files.pythonhosted.org/packages/11/c5/c4ce6ebe7f528a879441eabd2c6dd9e2e4c54f320a8c9344ba93b3aa8701/pydantic-1.10.22-cp311-cp311-win_amd64.whl", hash = "sha256:23bc19c55427091b8e589bc08f635ab90005f2dc99518f1233386f46462c550a", size = 2309702, upload-time = "2025-04-24T13:37:23.296Z" }, - { url = "https://files.pythonhosted.org/packages/f6/a3/ec66239ed7c9e90edfb85b23b6b18eb290ed7aa05f54837cdcb6a14faa98/pydantic-1.10.22-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:92d0f97828a075a71d9efc65cf75db5f149b4d79a38c89648a63d2932894d8c9", size = 2794865, upload-time = "2025-04-24T13:37:25.087Z" }, - { url = "https://files.pythonhosted.org/packages/49/6a/99cf3fee612d93210c85f45a161e98c1c5b45b6dcadb21c9f1f838fa9e28/pydantic-1.10.22-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af5a2811b6b95b58b829aeac5996d465a5f0c7ed84bd871d603cf8646edf6ff", size = 2534212, upload-time = "2025-04-24T13:37:26.848Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e6/0f8882775cd9a60b221103ee7d6a89e10eb5a892d877c398df0da7140704/pydantic-1.10.22-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cf06d8d40993e79af0ab2102ef5da77b9ddba51248e4cb27f9f3f591fbb096e", size = 2994027, upload-time = "2025-04-24T13:37:28.683Z" }, - { url = "https://files.pythonhosted.org/packages/e7/a3/f20fdecbaa2a2721a6a8ee9e4f344d1f72bd7d56e679371c3f2be15eb8c8/pydantic-1.10.22-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:184b7865b171a6057ad97f4a17fbac81cec29bd103e996e7add3d16b0d95f609", size = 3036716, upload-time = "2025-04-24T13:37:30.547Z" }, - { url = "https://files.pythonhosted.org/packages/1f/83/dab34436d830c38706685acc77219fc2a209fea2a2301a1b05a2865b28bf/pydantic-1.10.22-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:923ad861677ab09d89be35d36111156063a7ebb44322cdb7b49266e1adaba4bb", size = 3171801, upload-time = "2025-04-24T13:37:32.474Z" }, - { url = "https://files.pythonhosted.org/packages/1e/6e/b64deccb8a7304d584088972437ea3091e9d99d27a8e7bf2bd08e29ae84e/pydantic-1.10.22-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:82d9a3da1686443fb854c8d2ab9a473251f8f4cdd11b125522efb4d7c646e7bc", size = 3123560, upload-time = "2025-04-24T13:37:34.855Z" }, - { url = "https://files.pythonhosted.org/packages/08/9a/90d1ab704329a7ae8666354be84b5327d655764003974364767c9d307d3a/pydantic-1.10.22-cp312-cp312-win_amd64.whl", hash = "sha256:1612604929af4c602694a7f3338b18039d402eb5ddfbf0db44f1ebfaf07f93e7", size = 2191378, upload-time = "2025-04-24T13:37:36.649Z" }, - { url = "https://files.pythonhosted.org/packages/47/8f/67befe3607b342dd6eb80237134ebcc6e8db42138609306eaf2b30e1f273/pydantic-1.10.22-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b259dc89c9abcd24bf42f31951fb46c62e904ccf4316393f317abeeecda39978", size = 2797042, upload-time = "2025-04-24T13:37:38.753Z" }, - { url = "https://files.pythonhosted.org/packages/aa/91/bfde7d301f8e1c4cff949b3f1eb2c9b27bdd4b2368da0fe88e7350bbe4bc/pydantic-1.10.22-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9238aa0964d80c0908d2f385e981add58faead4412ca80ef0fa352094c24e46d", size = 2538572, upload-time = "2025-04-24T13:37:41.653Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/1b0097ece420354df77d2f01c72278fb43770c8ed732d6b7a303c0c70875/pydantic-1.10.22-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8029f05b04080e3f1a550575a1bca747c0ea4be48e2d551473d47fd768fc1b", size = 2986271, upload-time = "2025-04-24T13:37:43.551Z" }, - { url = "https://files.pythonhosted.org/packages/eb/4c/e257edfd5a0025a428aee7a2835e21b51c76a6b1c8994bcccb14d5721eea/pydantic-1.10.22-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c06918894f119e0431a36c9393bc7cceeb34d1feeb66670ef9b9ca48c073937", size = 3015617, upload-time = "2025-04-24T13:37:45.466Z" }, - { url = "https://files.pythonhosted.org/packages/00/17/ecf46ff31fd62d382424a07ed60540d4479094204bebeebb6dea597e88c3/pydantic-1.10.22-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e205311649622ee8fc1ec9089bd2076823797f5cd2c1e3182dc0e12aab835b35", size = 3164222, upload-time = "2025-04-24T13:37:47.35Z" }, - { url = "https://files.pythonhosted.org/packages/1a/47/2d55ec452c9a87347234bbbc70df268e1f081154b1851f0db89638558a1c/pydantic-1.10.22-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:815f0a73d5688d6dd0796a7edb9eca7071bfef961a7b33f91e618822ae7345b7", size = 3117572, upload-time = "2025-04-24T13:37:49.339Z" }, - { url = "https://files.pythonhosted.org/packages/03/2f/30359a36245b029bec7e442dd780fc242c66e66ad7dd5b50af2dcfd41ff3/pydantic-1.10.22-cp313-cp313-win_amd64.whl", hash = "sha256:9dfce71d42a5cde10e78a469e3d986f656afc245ab1b97c7106036f088dd91f8", size = 2174666, upload-time = "2025-04-24T13:37:51.114Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e0/1ed151a56869be1588ad2d8cda9f8c1d95b16f74f09a7cea879ca9b63a8b/pydantic-1.10.22-py3-none-any.whl", hash = "sha256:343037d608bcbd34df937ac259708bfc83664dadf88afe8516c4f282d7d471a9", size = 166503, upload-time = "2025-04-24T13:38:41.374Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, + { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, + { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, + { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, + { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, + { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, + { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, + { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, + { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, + { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, ] [[package]] @@ -2048,7 +2106,7 @@ wheels = [ [[package]] name = "snowfakery" version = "4.0.0" -source = { registry = "https://pypi.org/simple" } +source = { git = "https://github.com/SFDO-Tooling/snowfakery.git?rev=migrate_to_pydantic_v2#14f96d06fa75bc3bface20a6a0a7ed71fc315ad6" } dependencies = [ { name = "click" }, { name = "faker" }, @@ -2064,10 +2122,6 @@ dependencies = [ { name = "setuptools" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/69/94/51848ad67a409e2b8d37e10277e4ee43b8c982a47fd6e9bb114f427374b0/snowfakery-4.0.0.tar.gz", hash = "sha256:95b4a5add5b7e8483fcbf567e3b83ec7418031ce8a00fdc8542c906ec5392d91", size = 76039, upload-time = "2024-11-13T19:09:18.071Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/dd/6da304a468b69f036c2185a116cf4840e36b510e65c22bebb07abeec78fd/snowfakery-4.0.0-py3-none-any.whl", hash = "sha256:38ed1faec5839d45454a2ecf0a64ec4cb352662e84694b204866a0e9dedc1a52", size = 100733, upload-time = "2024-11-13T19:09:16.093Z" }, -] [[package]] name = "soupsieve" @@ -2288,6 +2342,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] +[[package]] +name = "typing-inspection" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, +] + [[package]] name = "tzdata" version = "2025.2" From 462b05a439534387f4ccbec4a436e97b7429b8e2 Mon Sep 17 00:00:00 2001 From: James Estevez Date: Tue, 30 Sep 2025 15:31:23 -0700 Subject: [PATCH 2/5] feat: Add Pydantic V1 compatibility layer for safe migration Implement systematic V1 compatibility across core modules: - Replace 'from pydantic import' with 'from pydantic.v1 import' - Update core configuration, task execution, and OAuth components - Maintain all existing functionality without breaking changes Updated modules: - Core: Configuration models, dependency resolution, version handling - Tasks: Metadata ETL, bulk data operations, package management - OAuth: Authentication and client models - Utils: YAML parsing, options processing, parallel execution This approach is used by FastAPI and other major Python projects. The Pydantic maintainers recommend V1 compatibility for complex migrations. Enables gradual migration with minimal performance impact. --- cumulusci/core/dependencies/dependencies.py | 4 ++-- cumulusci/core/source_transforms/transforms.py | 2 +- cumulusci/core/versions.py | 2 +- cumulusci/oauth/client.py | 2 +- cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py | 2 +- .../extract_dataset_utils/synthesize_extract_declarations.py | 2 +- cumulusci/tasks/bulkdata/mapping_parser.py | 2 +- cumulusci/tasks/bulkdata/select_utils.py | 2 +- cumulusci/tasks/create_package_version.py | 2 +- cumulusci/tasks/datadictionary.py | 2 +- cumulusci/tasks/metadata_etl/layouts.py | 2 +- cumulusci/tasks/metadata_etl/permissions.py | 2 +- cumulusci/tasks/metadata_etl/remote_site_settings.py | 4 ++-- cumulusci/utils/options.py | 2 +- .../utils/parallel/task_worker_queues/parallel_worker.py | 2 +- cumulusci/utils/yaml/cumulusci_yml.py | 4 ++-- cumulusci/utils/yaml/model_parser.py | 4 ++-- 17 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cumulusci/core/dependencies/dependencies.py b/cumulusci/core/dependencies/dependencies.py index 3301cdb8a5..2c0050dcba 100644 --- a/cumulusci/core/dependencies/dependencies.py +++ b/cumulusci/core/dependencies/dependencies.py @@ -6,10 +6,10 @@ from typing import List, Optional from zipfile import ZipFile -import pydantic +import pydantic.v1 as pydantic from github3.exceptions import NotFoundError from github3.repos.repo import Repository -from pydantic.networks import AnyUrl +from pydantic.v1.networks import AnyUrl from cumulusci.core.config import OrgConfig from cumulusci.core.config.project_config import BaseProjectConfig diff --git a/cumulusci/core/source_transforms/transforms.py b/cumulusci/core/source_transforms/transforms.py index ab311b1456..9bf0499a8e 100644 --- a/cumulusci/core/source_transforms/transforms.py +++ b/cumulusci/core/source_transforms/transforms.py @@ -10,7 +10,7 @@ from zipfile import ZipFile from lxml import etree as ET -from pydantic import BaseModel, root_validator +from pydantic.v1 import BaseModel, root_validator from cumulusci.core.dependencies.utils import TaskContext from cumulusci.core.enums import StrEnum diff --git a/cumulusci/core/versions.py b/cumulusci/core/versions.py index 21b34ff1e3..21437847d2 100644 --- a/cumulusci/core/versions.py +++ b/cumulusci/core/versions.py @@ -1,7 +1,7 @@ import re from typing import Optional, Union -from pydantic import BaseModel +from pydantic.v1 import BaseModel from cumulusci.core.enums import StrEnum diff --git a/cumulusci/oauth/client.py b/cumulusci/oauth/client.py index 9d812c7def..91059eba15 100644 --- a/cumulusci/oauth/client.py +++ b/cumulusci/oauth/client.py @@ -19,7 +19,7 @@ from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.x509.oid import NameOID -from pydantic import BaseModel +from pydantic.v1 import BaseModel from cumulusci.core.exceptions import CumulusCIUsageError from cumulusci.oauth.exceptions import OAuth2Error diff --git a/cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py b/cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py index cec42d0bd9..1ece5c1cd7 100644 --- a/cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +++ b/cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py @@ -2,7 +2,7 @@ import typing as T from pathlib import Path -from pydantic import Field, validator +from pydantic.v1 import Field, validator from cumulusci.core.enums import StrEnum from cumulusci.tasks.bulkdata.utils import DataApi diff --git a/cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py b/cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py index bfec28ef54..49febd966d 100644 --- a/cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +++ b/cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py @@ -2,7 +2,7 @@ import re import typing as T -from pydantic import validator +from pydantic.v1 import validator from cumulusci.salesforce_api.org_schema import NOT_EXTRACTABLE, Field, Schema from cumulusci.utils.iterators import partition diff --git a/cumulusci/tasks/bulkdata/mapping_parser.py b/cumulusci/tasks/bulkdata/mapping_parser.py index 28b71b1f34..cad6451345 100644 --- a/cumulusci/tasks/bulkdata/mapping_parser.py +++ b/cumulusci/tasks/bulkdata/mapping_parser.py @@ -7,7 +7,7 @@ from pathlib import Path from typing import IO, Any, Callable, Dict, List, Mapping, Optional, Tuple, Union -from pydantic import Field, ValidationError, root_validator, validator +from pydantic.v1 import Field, ValidationError, root_validator, validator from simple_salesforce import Salesforce from typing_extensions import Literal diff --git a/cumulusci/tasks/bulkdata/select_utils.py b/cumulusci/tasks/bulkdata/select_utils.py index 7835d8dea8..81c3c0e2d9 100644 --- a/cumulusci/tasks/bulkdata/select_utils.py +++ b/cumulusci/tasks/bulkdata/select_utils.py @@ -4,7 +4,7 @@ import typing as T from enum import Enum -from pydantic import Field, root_validator, validator +from pydantic.v1 import Field, root_validator, validator from cumulusci.core.enums import StrEnum from cumulusci.tasks.bulkdata.utils import CaseInsensitiveDict diff --git a/cumulusci/tasks/create_package_version.py b/cumulusci/tasks/create_package_version.py index 14a80334fc..9933b3e49e 100644 --- a/cumulusci/tasks/create_package_version.py +++ b/cumulusci/tasks/create_package_version.py @@ -5,7 +5,7 @@ import zipfile from typing import List, Optional -from pydantic import BaseModel, validator +from pydantic.v1 import BaseModel, validator from simple_salesforce.exceptions import SalesforceMalformedRequest from cumulusci.core.config.util import get_devhub_config diff --git a/cumulusci/tasks/datadictionary.py b/cumulusci/tasks/datadictionary.py index 4a8773260c..04418512ce 100644 --- a/cumulusci/tasks/datadictionary.py +++ b/cumulusci/tasks/datadictionary.py @@ -6,7 +6,7 @@ from zipfile import ZipFile from github3.repos.repo import Repository -from pydantic import BaseModel +from pydantic.v1 import BaseModel from cumulusci.core.dependencies.dependencies import ( Dependency, diff --git a/cumulusci/tasks/metadata_etl/layouts.py b/cumulusci/tasks/metadata_etl/layouts.py index 4b6ed9fbe6..425c53de85 100644 --- a/cumulusci/tasks/metadata_etl/layouts.py +++ b/cumulusci/tasks/metadata_etl/layouts.py @@ -1,6 +1,6 @@ from typing import List, Optional -from pydantic import BaseModel, root_validator +from pydantic.v1 import BaseModel, root_validator from typing_extensions import Literal from cumulusci.core.exceptions import TaskOptionsError diff --git a/cumulusci/tasks/metadata_etl/permissions.py b/cumulusci/tasks/metadata_etl/permissions.py index 9a453e14f3..6d2baedb79 100644 --- a/cumulusci/tasks/metadata_etl/permissions.py +++ b/cumulusci/tasks/metadata_etl/permissions.py @@ -1,6 +1,6 @@ import typing as T -import pydantic +import pydantic.v1 as pydantic from cumulusci.core.exceptions import TaskOptionsError from cumulusci.tasks.metadata_etl import MetadataSingleEntityTransformTask diff --git a/cumulusci/tasks/metadata_etl/remote_site_settings.py b/cumulusci/tasks/metadata_etl/remote_site_settings.py index 7add3b6e3d..907d5143d1 100644 --- a/cumulusci/tasks/metadata_etl/remote_site_settings.py +++ b/cumulusci/tasks/metadata_etl/remote_site_settings.py @@ -1,7 +1,7 @@ from typing import List, Optional -import pydantic -from pydantic import BaseModel +import pydantic.v1 as pydantic +from pydantic.v1 import BaseModel from cumulusci.core.exceptions import TaskOptionsError from cumulusci.tasks.metadata_etl.base import BaseMetadataSynthesisTask diff --git a/cumulusci/utils/options.py b/cumulusci/utils/options.py index 5d5d2828f0..1dcf353145 100644 --- a/cumulusci/utils/options.py +++ b/cumulusci/utils/options.py @@ -2,7 +2,7 @@ from inspect import signature from typing import Any, Dict, List -from pydantic import DirectoryPath, Field, FilePath, create_model +from pydantic.v1 import DirectoryPath, Field, FilePath, create_model from cumulusci.core.exceptions import TaskOptionsError from cumulusci.utils.yaml.model_parser import CCIDictModel diff --git a/cumulusci/utils/parallel/task_worker_queues/parallel_worker.py b/cumulusci/utils/parallel/task_worker_queues/parallel_worker.py index 72c3b84ad0..8130c37306 100644 --- a/cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +++ b/cumulusci/utils/parallel/task_worker_queues/parallel_worker.py @@ -7,7 +7,7 @@ from pathlib import Path from traceback import format_exc -from pydantic import BaseModel +from pydantic.v1 import BaseModel from cumulusci.core.config import ( BaseConfig, diff --git a/cumulusci/utils/yaml/cumulusci_yml.py b/cumulusci/utils/yaml/cumulusci_yml.py index 93516ed654..642358042b 100644 --- a/cumulusci/utils/yaml/cumulusci_yml.py +++ b/cumulusci/utils/yaml/cumulusci_yml.py @@ -9,8 +9,8 @@ from pathlib import Path from typing import Any, Dict, List, Optional, Sequence, Union -from pydantic import Field, root_validator, validator -from pydantic.types import DirectoryPath +from pydantic.v1 import Field, root_validator, validator +from pydantic.v1.types import DirectoryPath from typing_extensions import Literal, TypedDict from cumulusci.core.enums import StrEnum diff --git a/cumulusci/utils/yaml/model_parser.py b/cumulusci/utils/yaml/model_parser.py index 249d914fbd..9d8434db56 100644 --- a/cumulusci/utils/yaml/model_parser.py +++ b/cumulusci/utils/yaml/model_parser.py @@ -1,8 +1,8 @@ from pathlib import Path from typing import IO, Sequence, Union -from pydantic import BaseModel, ValidationError -from pydantic.error_wrappers import ErrorWrapper +from pydantic.v1 import BaseModel, ValidationError +from pydantic.v1.error_wrappers import ErrorWrapper from cumulusci.utils.yaml.safer_loader import load_from_source, load_yaml_data From 233caba50d71024e7705521e331818f4ebd91f08 Mon Sep 17 00:00:00 2001 From: James Estevez Date: Tue, 30 Sep 2025 15:34:50 -0700 Subject: [PATCH 3/5] fix: Update test compatibility for Pydantic V1 namespace Fix validation error handling and field imports in tests: - Update ValidationError imports to use pydantic.v1 namespace - Fix Field imports in model parser tests - Update pydantic.Extra usage for V1 compatibility - Resolve exception type mismatches in test suite Updated components: - Test files: Model validation, dependency tests, transform tests - Core files: Task validation, project config, deploy tasks All tests are now passing with V1 compatibility layer. --- cumulusci/core/config/project_config.py | 2 +- cumulusci/core/dependencies/tests/test_dependencies.py | 2 +- cumulusci/core/source_transforms/tests/test_transforms.py | 2 +- cumulusci/core/tasks.py | 2 +- .../extract_dataset_utils/tests/test_extract_yml.py | 2 +- cumulusci/tasks/salesforce/Deploy.py | 2 +- .../tasks/salesforce/tests/test_update_dependencies.py | 2 +- cumulusci/tasks/tests/test_create_package_version.py | 2 +- cumulusci/utils/yaml/tests/test_cumulusci_yml.py | 2 +- cumulusci/utils/yaml/tests/test_model_parser.py | 6 +++--- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cumulusci/core/config/project_config.py b/cumulusci/core/config/project_config.py index 856bca6401..72c3850e49 100644 --- a/cumulusci/core/config/project_config.py +++ b/cumulusci/core/config/project_config.py @@ -22,7 +22,7 @@ API_VERSION_RE = re.compile(r"^\d\d+\.0$") import github3 -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.core.config import FlowConfig, TaskConfig from cumulusci.core.config.base_task_flow_config import BaseTaskFlowConfig diff --git a/cumulusci/core/dependencies/tests/test_dependencies.py b/cumulusci/core/dependencies/tests/test_dependencies.py index e0c757c7aa..dc57210c0c 100644 --- a/cumulusci/core/dependencies/tests/test_dependencies.py +++ b/cumulusci/core/dependencies/tests/test_dependencies.py @@ -5,7 +5,7 @@ from zipfile import ZipFile import pytest -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.core.config.org_config import OrgConfig, VersionInfo from cumulusci.core.config.project_config import BaseProjectConfig diff --git a/cumulusci/core/source_transforms/tests/test_transforms.py b/cumulusci/core/source_transforms/tests/test_transforms.py index 99230f2fe2..619e9a125e 100644 --- a/cumulusci/core/source_transforms/tests/test_transforms.py +++ b/cumulusci/core/source_transforms/tests/test_transforms.py @@ -8,7 +8,7 @@ import pytest from lxml import etree as ET -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.core.exceptions import CumulusCIException, TaskOptionsError from cumulusci.core.source_transforms.transforms import ( diff --git a/cumulusci/core/tasks.py b/cumulusci/core/tasks.py index 0d8269aea4..7c8cffc2fb 100644 --- a/cumulusci/core/tasks.py +++ b/cumulusci/core/tasks.py @@ -11,7 +11,7 @@ from contextlib import nullcontext from typing import Any, Callable, Dict, List, Optional, Type, Union -from pydantic.error_wrappers import ValidationError +from pydantic.v1.error_wrappers import ValidationError from cumulusci import __version__ from cumulusci.core.config import TaskConfig diff --git a/cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py b/cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py index 8daf124e25..127b40b172 100644 --- a/cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +++ b/cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py @@ -1,7 +1,7 @@ from io import StringIO import pytest -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.tasks.bulkdata.extract_dataset_utils.extract_yml import ( ExtractDeclaration, diff --git a/cumulusci/tasks/salesforce/Deploy.py b/cumulusci/tasks/salesforce/Deploy.py index 66a5851b80..8c6ff6350c 100644 --- a/cumulusci/tasks/salesforce/Deploy.py +++ b/cumulusci/tasks/salesforce/Deploy.py @@ -2,7 +2,7 @@ from typing import List, Optional, Union from defusedxml.minidom import parseString -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.cli.ui import CliTable from cumulusci.core.dependencies.utils import TaskContext diff --git a/cumulusci/tasks/salesforce/tests/test_update_dependencies.py b/cumulusci/tasks/salesforce/tests/test_update_dependencies.py index 92e133c01e..266a24c7da 100644 --- a/cumulusci/tasks/salesforce/tests/test_update_dependencies.py +++ b/cumulusci/tasks/salesforce/tests/test_update_dependencies.py @@ -3,7 +3,7 @@ import zipfile from unittest import mock -import pydantic +import pydantic.v1 as pydantic import pytest from cumulusci.core.dependencies.dependencies import ( diff --git a/cumulusci/tasks/tests/test_create_package_version.py b/cumulusci/tasks/tests/test_create_package_version.py index e972529db8..c1983466fb 100644 --- a/cumulusci/tasks/tests/test_create_package_version.py +++ b/cumulusci/tasks/tests/test_create_package_version.py @@ -10,7 +10,7 @@ import pytest import responses import yaml -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.core.config import BaseProjectConfig, TaskConfig, UniversalConfig from cumulusci.core.dependencies.dependencies import ( diff --git a/cumulusci/utils/yaml/tests/test_cumulusci_yml.py b/cumulusci/utils/yaml/tests/test_cumulusci_yml.py index dce7cb3af9..e8608af3f1 100644 --- a/cumulusci/utils/yaml/tests/test_cumulusci_yml.py +++ b/cumulusci/utils/yaml/tests/test_cumulusci_yml.py @@ -4,7 +4,7 @@ from unittest.mock import MagicMock, Mock, patch import pytest -from pydantic import ValidationError +from pydantic.v1 import ValidationError from cumulusci.utils import temporary_dir from cumulusci.utils.yaml.cumulusci_yml import ( diff --git a/cumulusci/utils/yaml/tests/test_model_parser.py b/cumulusci/utils/yaml/tests/test_model_parser.py index 5c2f9167e4..fcceca7159 100644 --- a/cumulusci/utils/yaml/tests/test_model_parser.py +++ b/cumulusci/utils/yaml/tests/test_model_parser.py @@ -2,7 +2,7 @@ from unittest.mock import Mock import pytest -from pydantic import Field +from pydantic.v1 import Field from cumulusci.utils.yaml.model_parser import CCIDictModel, CCIModel, ValidationError @@ -20,7 +20,7 @@ class TestCCIModel: def test_fields_property(self): # JSON is YAML. Strange but true. foo = Document.parse_from_yaml(StringIO("{bar: 'blah'}")) - assert type(foo) == Foo + assert isinstance(foo, Foo) assert foo.fields_ == [] assert foo.fields == [] @@ -122,7 +122,7 @@ class Document(CCIDictModel): # JSON is YAML. Strange but true. foo = Document.parse_from_yaml(StringIO("{bar: 'blah'}")) - assert type(foo) == Foo + assert isinstance(foo, Foo) assert foo["fields"] == [] foo = Document.parse_from_yaml(StringIO("{bar: 'blah', fields: [1,2]}")) From fe41f2da9df8f31ea7e8e34b5af4927ca0b4f42b Mon Sep 17 00:00:00 2001 From: James Estevez Date: Thu, 9 Oct 2025 22:10:21 -0700 Subject: [PATCH 4/5] Update to snowfakery v4.1 --- pyproject.toml | 2 +- uv.lock | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b17199500d..66cdbf7053 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ dependencies = [ "sarge", "selenium<4", "simple-salesforce==1.11.4", - "snowfakery @ git+https://github.com/SFDO-Tooling/snowfakery.git@migrate_to_pydantic_v2", + "snowfakery>=4.1.0", "xmltodict", "docutils<=0.21.2", ] diff --git a/uv.lock b/uv.lock index 81712f7390..071af4e7ba 100644 --- a/uv.lock +++ b/uv.lock @@ -505,7 +505,7 @@ requires-dist = [ { name = "scikit-learn", marker = "extra == 'select'" }, { name = "selenium", specifier = "<4" }, { name = "simple-salesforce", specifier = "==1.11.4" }, - { name = "snowfakery", git = "https://github.com/SFDO-Tooling/snowfakery.git?rev=migrate_to_pydantic_v2" }, + { name = "snowfakery", specifier = ">=4.1.0" }, { name = "sqlalchemy", specifier = "<2" }, { name = "xmltodict" }, ] @@ -2105,8 +2105,8 @@ wheels = [ [[package]] name = "snowfakery" -version = "4.0.0" -source = { git = "https://github.com/SFDO-Tooling/snowfakery.git?rev=migrate_to_pydantic_v2#14f96d06fa75bc3bface20a6a0a7ed71fc315ad6" } +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "faker" }, @@ -2122,6 +2122,10 @@ dependencies = [ { name = "setuptools" }, { name = "sqlalchemy" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/bf/6d/8e13daa8b9ebc5f6b24351ab0bf3a25be59bc24d68b9f7636e7ce779957d/snowfakery-4.1.0.tar.gz", hash = "sha256:d589c14ab7673649023138b6ef468a51e8bc1c390db624be115d1adbfe5c1d36", size = 76085, upload-time = "2025-10-09T05:51:05.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/87/1f9b9dc9ee25c32aff7f90187d64c727baa01ca1a8b4d1a43bb982110929/snowfakery-4.1.0-py3-none-any.whl", hash = "sha256:c13453ae5240bbc3d0ccf6049d3c9f1989d0c803672e88f7cff25419828c6ce0", size = 100778, upload-time = "2025-10-09T05:51:06.514Z" }, +] [[package]] name = "soupsieve" From d33ecd3073f87f424738063de53cd0a53c5bd2de Mon Sep 17 00:00:00 2001 From: James Estevez Date: Fri, 10 Oct 2025 11:23:24 -0700 Subject: [PATCH 5/5] fix: Remove unused global declaration Remove the global declaration for 'has_shown_yaml_error_message'. This variable was deleted in a previous change, but the declaration was left behind by mistake. This fixes flake8 error F824. --- cumulusci/utils/yaml/cumulusci_yml.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cumulusci/utils/yaml/cumulusci_yml.py b/cumulusci/utils/yaml/cumulusci_yml.py index 642358042b..78cc9ac960 100644 --- a/cumulusci/utils/yaml/cumulusci_yml.py +++ b/cumulusci/utils/yaml/cumulusci_yml.py @@ -280,7 +280,6 @@ class ErrorDict(TypedDict): def _log_yaml_errors(logger, errors: List[ErrorDict]): "Format and log a Pydantic-style error dictionary" - global has_shown_yaml_error_message plural = "" if len(errors) <= 1 else "s" logger.warning(f"CumulusCI Configuration Warning{plural}:") for error in errors: